├── .gitignore ├── lib ├── .examples.qcl.swp ├── dft.qcl ├── deutsch.qcl ├── grover.qcl ├── primes.qcl ├── shor.qcl ├── linalg.qcl ├── test.qcl ├── examples.qcl ├── modarith.qcl └── default.qcl ├── plot.h ├── extern.h ├── qc ├── qc.h ├── Makefile ├── terms.cc ├── terms.h ├── bitvec.cc ├── operator.h ├── operator.cc ├── shor.cc ├── bitvec.h └── qustates.h ├── dump.h ├── debug.h ├── qcl.cc ├── format.h ├── parse.h ├── cond.cc ├── error.h ├── symbols.h ├── CHANGES ├── parse.cc ├── options.h ├── quheap.h ├── cond.h ├── debug.cc ├── symbols.cc ├── error.cc ├── format.cc ├── Makefile ├── README ├── dump.cc ├── plot.cc ├── qcl.lex ├── types.cc ├── syntax.cc └── qcl.y /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | .depend 3 | 4 | -------------------------------------------------------------------------------- /lib/.examples.qcl.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learner-long-life/qcl/HEAD/lib/.examples.qcl.swp -------------------------------------------------------------------------------- /lib/dft.qcl: -------------------------------------------------------------------------------- 1 | set library 1; 2 | 3 | // pseudo classic operator to swap bit order 4 | 5 | cond qufunct flip(qureg q) { 6 | int i; // declare loop counter 7 | for i=0 to #q/2-1 { // swap 2 symmetric bits 8 | Swap(q[i],q[#q-i-1]); 9 | } 10 | } 11 | 12 | // discrete Fourier transform (Coppersmith) 13 | 14 | operator dft(qureg q) { // main operator 15 | const n=#q; // set n to length of input 16 | int i; int j; // declare loop counters 17 | for i=1 to n { 18 | for j=1 to i-1 { // apply conditional phase gates 19 | V(pi/2^(i-j),q[n-i] & q[n-j]); 20 | // if q[n-i] and q[n-j] { Phase(pi/2^(i-j)); } 21 | } 22 | H(q[n-i]); // qubit rotation 23 | } 24 | flip(q); // swap bit order of the output 25 | } 26 | 27 | set library 0; 28 | 29 | -------------------------------------------------------------------------------- /plot.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef PLOT_H 17 | #define PLOT_H 1 18 | 19 | #pragma interface 20 | 21 | #include "types.h" 22 | 23 | void plot_state(QuHeap *qh); 24 | void plot_spectrum(quState *q,string lab=""); 25 | void plot_spectrum2(quState *qx,quState *qy,string labx="",string laby=""); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /extern.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef EXTERN_H 17 | #define EXTERN_H 1 18 | 19 | #pragma interface 20 | 21 | #include "types.h" 22 | 23 | /* 24 | class QuBaseState : public quBaseState { 25 | public: 26 | QuBaseState(int n) : quBaseState(n) { } 27 | }; 28 | */ 29 | 30 | struct RoutTableEntry { 31 | tExtRout *rout; 32 | char *id; 33 | }; 34 | 35 | extern RoutTableEntry ExtRoutTable[]; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /qc/qc.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library. 4 | 5 | Copyright by Bernhard Oemer 1996, all rights reserved 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | The use and distribution in any electronic or non-electronic way 11 | of this or any other file of this package is forbidden without 12 | prior written or PGP-signed permission from the author. 13 | 14 | E-mail: oemer@tph.tuwien.ac.at 15 | 16 | PGP fingerprint: 51 BB 4A CE CB 15 32 DE A7 64 BC F4 05 F1 35 A8 17 | PGP public key: http://tph.tuwien.ac.at/~oemer/pubkey.txt 18 | 19 | ************************************************************************/ 20 | 21 | #ifndef _LIBQC_H 22 | #define _LIBQC_H 1 23 | 24 | #include "bitvec.h" 25 | #include "terms.h" 26 | #include "qustates.h" 27 | #include "operator.h" 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /dump.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef DUMP_H 17 | #define DUMP_H 1 18 | 19 | #pragma interface 20 | 21 | #include "types.h" 22 | 23 | /* 24 | bitvec trimvect(const bitvec& v); 25 | string vect2bin(const bitvec& v); 26 | string vect2dec(const bitvec& v); 27 | string vect2hex(const bitvec& v); 28 | */ 29 | 30 | int report_state(QuHeap *qh); 31 | int dump_state(QuHeap *qh,ostream *o=0); 32 | int dump_spectrum(quState *qs,ostream *o=0); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /lib/deutsch.qcl: -------------------------------------------------------------------------------- 1 | /* Define Oracle */ 2 | 3 | const coin1=(random()>=0.5); // Define two random boolean 4 | const coin2=(random()>=0.5); // constants 5 | 6 | boolean g(boolean x) { // Oracle function g 7 | if coin1 { // coin1=true -> g is constant 8 | return coin2; 9 | } else { // coin1=false -> g is balanced 10 | return x xor coin2; 11 | } 12 | } 13 | 14 | qufunct G(quconst x,quvoid y) { // Construct oracle op. G from g 15 | if g(false) xor g(true) { CNot(y,x); } 16 | if g(false) { Not(y); } 17 | } 18 | 19 | /* Deutsch's Algorithm */ 20 | 21 | operator U(qureg x,qureg y) { // Bundle all unitary operations 22 | H(x); // of the algorithm into one 23 | G(x,y); // operator U 24 | H(x & y); 25 | } 26 | 27 | procedure deutsch() { // Classical control structure 28 | qureg x[1]; // allocate 2 qubits 29 | qureg y[1]; 30 | int m; 31 | { // evaluation loop 32 | reset; // initialize machine state 33 | U(x,y); // do unitary computation 34 | measure y,m; // measure 2nd register 35 | } until m==1; // value in 1st register valid? 36 | measure x,m; // measure 1st register which 37 | print "g(0) xor g(1) =",m; // contains g(0) xor g(1) 38 | reset; // clean up 39 | } 40 | 41 | -------------------------------------------------------------------------------- /lib/grover.qcl: -------------------------------------------------------------------------------- 1 | qufunct query(qureg x,quvoid f,int n) { 2 | int i; 3 | for i=0 to #x-1 { // x -> NOT (x XOR n) 4 | if not bit(n,i) { Not(x[i]); } 5 | } 6 | CNot(f,x); // flip f if x=1111.. 7 | for i=0 to #x-1 { // x <- NOT (x XOR n) 8 | if not bit(n,i) { !Not(x[i]); } 9 | } 10 | } 11 | 12 | operator diffuse(qureg q) { 13 | H(q); // Hadamard Transform 14 | Not(q); // Invert q 15 | CPhase(pi,q); // Rotate if q=1111.. 16 | !Not(q); // undo inversion 17 | !H(q); // undo Hadamard Transform 18 | } 19 | 20 | operator search(qureg q,int n) { 21 | int i; 22 | qureg f[1]; 23 | for i=1 to ceil(sqrt(2^#q)) { 24 | query(q,f,n); 25 | CPhase(pi,f); 26 | !query(q,f,n); 27 | diffuse(q); 28 | } 29 | } 30 | 31 | procedure grover(int n) { 32 | int l=floor(log(n,2))+1; // no. of qubits 33 | int m=ceil(pi/8*sqrt(2^l)); // no. of iterations 34 | int x; 35 | int i; 36 | qureg q[l]; 37 | qureg f[1]; 38 | print l,"qubits, using",m,"iterations"; 39 | { 40 | reset; 41 | H(q); // prepare superposition 42 | for i= 1 to m { // main loop 43 | query(q,f,n); // calculate C(q) 44 | CPhase(pi,f); // negate |n> 45 | !query(q,f,n); // undo C(q) 46 | diffuse(q); // diffusion operator 47 | } 48 | measure q,x; // measurement 49 | print "measured",x; 50 | } until x==n; 51 | reset; // clean up local registers 52 | } 53 | 54 | -------------------------------------------------------------------------------- /debug.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef DEBUG_H 17 | #define DEBUG_H 18 | 19 | #include 20 | 21 | #include "symbols.h" 22 | #include "quheap.h" 23 | #include "syntax.h" 24 | 25 | #define DB_NORMAL 1 26 | #define DB_ESCAPE 2 27 | #define DB_ERROR 3 28 | #define DB_IRQ 4 29 | 30 | #define QL_ERRORREPORT 0 // report errors and continue 31 | #define QL_ERRORABORT 1 // abort on errors 32 | #define QL_ERRORRETURN 2 // return on errors 33 | #define QL_IGNOREEXIT 4 // ignore exit 34 | #define QL_NOERRMSG 8 // don't print errormessages 35 | 36 | /* 37 | class objlist : public list { 38 | public: 39 | objlist(); 40 | ~objlist(); 41 | }; 42 | */ 43 | 44 | extern int shell_depth; 45 | 46 | int qcllist(SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj=0,int flags=QL_ERRORREPORT); 47 | int qclfile(string fname,SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj=0,int flags=QL_ERRORRETURN); 48 | int qclshell(SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj=0,int cond=DB_NORMAL); 49 | int qclstring(string s,SymTable *loc,SymTable *gl,QuHeap *qh); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /qcl.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #include "syntax.h" 17 | #include "symbols.h" 18 | #include "error.h" 19 | #include "quheap.h" 20 | #include "parse.h" 21 | #include "options.h" 22 | #include "debug.h" 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | extern char *optarg; 29 | extern int optind; 30 | extern struct msgstruct *message; 31 | 32 | int main(int argc,char **argv) { 33 | string s; 34 | int i; 35 | 36 | initialize_readline(); 37 | parseopt(argc,argv); 38 | QuHeap qh(optBits); 39 | SymTab gl(1); 40 | SymTab loc; 41 | 42 | cout << format->output_beg; 43 | if(!optQuiet) { 44 | cout << "QCL Quantum Computation Language (" 45 | << optBits << " qubits, seed " << optSeed << ")\n"; 46 | } 47 | if(!optNoDefaultInclude) qclfile(DEF_STD_INCLUDE,&loc,&gl,&qh); 48 | for(i=optind;ioutput_end; 53 | return 0; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /format.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef FORMAT_H 17 | #define FORMAT_H 18 | 19 | struct OutputFormat { 20 | const char *output_beg; 21 | const char *output_end; 22 | const char *error_beg; 23 | const char *error_end; 24 | const char *msg_beg; 25 | const char *msg_end; 26 | const char *print_beg; 27 | const char *print_end; 28 | const char *prompt_beg; 29 | const char *prompt_end; 30 | const char *ps_beg; 31 | const char *ps_end; 32 | const char *latex_beg; 33 | const char *latex_end; 34 | const char *math_beg; 35 | const char *math_end; 36 | const char *texverb_beg; 37 | const char *texverb_end; 38 | const char *ket_beg; 39 | const char *ket_end; 40 | const char *exor; 41 | const char *imag; 42 | const char *ldots; 43 | const char *mult; 44 | const char *matrix_beg; 45 | const char *matrix_cont; 46 | const char *matrix_end; 47 | const char *matrix_col; 48 | const char *matrix_sep; 49 | const char *matrix_nl; 50 | }; 51 | 52 | extern const OutputFormat FormatPlain; 53 | extern const OutputFormat FormatXTerm; 54 | extern const OutputFormat FormatDarkXTerm; 55 | extern const OutputFormat FormatTeXmacs; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /parse.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef PARSE_H 17 | #define PARSE_H 18 | 19 | #include 20 | #include 21 | extern char *yytext; 22 | #define YYNEW(o) (yyTest ? 0 : new o) 23 | #define YYTRY(o) { if(!yyTest) { o; } } 24 | #define YYMAXINCLUDE 10 25 | #define YY_USER_INIT { yyToplevelFile=0; yyStringBufferActive=0; yyIncludeStackPt=0; } 26 | 27 | extern void yyrestart(FILE*); 28 | extern int yyparse(); 29 | extern int yydebug; 30 | 31 | extern void yyScanString(string s); 32 | extern void yyScanFile(FILE *f); 33 | extern void yyCleanUp(); 34 | 35 | class objlist : public list { 36 | public: 37 | ~objlist() { 38 | while(size()) { 39 | if(front()) delete front(); 40 | pop_front(); 41 | } 42 | } 43 | }; 44 | 45 | 46 | //extern sObject *yyObject; 47 | extern objlist *yyObjList; 48 | 49 | extern int yyTest; 50 | extern FILE* yyToplevelFile; 51 | extern int yyStringBufferActive; 52 | extern string yyFilenames[YYMAXINCLUDE]; 53 | extern FILE* yyFilePointers[YYMAXINCLUDE]; 54 | extern int yyLineNos[YYMAXINCLUDE]; 55 | extern int yyIncludeStackPt; 56 | extern string yyFilename; 57 | extern int yyLineNo; 58 | extern int yyStmtBeg; 59 | 60 | 61 | FILE* openqclfile(string fname); 62 | 63 | int chksyntax(string s); 64 | int chksyntax(FILE* f); 65 | objlist* parseobj(); 66 | string safestring(const char *s); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /cond.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include "cond.h" 19 | #include "types.h" 20 | 21 | string QuCond::str() const { 22 | string ostr=""; 23 | bitvec v; 24 | iter i; 25 | int j; 26 | if(elem()==0) return "<>"; 27 | for(i=cond.begin();i!=cond.end();i++) { 28 | ostr+=" "; 29 | v=*i; 30 | if(zero(v)) { 31 | ostr+="*;"; 32 | } else { 33 | for(j=0;jbasebits()); 46 | m.setbit(q->mapindex(i)); 47 | return QuCond(m); 48 | } 49 | 50 | QuCond regcomp(const quState *q,const quState *p) { 51 | QuCond c=QCTRUE(q->basebits()); 52 | int i; 53 | int n=q->mapbits(); 54 | if(n!=p->mapbits()) return QCFALSE(q->basebits()); 55 | for(i=0;ibasebits()); 62 | int i; 63 | for(i=0;imapbits();i++) { 64 | if(n&1) 65 | c=c & regbit(q,i); 66 | else 67 | c=c & ~regbit(q,i); 68 | n>>=1; 69 | } 70 | if(n) return QCFALSE(q->basebits()); 71 | return c; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /lib/primes.qcl: -------------------------------------------------------------------------------- 1 | set library 1; 2 | 3 | // returns the smallest factor > 1 of n or 1 if n is prime 4 | 5 | int findfactor(int n) { 6 | int i; 7 | if n<=0 { exit "findfactor takes only positive args"; } 8 | for i=2 to floor(sqrt(n)) { 9 | if n mod i == 0 { return i; } 10 | } 11 | return 1; 12 | } 13 | 14 | // test if n is a prime number 15 | 16 | boolean testprime(int n) { 17 | int i; 18 | if n<=1 { return false; } 19 | if n==2 or n==3 { return true; } 20 | if n mod 2 == 0 { return false; } 21 | for i=3 to floor(sqrt(n)) step 2 { 22 | if n mod i == 0 { return false; } 23 | } 24 | return true; 25 | } 26 | 27 | // test if n is a prime power 28 | 29 | boolean testprimepower(int n) { 30 | int i; 31 | int f; 32 | i=2; 33 | while i<=floor(sqrt(n)) and f==0 { 34 | if n mod i == 0 { f=i; } 35 | i=i+1; 36 | } 37 | for i=2 to floor(log(n,f)) { 38 | if f^i==n { return true; } 39 | } 40 | return false; 41 | } 42 | 43 | // returns x^a mod n 44 | 45 | int powmod(int x,int a,int n) { 46 | int u=x; 47 | int y=1; 48 | int i; 49 | 50 | for i=0 to 30 { 51 | if a/2^i mod 2 == 1 { y=y*u mod n; } 52 | u=u^2 mod n; 53 | } 54 | return y; 55 | } 56 | 57 | // return the modular inverse to a mod n or 0 if gcd(a,n)>1 58 | 59 | int invmod(int a,int n) { 60 | int b=a; 61 | int i; 62 | 63 | if gcd(a,n)>1 { return 0; } 64 | for i=1 to n { 65 | if b*a mod n == 1 { return b; } 66 | b=b*a mod n; 67 | } 68 | return 0; 69 | } 70 | 71 | // finds the denominator q of the best rational approximation p/q 72 | // for x with q=qmax { return q1; } 87 | q0=q1; q1=q2; 88 | } 89 | } 90 | 91 | set library 0; 92 | -------------------------------------------------------------------------------- /qc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for libqc 2 | # 3 | # This file is part of the Quantum Computation Library (QCLIB). 4 | # 5 | # (c) Copyright by Bernhard Oemer , 1998-2006 6 | # 7 | # This program comes without any warranty; without even the implied 8 | # warranty of merchantability or fitness for any particular purpose. 9 | # 10 | # This program is free software under the terms of the 11 | # GNU General Public Licence (GPL) version 2 or higher 12 | 13 | # Comment out if you want to compile for a different target architecture 14 | 15 | #ARCHOPT = -m32 -march=i686 16 | 17 | # Debugging options 18 | 19 | DEBUG = -g -O2 -DQC_DEBUG 20 | #DEBUG = -g -pg -DQC_DEBUG 21 | #DEBUG = -O2 22 | 23 | # Comment out if you if you want to use SysV Xrand48() linear congruential 24 | # PRG instead of the default random() non-linear additive feedback PRG. 25 | 26 | #PRGOPT = -DQC_USE_RAND48 27 | 28 | CXXFLAGS = $(ARCHOPT) -c -pedantic -Wall $(DEBUG) $(PRGOPT) 29 | 30 | LDFLAGS = $(ARCHOPT) -L. -lm -lqc 31 | 32 | FILESCC = bitvec.cc terms.cc qustates.cc operator.cc 33 | FILESH = bitvec.h terms.h qustates.h operator.h qc.h 34 | SOURCE = $(FILESCC) $(FILESH) shor.cc Makefile 35 | 36 | all: libqc.a 37 | 38 | libqc.a: bitvec.o terms.o qustates.o operator.o 39 | ar rc libqc.a bitvec.o terms.o qustates.o operator.o && ranlib libqc.a 40 | 41 | bitvec.o: bitvec.cc bitvec.h 42 | $(CXX) bitvec.cc -o bitvec.o $(CXXFLAGS) 43 | 44 | terms.o: terms.cc terms.h bitvec.h 45 | $(CXX) terms.cc -o terms.o $(CXXFLAGS) 46 | 47 | qustates.o: qustates.cc qustates.h terms.h bitvec.h 48 | $(CXX) qustates.cc -o qustates.o $(CXXFLAGS) 49 | 50 | operator.o: operator.cc operator.h qustates.h terms.h bitvec.h 51 | $(CXX) operator.cc -o operator.o $(CXXFLAGS) 52 | 53 | shor.o: shor.cc qustates.h terms.h bitvec.h 54 | $(CXX) shor.cc -o shor.o $(CXXFLAGS) 55 | 56 | shor: shor.o libqc.a 57 | $(CXX) shor.o -o shor $(LNKOPT) 58 | 59 | # Other Functions 60 | 61 | edit: 62 | nedit $(SOURCE) & 63 | 64 | clean: 65 | rm -f *.o 66 | 67 | clear: clean 68 | rm -f libqc.a shor 69 | -------------------------------------------------------------------------------- /error.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef ERROR_H 17 | #define ERROR_H 1 18 | 19 | #pragma interface 20 | 21 | #include "types.h" 22 | 23 | class tError; 24 | 25 | int yyerror(char*); 26 | 27 | enum ErrType { errNONE, errEXIT, errMSG, errINT, errLEXICAL, errPARSE, 28 | errTYPMIS, errINVTYP, errPARMIS, errINVPAR, errSYMBOL, 29 | errSCOPE, errDEF, errMATH,errRUN, errGEN, errSYNTAX, 30 | errUSR, errRANGE, errEXT, errIO, errSHELL, errMEM, 31 | errOPT, errIGNORE, errIRQ }; 32 | 33 | 34 | 35 | void initialize_readline(); 36 | 37 | void qclerror(string e); 38 | void qclerror(const tError& e); 39 | 40 | void qclabort(string e=""); 41 | void qclabort(const tError& e); 42 | 43 | 44 | string qclinput(string p="?"); 45 | 46 | void qcloutput(string s); 47 | void qclprint(string s); 48 | void qcllog(string s); 49 | void qclmessage(string s); 50 | 51 | void qcltrace(string s,sObject *obj,SymTable *loc,SymTable *gl,QuHeap *qh=0); 52 | 53 | extern int isErrorReported; 54 | 55 | 56 | class tError { 57 | ErrType err; 58 | string msg; 59 | string loc; 60 | sObject *obj; 61 | public: 62 | tError(ErrType t,string s="",sObject *o=0); 63 | void setobj(sObject *o); 64 | void setmsg(string s) { msg=s; } 65 | int hasobj() const { return loc!=""; } 66 | int hasmsg() const { return msg!=""; } 67 | string message() const { return msg; } 68 | string where() const { return loc; } 69 | ErrType type() const { return err; } 70 | sObject *object() const { return obj; } 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /symbols.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef SYMBOLS_H 17 | #define SYMBOLS_H 1 18 | 19 | #pragma interface 20 | 21 | #include "types.h" 22 | 23 | 24 | class SymTable { 25 | public: 26 | struct entry { 27 | sDef *pdef; 28 | tValue *pval; 29 | entry *pred; 30 | entry *succ; 31 | }; 32 | SymTable() { } 33 | virtual ~SymTable() { } 34 | virtual int put(sDef *d,const tValue& v=tValue()) = 0; 35 | virtual tValue getVal(const tId& id,ObjType *o=0) const = 0; 36 | virtual sDef *getDef(const tId& id) const = 0; 37 | virtual tValue *getRef(const tId& id,ObjType *o=0) const = 0; 38 | virtual string prtstr(int ind=NOINDENT) = 0; 39 | void print(ostream& o) { o << prtstr(); } 40 | }; 41 | 42 | class SymTab : public SymTable { 43 | entry *root; 44 | void deltree(entry *t); 45 | int putentry(entry *t,entry *e); 46 | entry *getentry(entry *t,const tId& id) const; 47 | string recstr(entry *e,int ind=NOINDENT); 48 | int global; 49 | public: 50 | SymTab(int g=0) : SymTable() { root=0; global=g; } 51 | virtual ~SymTab() { if(root) deltree(root); } 52 | virtual int put(sDef *d,const tValue& v=tValue()); 53 | virtual tValue getVal(const tId& id,ObjType *o=0) const; 54 | virtual sDef *getDef(const tId& id) const; 55 | virtual tValue *getRef(const tId& id,ObjType *o=0) const; 56 | virtual string prtstr(int ind=NOINDENT); 57 | }; 58 | 59 | class SymTabComb : public SymTable { 60 | SymTable *tab1; 61 | SymTable *tab2; 62 | public: 63 | SymTabComb(SymTable *t1,SymTable *t2) : SymTable() { 64 | tab1=t1; tab2=t2; } 65 | virtual ~SymTabComb() { }; 66 | virtual int put(sDef *d,const tValue& v=tValue()); 67 | virtual tValue getVal(const tId& id,ObjType *o=0) const; 68 | virtual sDef *getDef(const tId& id) const; 69 | virtual tValue *getRef(const tId& id,ObjType *o=0) const; 70 | virtual string prtstr(int ind=NOINDENT); 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /CHANGES: -------------------------------------------------------------------------------- 1 | Changes in 0.6.1: 2 | * Fixed -x option bug 3 | * new option --qcluserdir, --include-path renamed to --qcldir 4 | * new enviroment variable QCLUSERDIR 5 | 6 | Changes in 0.6.0: 7 | * Code cleanups for ISO C++ compliance 8 | * Dropped static binary support 9 | 10 | Changes in 0.5.1: 11 | * Double declaration as "qufunct operator" for non-boolean implementations 12 | of basis permutations 13 | * Recursive operator definitions 14 | * New auto-dump format which displays registers 15 | * Sample implementation of Deutsch's algorithm 16 | 17 | Changes in 0.5.0: 18 | 19 | * Conditional Operators and quantum conditions (experimental) 20 | * Vectors, matrices and tensors (see linalg.qcl) 21 | * New elementary operators (see default.qcl) 22 | * Plotting of states and spectrums via the new "plot" command 23 | * New and revised sample programs 24 | * break-statement for loops 25 | * Bitwise not, and, or, xor as built-in functions 26 | * Built in function bit(n,i) (i-th bit of binary expansion of n) 27 | * Improved TeXmacs support 28 | * Support for keyboard interrupts (SIGINT, SIGTSTP) 29 | * Optimizations in the simulation layer (more than 300% speedup in some 30 | cases) 31 | * Removal of legacy code for old complex- and string-classes 32 | * Improved support for non-Intel plattforms 33 | * Rewrite of Error handling to use C++ exceptions 34 | * Major code-cleanups 35 | * Minor bug fixes 36 | 37 | Changes in 0.4.3: 38 | 39 | * Color XTerm and TeXmacs support (by Andrey G. Grozin). 40 | * Bug with random() on non-GNU systems fixed (thanks to Joel Hegg). 41 | * Internal changes. 42 | 43 | Changes in 0.4.2: 44 | 45 | * Compile glitch fixed with RedHat 7.2. 46 | * Nicer output of quantum states. 47 | 48 | Changes in 0.4.1: 49 | 50 | * ANSI C++ complience (except for local array variables). 51 | * Fixed unitarity testing for matrix operators. 52 | * Minor bugfixes. 53 | 54 | Changes in 0.4.0: 55 | 56 | * As the available documentation already exceeds the size of the 57 | source code by an order of magnitude, the manual is no longer part 58 | of the main distribution. If you are new to QCL, you probably want 59 | do check out the Documentation section below. 60 | * A sample inplementation of Grover's Database Search algorithm is 61 | contained in the lib directory. 62 | * The QCL searchpath now also looks for qcl-files in ./lib. 63 | * Besides the dynamically linked program, the binary package now 64 | also contains a static binary qcl-static. 65 | * minor bugfixes. 66 | 67 | -------------------------------------------------------------------------------- /lib/shor.qcl: -------------------------------------------------------------------------------- 1 | include "modarith.qcl"; 2 | include "dft.qcl"; 3 | 4 | procedure shor(int number) { 5 | int width=ceil(log(number,2)); // size of number in bits 6 | qureg reg1[2*width]; // first register 7 | qureg reg2[width]; // second register 8 | int qmax=2^width; 9 | int factor; // found factor 10 | int m; real c; // measured value 11 | int x; // base of exponentiation 12 | int p; int q; // rational approximation p/q 13 | int a; int b; // possible factors of number 14 | int e; // e=x^(q/2) mod number 15 | 16 | if number mod 2 == 0 { exit "number must be odd"; } 17 | if testprime(number) { exit "prime number"; } 18 | if testprimepower(number) { exit "prime power"; }; 19 | { 20 | { // generate random base 21 | x=floor(random()*(number-3))+2; 22 | } until gcd(x,number)==1; 23 | print "chosen random x =",x; 24 | H(reg1); // Hadamard transform 25 | expn(x,number,reg1,reg2); // modular exponentiation 26 | measure reg2; // measure 2nd register 27 | dft(reg1); // Fourier transform 28 | measure reg1,m; // measure 2st register 29 | reset; // clear local registers 30 | if m==0 { // failed if measured 0 31 | print "measured zero in 1st register. trying again ..."; 32 | } else { 33 | c=m*0.5^(2*width); // fixed point form of m 34 | q=denominator(c,qmax); // find rational approximation 35 | p=floor(q*c+0.5); 36 | print "measured",m,", approximation for",c,"is",p,"/",q; 37 | if q mod 2==1 and 2*q, 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #include "syntax.h" 17 | #include "symbols.h" 18 | #include "error.h" 19 | #include "parse.h" 20 | #include "options.h" 21 | 22 | objlist *yyObjList; 23 | int yyTest; 24 | FILE* yyToplevelFile; 25 | int yyStringBufferActive; 26 | string yyFilenames[YYMAXINCLUDE]; 27 | FILE* yyFilePointers[YYMAXINCLUDE]; 28 | int yyLineNos[YYMAXINCLUDE]; 29 | int yyIncludeStackPt = 0; 30 | string yyFilename=""; 31 | 32 | extern char *yytext; 33 | extern int yylineno; 34 | 35 | string safestring(const char *s) { 36 | string t; 37 | while(*s) { 38 | if(isprint(*s)) 39 | t+=*s; 40 | else 41 | t+=sdec(*s,"\\0%lo"); 42 | s++; 43 | } 44 | return t; 45 | } 46 | 47 | int yyerror(char* s) { 48 | string t; 49 | if(!yyStringBufferActive) { 50 | t+="in "+yyFilename+", line "+sdec(yylineno)+", "; 51 | }; 52 | t+="near \""+safestring(yytext)+"\""; 53 | qclerror(t); 54 | qclerror(s); 55 | return 1; 56 | } 57 | 58 | FILE* openqclfile(string fname) { 59 | string s; 60 | FILE *f; 61 | s=fname; 62 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 63 | s=fname+".qcl"; 64 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 65 | if(optUserPath!="") { 66 | s=optUserPath+"/"+fname; 67 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 68 | s=optUserPath+"/"+fname+".qcl"; 69 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 70 | } 71 | if(optIncludePath!="") { 72 | s=optIncludePath+"/"+fname; 73 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 74 | s=optIncludePath+"/"+fname+".qcl"; 75 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 76 | } 77 | s="lib/"+fname; 78 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 79 | s="lib/"+fname+".qcl"; 80 | if(( f=fopen(s.c_str(),"r") )) { yyFilename=s; return f; }; 81 | return 0; 82 | } 83 | 84 | int chksyntax(string s) { 85 | int r; 86 | yyTest=1; 87 | yyObjList=0; 88 | yyScanString(s); 89 | r=yyparse(); 90 | yyCleanUp(); 91 | yyTest=0; 92 | return r; 93 | } 94 | 95 | int chksyntax(FILE* f) { 96 | int r; 97 | yyTest=1; 98 | yyObjList=0; 99 | yyScanFile(f); 100 | r=yyparse(); 101 | yyCleanUp(); 102 | yyTest=0; 103 | return r; 104 | } 105 | 106 | objlist* parseobj() { 107 | yyTest=0; 108 | yyObjList=0; 109 | int r; 110 | r=yyparse(); 111 | if(r || !yyObjList) qclabort("parsing failed"); 112 | return yyObjList; 113 | } 114 | -------------------------------------------------------------------------------- /lib/linalg.qcl: -------------------------------------------------------------------------------- 1 | set library 1; 2 | 3 | complex matrix diag(complex vector v) { 4 | complex matrix m[#v]; 5 | int i; 6 | for i=0 to #v-1 { m[i,i]=v[i]; } 7 | return m; 8 | } 9 | 10 | complex vector unitv(int d,int i) { 11 | complex vector v[d]; 12 | v[i]=1; 13 | return v; 14 | } 15 | 16 | complex matrix unitm(int d) { 17 | complex matrix m[d]; 18 | int i; 19 | for i=0 to d-1 { m[i,i]=1; } 20 | return m; 21 | } 22 | 23 | complex matrix trans(complex matrix m) { 24 | complex matrix mm[#m]; 25 | int i; int j; 26 | for i=0 to #m-1 { 27 | for j=0 to #m-1 { 28 | mm[i,j]=m[j,i]; 29 | } 30 | } 31 | return mm; 32 | } 33 | 34 | complex matrix adj(complex matrix m) { 35 | complex matrix mm[#m]; 36 | int i; int j; 37 | for i=0 to #m-1 { 38 | for j=0 to #m-1 { 39 | mm[i,j]=conj(m[j,i]); 40 | } 41 | } 42 | return mm; 43 | } 44 | 45 | complex vector column(complex matrix m,int j) { 46 | int i; 47 | complex vector v[#m]; 48 | for i=0 to #m-1 { 49 | v[i]=m[i,j]; 50 | } 51 | return v; 52 | } 53 | 54 | complex vector row(complex matrix m,int i) { 55 | int j; 56 | complex vector v[#m]; 57 | for j=0 to #m-1 { 58 | v[j]=m[i,j]; 59 | } 60 | return v; 61 | } 62 | 63 | complex matrix submatrix(complex matrix m,int i,int j) { 64 | complex matrix mm[#m-1]; 65 | int ii; int jj; 66 | for ii=0 to #m-2 { 67 | for jj=0 to #m-2 { 68 | mm[ii,jj]=m[ii+int(ii>=i),jj+int(jj>=j)]; 69 | } 70 | } 71 | return mm; 72 | } 73 | 74 | complex det(complex matrix m) { 75 | int i; 76 | complex d; 77 | if #m==1 { return m[0,0]; } 78 | for i=0 to #m-1 { 79 | if m[i,0]!=0 { 80 | d=d+(-1)^i*m[i,0]*det(submatrix(m,i,0)); 81 | } 82 | } 83 | return d; 84 | } 85 | 86 | complex trace(complex matrix m) { 87 | int i; 88 | complex t; 89 | for i=0 to #m-1 { t=t+m[i,i]; } 90 | return t; 91 | } 92 | 93 | complex matrix inverse(complex matrix m) { 94 | int i; int j; 95 | complex matrix mm[#m]; 96 | complex d=det(m); 97 | if d==0 { exit "matrix is singular"; } 98 | for i=0 to #m-1 { 99 | for j=0 to #m-1 { 100 | mm[i,j]=(-1)^(i+j)*det(submatrix(m,j,i))/d; 101 | } 102 | } 103 | return mm; 104 | } 105 | 106 | const epsilon=tensor3(0,0,0,0,0,1,0,-1,0,0,0,-1,0,0,0,1,0,0,0,1,0,-1,0,0,0,0,0); 107 | 108 | complex vector cross(complex vector a,complex vector b) { 109 | return (epsilon*b)*a; 110 | } 111 | 112 | complex matrix outer(complex vector a,complex vector b) { 113 | int i; int j; 114 | complex matrix m[#a]; 115 | for i=0 to #a { 116 | for j=0 to #b { 117 | m[i,j]=a[i]*b[j]; 118 | } 119 | } 120 | return m; 121 | } 122 | 123 | complex tensor3 outervm(complex vector v,complex matrix m) { 124 | int i; int j; int k; 125 | complex tensor3 t[#v]; 126 | for i=0 to #v-1 { 127 | for j=0 to #m-1 { 128 | for k=0 to #m-1 { 129 | t[i,j,k]=v[i]*m[j,k]; 130 | } 131 | } 132 | } 133 | return t; 134 | } 135 | 136 | complex tensor3 outermv(complex matrix m,complex vector v) { 137 | int i; int j; int k; 138 | complex tensor3 t[#m]; 139 | for i=0 to #m-1 { 140 | for j=0 to #m-1 { 141 | for k=0 to #v-1 { 142 | t[i,j,k]=m[i,j]*v[k]; 143 | } 144 | } 145 | } 146 | return t; 147 | } 148 | 149 | set library 0; 150 | 151 | -------------------------------------------------------------------------------- /options.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef OPTIONS_H 17 | #define OPTIONS_H 1 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "types.h" 25 | #include "format.h" 26 | 27 | #define VERSION "QCL version 0.6.3" 28 | #define COPYRIGHT "(c) by Bernhard Oemer, 1998-2006" 29 | #define DISCLAIMER "This program is free software under the terms of the GPL" 30 | 31 | #define QUOTE(x) #x 32 | 33 | #ifndef DEF_INCLUDE_PATH 34 | #define DEF_INCLUDE_PATH "/usr/local/lib/qcl" 35 | #endif 36 | 37 | #define ENV_INCLUDE_PATH "QCLDIR" 38 | #define ENV_USER_PATH "QCLUSERDIR" 39 | 40 | #ifndef DEF_STD_INCLUDE 41 | #define DEF_STD_INCLUDE "default.qcl" 42 | #endif 43 | 44 | #ifndef DEF_LOAD_FILE 45 | #define DEF_LOAD_FILE "qclstate" 46 | #endif 47 | 48 | #ifndef DEF_SAVE_FILE 49 | #define DEF_SAVE_FILE DEF_LOAD_FILE 50 | #endif 51 | 52 | #ifndef DEF_DATAFILE_EXT 53 | #define DEF_DATAFILE_EXT ".qst" 54 | #endif 55 | 56 | #ifndef EPSILON_MATRIX 57 | #define EPSILON_MATRIX 0.000001 58 | #endif 59 | 60 | #ifndef EPSILON_CHECK 61 | #define EPSILON_CHECK 0.000001 62 | #endif 63 | 64 | #ifndef AUTODUMP_STATES 65 | #define AUTODUMP_STATES 8 66 | #endif 67 | 68 | 69 | extern const OutputFormat *format; 70 | extern ofstream *file; 71 | 72 | extern char *optarg; 73 | extern int optind; 74 | 75 | void printusage(char *name); 76 | void evalopt(int c,const char *optarg); 77 | void parseopt(int argc,char **argv); 78 | 79 | extern struct option qcl_options[]; 80 | 81 | extern int optInteractive; 82 | extern int optQuiet; 83 | extern string optExec; 84 | extern const OutputFormat *optInterface; 85 | extern int optTeXmacs; 86 | extern int optColor; 87 | extern int optNoDefaultInclude; 88 | extern ofstream *optLogfile; 89 | extern int optBits; 90 | extern string optIncludePath; 91 | extern string optUserPath; 92 | extern int optSeed; 93 | extern char optDumpFormat; 94 | extern int optShowRegs; 95 | extern int optQuregMask; 96 | extern int optDebug; 97 | extern int optAutoDump; 98 | extern int optDumpPrecision; 99 | extern tReal optDumpEpsilon; 100 | extern int optTrucStates; 101 | extern int optPrintPrecision; 102 | extern int optTruncZeros; 103 | extern string optPlotPaper; 104 | extern int optPlotSize; 105 | extern string optDumpFilename; 106 | extern string optPlotFilename; 107 | extern int optLog; 108 | extern int optLogState; 109 | extern int optCheck; 110 | extern int optTrace; 111 | extern int optSyntax; 112 | extern int optEcho; 113 | extern int optTest; 114 | extern int optShellEscape; 115 | extern int optAllowRedefines; 116 | extern int optIRQ; 117 | 118 | #define IRQ_NONE 0 119 | #define IRQ_SHELL 1 120 | #define IRQ_EXIT 2 121 | 122 | void irqOn(); 123 | void irqOff(); 124 | extern volatile int irqFlag; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /lib/test.qcl: -------------------------------------------------------------------------------- 1 | include "shor"; 2 | include "grover"; 3 | 4 | procedure testexpn() { 5 | qureg q[6]; 6 | qureg p[8]; 7 | int m; 8 | print "testing modular exponentiation (7^x mod 31)"; 9 | reset; 10 | set seed 0; 11 | H(q); 12 | expn(7,31,q,p); 13 | measure q,m; 14 | if m!=32 { 15 | print "measured",m,"expected 32"; 16 | } 17 | reset; 18 | } 19 | 20 | procedure testdft() { 21 | qureg q[6]; 22 | print "testing discrete Fourier transform"; 23 | reset; 24 | dft(q); 25 | CPhase(pi/2,q[1]); 26 | !dft(q); 27 | print "expecting (1+i)/2 |000000> - i/2 |010000> + 1/2 |110000>"; 28 | dump; 29 | reset; 30 | } 31 | 32 | procedure testcond() { 33 | qureg a[1]; 34 | qureg b[1]; 35 | qureg c[1]; 36 | qureg d[1]; 37 | qureg e[1]; 38 | qureg q[1]; 39 | 40 | print "testing quantum conditions"; 41 | reset; 42 | set log 1; 43 | print a; 44 | if a { Not(q); }; 45 | print a and c; 46 | if a and c { Not(q); }; 47 | print (a or b) and c; 48 | if (a or b) and c { Not(q); }; 49 | print (a and b) xor (c and d); 50 | if (a and b) xor (c and d) { Not(q); }; 51 | print (a or b) and c; 52 | if (a or b) and c { Phase(pi/3); } else { Phase(-pi/3); } 53 | print a or b, c or d,d or e; 54 | if a or b { 55 | if c or d { 56 | Phase(pi/2); 57 | } else { 58 | Phase(pi/3); 59 | } 60 | } else { 61 | if d or e { 62 | Phase(pi/4); 63 | } else { 64 | Phase(pi/5); 65 | } 66 | } 67 | set log 0; 68 | reset; 69 | } 70 | 71 | operator tf1(qureg q) { 72 | int i; 73 | for i=0 to #q-1 { 74 | if q[i] { break; } 75 | Phase(pi/2^i); 76 | } 77 | } 78 | 79 | cond operator tf2(qureg q,qureg p) { 80 | int i; 81 | int n=0; 82 | for i=0 to #q-1 { 83 | if q[i] { n=i; } 84 | } 85 | Not(p[n]); 86 | } 87 | 88 | procedure testfork() { 89 | qureg q[3]; 90 | qureg p[3]; 91 | 92 | print "testing forking quantum if-statements"; 93 | reset; 94 | H(q); 95 | set log 1; 96 | list tf1; 97 | tf1(q); 98 | set log 0; 99 | dump; 100 | reset; 101 | H(q); 102 | set log 1; 103 | list tf2; 104 | tf2(q,p); 105 | set log 0; 106 | dump; 107 | reset; 108 | } 109 | 110 | procedure testbitops() { 111 | qureg q[1]; 112 | print "Operator H:"; 113 | reset; 114 | H(q); !H(q); dump; 115 | H(q); 116 | dump; 117 | reset; Not(q); 118 | H(q); 119 | dump; 120 | 121 | print "Operator X:"; 122 | reset; 123 | X(q); !X(q); dump; 124 | X(q); 125 | dump; 126 | reset; Not(q); 127 | X(q); 128 | dump; 129 | 130 | print "Operator Y:"; 131 | reset; 132 | Y(q); !Y(q); dump; 133 | Y(q); 134 | dump; 135 | reset; Not(q); 136 | Y(q); 137 | dump; 138 | 139 | print "Operator Z:"; 140 | reset; 141 | Z(q); !Z(q); dump; 142 | Z(q); 143 | dump; 144 | reset; Not(q); 145 | Z(q); 146 | dump; 147 | 148 | print "Operator S:"; 149 | reset; 150 | S(q); !S(q); dump; 151 | S(q); 152 | dump; 153 | reset; Not(q); 154 | S(q); 155 | dump; 156 | 157 | print "Operator T:"; 158 | reset; 159 | T(q); !T(q); dump; 160 | T(q); 161 | dump; 162 | reset; Not(q); 163 | T(q); 164 | dump; 165 | 166 | reset; 167 | } 168 | 169 | set seed 0; 170 | set check 1; 171 | set echo 1; 172 | 173 | shor(15); 174 | grover(123); 175 | testexpn(); 176 | testdft(); 177 | //testcond(); 178 | //testfork(); 179 | //testbitops(); 180 | 181 | -------------------------------------------------------------------------------- /qc/terms.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #pragma implementation "terms.h" 16 | 17 | #include "terms.h" 18 | 19 | #include 20 | 21 | using namespace std; 22 | 23 | #define NONE (-1) 24 | 25 | DEBUG( int nterms=0; ) 26 | DEBUG( int ntermlists=0; ) 27 | DEBUG( int nprobtrees=0; ) 28 | 29 | 30 | /* member functions */ 31 | 32 | // class termlist: 33 | 34 | termlist::termlist(int bits,int len) { 35 | _nbits=bits; 36 | listlen=len; 37 | hashlen=1<=listlen) { 87 | pt=list; 88 | n=_nterms; 89 | listlen*=2; 90 | hashlen*=2; 91 | hashmask=hashlen-1; 92 | qc_delarray(hash); 93 | newlist(); 94 | clear(); 95 | for(i=0;ivect()==v) { 107 | pt->setampl(pt->ampl()+z); 108 | return; 109 | }; 110 | h+=hashfunct2(v); 111 | h&=hashmask; 112 | }; 113 | } 114 | 115 | /* other functions */ 116 | 117 | int duallog(int k) { 118 | int i=0; 119 | 120 | for(;k!=0;k>>=1) i++; 121 | return i; 122 | } 123 | 124 | ostream& operator << (ostream& s,const term& t) { 125 | complx z=t.ampl(); 126 | //s.form("%+19.17f\t%+19.17f\t",z.real(),z.imag()); 127 | s << setw(19) << setprecision(17) << z.real() << '\t'; 128 | s << setw(19) << setprecision(17) << z.imag() << '\t'; 129 | s << t.vect(); 130 | return s; 131 | } 132 | 133 | istream& operator >> (istream& s,term& t) { 134 | bitvec v(t.nbits()); 135 | double x=10,y=10; 136 | 137 | //s.scan("%lf %lf",&x,&y); 138 | s >> x >> y; 139 | if(x>1 || x<-1 || y>1 || y<-1) goto error; 140 | s >> v; 141 | t.setvect(v); 142 | t.setampl(complx(x,y)); 143 | return s; 144 | error: 145 | t.setvect(bitvec()); 146 | return s; 147 | } 148 | 149 | -------------------------------------------------------------------------------- /quheap.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef QUHEAP_H 17 | #define QUHEAP_H 18 | 19 | #pragma interface 20 | 21 | #include "operator.h" 22 | #include "types.h" 23 | #include "syntax.h" 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | extern int isStateModified; 30 | 31 | term string2term(const string& s,int l); 32 | string term2string(const term& t,int binary=0); 33 | 34 | class QuHeap { 35 | struct quentry { 36 | sRoutDef *d; 37 | SymTable *s; 38 | int i; 39 | }; 40 | struct centry { 41 | QuCond qc; 42 | QuCond qc0; 43 | tValue tmp; 44 | quState *reg; 45 | quState *reg0; 46 | bitvec dep; 47 | bitvec inv; 48 | vector *ev; 49 | }; 50 | int nbits; 51 | bitvec mbits; 52 | int nfree; 53 | bitvec mfree; 54 | int ndirty; 55 | bitvec mdirty; 56 | quState *bs; 57 | QuHeap *parent; 58 | int delbs; 59 | int delayed; 60 | 61 | int ignore; 62 | bitvec fmask; 63 | bitvec oldfmask; 64 | int qconds; 65 | vector cd; 66 | vector ql; 67 | vector regs; 68 | void init(); 69 | quentry makeentry(tId op,SymTable *gl,int inv=0,int cnd=1, 70 | tValue a=tUNDEF,tValue b=tUNDEF,tValue c=tUNDEF); 71 | void callentry(const quentry& q,SymTable *gl); 72 | public: 73 | int ncond() const { return fmask.length(); } 74 | quState *cond() const { 75 | return ncond() ? cd.back().reg0 : 0; 76 | } 77 | bitvec cmask() const { 78 | return fmask.length() ? cd.back().dep : bitvec(nbits); 79 | } 80 | bitvec imask() const { 81 | return fmask.length() ? cd.back().inv : bitvec(nbits); 82 | } 83 | 84 | QuHeap(int n,int d=0); 85 | QuHeap(quState *s,int d=0); 86 | QuHeap(QuHeap *h,int d=0); 87 | ~QuHeap(); 88 | tValue qualloc(int n,BaseType t=tQUREG); 89 | void qufree(tValue var); 90 | tValue measure(tValue); 91 | void reset(); 92 | 93 | void addReg(quState *r) { regs.push_back(tValue(*r)); }; 94 | int Regs() const { return regs.size(); } 95 | const quState* Reg(int i) const { return regs[i].qustate(); }; 96 | 97 | void qcond(quState *s,SymTable *gl); 98 | int qif(QuCond qc,SymTable *gl,int has_else=0); 99 | int qelse(QuCond qc,SymTable *gl); 100 | void qendif(SymTable *gl); 101 | int qendfork(SymTable *gl); 102 | 103 | void add(sRoutDef *d,SymTable *s,int inv); 104 | void apply(SymTable *gl,int inv); 105 | 106 | void call(tId op,SymTable *gl,int inv=0,int cnd=1, 107 | tValue a=tUNDEF,tValue b=tUNDEF,tValue c=tUNDEF); 108 | void call(sRoutDef *d,SymTable *loc,SymTable *gl,int inv=0,int cnd=1); 109 | string prtstr(); 110 | quState *state() const { return bs; } 111 | int nBits() const { return nbits; } 112 | bitvec mBits() const { return mbits; } 113 | int nFree() const { return nfree; } 114 | bitvec mFree() const { return mfree; } 115 | int nDirty() const { return ndirty; } 116 | bitvec mDirty() const { return mdirty; } 117 | int nTerms() const { return bs ? bs->baseterms() : 0; } 118 | 119 | int load(ifstream& f); 120 | int save(ofstream& f); 121 | 122 | // workaround for broken template lib. 123 | // QuHeap& operator=(QuHeap const &) { assert(0); return *this; }; 124 | }; 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /cond.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #ifndef COND_H 17 | #define COND_H 1 18 | 19 | #pragma interface 20 | 21 | #include "qc.h" 22 | 23 | #include 24 | #include 25 | 26 | #define QCFALSE(b) QuCond(b) 27 | #define QCTRUE(b) (~QuCond(b)) 28 | 29 | class QuCond { 30 | int _bits; 31 | set cond; 32 | typedef set::iterator iter; 33 | iter cursor; 34 | void add(const bitvec& v) { 35 | iter p; 36 | p=cond.find(v); 37 | if(p==cond.end()) 38 | cond.insert(v); 39 | else 40 | cond.erase(v); 41 | } 42 | public: 43 | QuCond() { _bits=0; } 44 | QuCond(int n) { _bits=n; } 45 | QuCond(const quState *q) { 46 | _bits=q->basebits(); 47 | cond.insert(q->unmap(~bitvec(q->mapbits()))); 48 | } 49 | QuCond(const bitvec& v) { 50 | _bits=v.length(); 51 | cond.insert(v); 52 | } 53 | int bits() const { return _bits; } 54 | int elem() const { return cond.size(); } 55 | bitvec clause(int n) const { 56 | iter i=cond.begin(); 57 | while(i!=cond.end() && n--) i++; 58 | if(i!=cond.end()) return *i; 59 | return bitvec(bits()); 60 | } 61 | int isTrue() const { return elem()==1 && zero(*cond.begin()); } 62 | int isFalse () const { return elem()==0; } 63 | QuCond operator ~ () const { 64 | QuCond r(*this); 65 | r.add(bitvec(bits())); 66 | return r; 67 | } 68 | QuCond operator ^ (const QuCond& c) const { 69 | if(isFalse()) return c; 70 | QuCond r(c); 71 | iter i; 72 | for(i=cond.begin();i!=cond.end();i++) r.add(*i); 73 | return r; 74 | } 75 | QuCond operator & (const QuCond& c) const { 76 | if(isTrue()) return c; 77 | if(c.isTrue()) return *this; 78 | QuCond r(bits()); 79 | iter i,j; 80 | for(i=cond.begin();i!=cond.end();i++) 81 | for(j=c.cond.begin();j!=c.cond.end();j++) 82 | r.add(*i | *j); 83 | return r; 84 | } 85 | QuCond operator | (const QuCond& c) const { 86 | if(isFalse()) return c; 87 | if(c.isFalse()) return *this; 88 | return c ^ (*this) ^ (c & (*this)); 89 | } 90 | bitvec depmask() const { 91 | iter i; 92 | bitvec m(bits()); 93 | for(i=cond.begin();i!=cond.end();i++) m|=(*i); 94 | return m; 95 | } 96 | bitvec first() { 97 | cursor=cond.begin(); 98 | return cursor==cond.end() ? bitvec(0) : *cursor; 99 | } 100 | bitvec next() { 101 | if(cursor!=cond.end()) cursor++; 102 | return cursor==cond.end() ? bitvec(0) : *cursor; 103 | } 104 | string str() const; 105 | }; 106 | 107 | inline int operator == (const QuCond& a,const QuCond& b) { 108 | if(a.elem()!=b.elem() || a.bits()!=b.bits()) return 0; 109 | return (a^b).isFalse(); 110 | } 111 | 112 | inline int operator != (const QuCond& a,const QuCond& b) { 113 | if(a.elem()!=b.elem() || a.bits()!=b.bits()) return 1; 114 | return !(a^b).isFalse(); 115 | } 116 | 117 | inline int operator < (const QuCond& a,const QuCond& b) { 118 | if(a.bits()!=b.bits()) return 0; 119 | if(a.elem() (const QuCond& a,const QuCond& b) { 124 | if(a.bits()!=b.bits()) return 0; 125 | if(a.elem()>b.elem()) return 1; 126 | return a.depmask().nset()>b.depmask().nset(); 127 | } 128 | 129 | QuCond regcomp(const quState *q,const quState *p); 130 | QuCond regcomp(const quState *q,int n); 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /debug.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #include "syntax.h" 17 | #include "symbols.h" 18 | #include "error.h" 19 | #include "parse.h" 20 | #include "options.h" 21 | #include "debug.h" 22 | #include "dump.h" 23 | 24 | /* 25 | 26 | objlist::objlist() : list() { 27 | sObject *p; 28 | while((p=parseobj())) push_back(p); 29 | yyCleanUp(); 30 | } 31 | 32 | objlist::~objlist() { 33 | while(size()) { 34 | delete front(); 35 | pop_front(); 36 | } 37 | } 38 | 39 | */ 40 | 41 | int shell_depth=-1; 42 | 43 | int qcllist(SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj,int flags) { 44 | objlist *o; 45 | sObject *p; 46 | 47 | o=parseobj(); 48 | while(o->size()) { 49 | p=o->front(); 50 | if(optEcho) qcloutput(p->prtstr(INDENT)); 51 | if(p->isInclude()) { 52 | if(qclfile(((sInclude*)p)->filename(),loc,gl,qh,0,flags|QL_ERRORRETURN)) { 53 | delete o; 54 | return 1; 55 | } 56 | o->pop_front(); 57 | delete p; 58 | continue; 59 | } 60 | try { 61 | p->typecheck(loc,gl); 62 | if(p->isDef()) { 63 | ((sDef*)p)->define(loc,gl,qh); 64 | } else if(p->isStmt()) { 65 | ((sStmt*)p)->exec(loc,gl,qh); 66 | delete p; 67 | } else { 68 | throw tError(errINT,"input is neither definition nor statement"); 69 | } 70 | } catch(tError e) { 71 | if(e.type()==errEXIT) { delete o; return 2; } 72 | if(e.type()==errIGNORE) { 73 | } else { 74 | if(flags&QL_ERRORABORT) qclabort(e); 75 | if(!(flags&QL_NOERRMSG)) qclerror(e); 76 | if(flags&QL_ERRORRETURN) { delete o; return 1; } 77 | } 78 | delete p; 79 | } 80 | o->pop_front(); 81 | } 82 | return 0; 83 | } 84 | 85 | int qclfile(string fname,SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj,int flags) { 86 | FILE *f; 87 | string s; 88 | 89 | f=openqclfile(fname); 90 | if(!f) { qclerror("Can't open "+fname); return 1; } 91 | if(chksyntax(f)) return 1; 92 | f=openqclfile(fname); 93 | if(!f) { 94 | qclerror("Can't reopen "+fname); 95 | return 1; 96 | } 97 | yyScanFile(f); 98 | return qcllist(loc,gl,qh,0,flags | QL_ERRORRETURN); 99 | } 100 | 101 | int qclshell(SymTable *loc,SymTable *gl,QuHeap *qh,sObject *obj,int cond) { 102 | string s,prompt; 103 | 104 | SymTab l,g(1); 105 | SymTabComb lcomb((SymTable*)&l,loc),gcomb((SymTable*)&g,gl); 106 | QuHeap lqh(qh); 107 | 108 | irqOff(); 109 | shell_depth++; 110 | if(cond==DB_ESCAPE) qclmessage("shell escape"); 111 | if(cond==DB_ERROR) { 112 | qclmessage("debug shell"); 113 | qcloutput(loc->prtstr(1)); 114 | } 115 | if(cond==DB_IRQ && obj) { 116 | qclmessage("user interrupt in "+obj->defstr()); 117 | qcloutput(loc->prtstr(1)); 118 | } 119 | prompt="qcl"; 120 | if(shell_depth>=1) prompt+=(char)('0'+shell_depth); 121 | prompt+=cond==DB_ERROR ? "$ " : "> "; 122 | 123 | while(1) { 124 | if(isStateModified) lqh.state()->normalize(); 125 | if(optAutoDump && isStateModified) report_state(&lqh); 126 | isStateModified=0; 127 | s=qclinput(prompt); 128 | if(s.substr(0,prompt.length())==prompt) 129 | s=s.erase(0,prompt.length()); 130 | if(s=="\n") continue; 131 | if(s=="") { cout << "\n"; break; } 132 | s+=";"; 133 | if(chksyntax(s)) continue; 134 | yyScanString(s); 135 | if(qcllist(&lcomb,&gcomb,&lqh,0,QL_ERRORRETURN)==2) break; 136 | }; 137 | shell_depth--; 138 | return 0; 139 | } 140 | 141 | int qclstring(string s,SymTable *loc,SymTable *gl,QuHeap *qh) { 142 | if(chksyntax(s)) return 1; 143 | yyScanString(s); 144 | return qcllist(loc,gl,qh,0,QL_ERRORRETURN); 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /symbols.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include "symbols.h" 19 | #include "syntax.h" 20 | 21 | #define IND() if(ind!=NOINDENT) \ 22 | { int i; for(i=0;ipred) deltree(t->pred); 29 | if(t->succ) deltree(t->succ); 30 | if(t->pval) qcl_delete(t->pval); 31 | if(global && t->pdef) qcl_delete(t->pdef); 32 | qcl_delete(t); 33 | } 34 | 35 | int SymTab::putentry(entry *t,entry *e) { 36 | if(e->pdef->id()pdef->id()) { 37 | if(t->pred) return putentry(t->pred,e); 38 | t->pred=e; 39 | return 0; 40 | }; 41 | if(e->pdef->id()>t->pdef->id()) { 42 | if(t->succ) return putentry(t->succ,e); 43 | t->succ=e; 44 | return 0; 45 | }; 46 | return 1; 47 | } 48 | 49 | SymTab::entry * SymTab::getentry(entry *t,const tId& id) const { 50 | if(id==t->pdef->id()) return t; 51 | if(t->pred && idpdef->id()) return getentry(t->pred,id); 52 | if(t->succ && id>t->pdef->id()) return getentry(t->succ,id); 53 | return 0; 54 | } 55 | 56 | int SymTab::put(sDef *d,const tValue& v) { 57 | entry *e; 58 | 59 | if(!d->isDef()) return 1; 60 | e=new entry; 61 | e->pdef=d; 62 | e->pval= d->isValueDef() ? new tValue(v) : 0; 63 | e->pred=e->succ=0; 64 | if(root) return putentry(root,e); 65 | root=e; 66 | return 0; 67 | } 68 | 69 | tValue SymTab::getVal(const tId& id,ObjType *o) const { 70 | entry *e; 71 | 72 | if(!root) return tValue(); 73 | e=getentry(root,id); 74 | if(!e) return tValue(); 75 | if(!e->pdef->isValueDef()) return tValue(); 76 | if(o) *o=e->pdef->object(); 77 | return *(e->pval); 78 | } 79 | 80 | sDef *SymTab::getDef(const tId& id) const { 81 | entry *e; 82 | 83 | if(!root) return 0; 84 | e=getentry(root,id); 85 | if(!e) return 0; 86 | return e->pdef; 87 | } 88 | 89 | tValue *SymTab::getRef(const tId& id,ObjType *o) const { 90 | entry *e; 91 | 92 | if(!root) return 0; 93 | e=getentry(root,id); 94 | if(!e) return 0; 95 | if(!e->pdef->isValueDef()) return 0; 96 | if(o) *o=e->pdef->object(); 97 | return e->pval; 98 | } 99 | 100 | string SymTab::recstr(entry *e,int ind) { 101 | string ostr; 102 | if (!e) return ""; 103 | if(e->pred) ostr+=recstr(e->pred,ind); 104 | IND(); 105 | ostr+=e->pdef->declstr()+";"; 106 | if(ind!=NOINDENT || e->succ) ostr+=NL(); 107 | if(e->succ) ostr+=recstr(e->succ,ind); 108 | return ostr; 109 | } 110 | 111 | string SymTab::prtstr(int ind) { 112 | string ostr; 113 | 114 | if(ind==NOINDENT) { 115 | return "{"+recstr(root,ind)+"}"; 116 | } else { 117 | return recstr(root,ind); 118 | } 119 | } 120 | 121 | int SymTabComb::put(sDef *d,const tValue& v) { 122 | return tab1->put(d,v); 123 | } 124 | 125 | tValue SymTabComb::getVal(const tId& id,ObjType *o) const { 126 | tValue v; 127 | 128 | v=tab1->getVal(id,o); 129 | if(v.isDefined()) return v; 130 | return tab2->getVal(id,o); 131 | } 132 | 133 | sDef *SymTabComb::getDef(const tId& id) const { 134 | sDef *d; 135 | 136 | d=tab1->getDef(id); 137 | if(d) return d; 138 | return tab2->getDef(id); 139 | } 140 | 141 | tValue *SymTabComb::getRef(const tId& id,ObjType *o) const { 142 | tValue *v; 143 | 144 | v=tab1->getRef(id,o); 145 | if(v) return v; 146 | return tab2->getRef(id,o); 147 | } 148 | 149 | string SymTabComb::prtstr(int ind) { 150 | string ostr; 151 | 152 | if(ind==NOINDENT) { 153 | ostr="{"; 154 | if(tab1) ostr+=tab1->prtstr(ind); 155 | ostr+=","; 156 | if(tab2) ostr+=tab2->prtstr(ind); 157 | ostr+="}"; 158 | } else { 159 | if(tab2) ostr+=tab2->prtstr(ind); 160 | if(tab1) ostr+=tab1->prtstr(ind); 161 | }; 162 | return ostr; 163 | } 164 | 165 | SymTable *glsym; // global SymTable 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /error.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | 19 | #ifdef QCL_USE_READLINE 20 | #include 21 | #include 22 | extern "C" { 23 | #include 24 | #include 25 | }; 26 | #endif 27 | 28 | #include "error.h" 29 | #include "syntax.h" 30 | #include "symbols.h" 31 | #include "quheap.h" 32 | #include "options.h" 33 | 34 | int isErrorReported=0; 35 | 36 | void initialize_readline() { 37 | #ifdef QCL_USE_READLINE 38 | // rl_bind_key ('\t', rl_insert); 39 | rl_unbind_key('\t'); 40 | #endif 41 | } 42 | 43 | const char *ERROR_STR[] = { 44 | "no error","exit","message","internal error","illegal token","parse error", 45 | "type mismatch","invalid type","parameter mismatch","invalid parameter", 46 | "unknown symbol","illegal scope","invalid definition","math error", 47 | "runtime error","general error","syntax error","user error", 48 | "range error", "external error", "I/O-error", "shell error", 49 | "memory error", "option error", "ignored", "user interrupt" 50 | }; 51 | 52 | void qclerror(string e) { 53 | cout << format->error_beg << e << format->error_end; 54 | if(optLogfile) { 55 | *optLogfile << "! " << e << '\n'; 56 | } 57 | } 58 | 59 | void qclerror(const tError& e) { 60 | if(e.where()!="") qclerror(e.where()+":"); 61 | string s=ERROR_STR[e.type()]; 62 | s+=": "+e.message(); 63 | qclerror(s); 64 | } 65 | 66 | void qclabort(string e) { 67 | if(e!="") qclerror(e); 68 | if(optLogfile) { 69 | *optLogfile << "! QCL terminated\n"; 70 | qcl_delete(optLogfile); 71 | optLogfile=0; 72 | } 73 | cout << format->output_end; 74 | exit(1); 75 | } 76 | 77 | void qclabort(const tError& e) { 78 | qclerror(e); 79 | qclabort(); 80 | } 81 | 82 | string qclinput(string p) { 83 | static string lastline=""; 84 | string prompt=format->prompt_beg+p+format->prompt_end; 85 | string t=""; 86 | irqOff(); 87 | if(optTeXmacs) { 88 | char c; 89 | cout << prompt << format->output_end << flush; 90 | while(cin.get(c) && c!='\n') t+=c; 91 | if(!cin.eof()) t+='\n'; 92 | } else { 93 | #ifdef QCL_USE_READLINE 94 | char *l; 95 | cout << format->output_end << flush; 96 | l=readline(prompt.c_str()); 97 | if(l) { 98 | t=l; t+='\n'; 99 | if(*l && t!=lastline) { 100 | add_history(l); 101 | lastline=t; 102 | } 103 | free(l); 104 | } 105 | #else 106 | char c; 107 | cout << prompt << format->output_end << flush; 108 | while(cin.get(c) && c!='\n') t+=c; 109 | if(!cin.eof()) t+='\n'; 110 | #endif 111 | } 112 | if(optIRQ) irqOn(); 113 | cout << format->output_beg; 114 | return t; 115 | } 116 | 117 | void qcloutput(string s) { 118 | cout << s << flush; 119 | } 120 | 121 | void qclprint(string s) { 122 | cout << format->print_beg << s << format->print_end << flush; 123 | } 124 | 125 | void qclmessage(string s) { 126 | cout << format->msg_beg << s << format->msg_end << flush; 127 | } 128 | 129 | void qcllog(string s) { 130 | if(optLogfile) *optLogfile << s << flush; 131 | } 132 | 133 | void qcltrace(string s,sObject *obj,SymTable *loc,SymTable *gl,QuHeap *qh) { 134 | cerr << s; 135 | if(obj) { 136 | cerr << " Object " << obj->objstr(); 137 | if(obj->def()) 138 | cerr << " (" << obj->defstr() << ")"; 139 | if(obj->isExpr()) cerr << " type " << ((sExpr*)obj)->type().str(); 140 | cerr << "\n"; 141 | } 142 | if(obj) cerr << " line: " << obj->prtstr() << "\n"; 143 | //if(gl) cerr << " global:" << gl->prtstr() << "\n"; 144 | if(loc) cerr << " local: " << loc->prtstr() << "\n"; 145 | if(qh) cerr << " quheap:" << qh->prtstr() << "\n"; 146 | } 147 | 148 | tError::tError(ErrType t,string s,sObject *o) { 149 | err=t; 150 | msg=s; 151 | obj=0; 152 | if(o) setobj(o); 153 | } 154 | 155 | void tError::setobj(sObject *o) { 156 | obj=o; 157 | loc=""; 158 | if(!o) return; 159 | if(o->inRoutDef()) { 160 | loc+="in "+o->def()->declstr()+" "; 161 | } 162 | string s=o->prtstr(); 163 | if(s.length()>40) { 164 | s.resize(25); 165 | s+=" ..."; 166 | } 167 | loc+="at \""+s+'"'; 168 | } 169 | 170 | -------------------------------------------------------------------------------- /format.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #include "format.h" 16 | 17 | #define DATA_BEGIN "\2" 18 | #define DATA_END "\5" 19 | #define DATA_ESCAPE "\033" 20 | 21 | #define XTERMCOLOR(x) "\033[0;3" #x "m" 22 | 23 | #define XTERM_BLACK XTERMCOLOR(0) 24 | #define XTERM_RED XTERMCOLOR(1) 25 | #define XTERM_GREEN XTERMCOLOR(2) 26 | #define XTERM_YELLOW XTERMCOLOR(3) 27 | #define XTERM_BLUE XTERMCOLOR(4) 28 | #define XTERM_MAGENTA XTERMCOLOR(5) 29 | #define XTERM_CYAN XTERMCOLOR(6) 30 | #define XTERM_WHITE XTERMCOLOR(7) 31 | 32 | const OutputFormat FormatPlain = { 33 | "", // output_beg 34 | "", // output_end 35 | "! ", // error_beg 36 | "\n", // error_end 37 | "! ", // msg_beg 38 | "\n", // msg_end 39 | ": ", // print_beg 40 | "\n", // print_end 41 | "", // prompt_beg 42 | "", // prompt_end 43 | "", // ps_beg 44 | "", // ps_end 45 | "", // latex_beg 46 | "", // latex_end 47 | "", // math_beg 48 | "", // math_end 49 | "", // texverb_beg 50 | "", // texverb_end 51 | "|", // ket_beg 52 | ">", // ket_end 53 | ";", // xor 54 | "i", // imag 55 | "...", // ldots 56 | " ", // mult 57 | "", // matrix_beg 58 | "", // matrix_cont 59 | "", // matrix_end 60 | "", // matrix_col 61 | "", // matrix_sep 62 | "" // matrix_nl 63 | }; 64 | 65 | const OutputFormat FormatXTerm = { 66 | XTERM_BLACK, // output_beg 67 | XTERM_BLACK, // output_end 68 | XTERM_RED "! ", // error_beg 69 | XTERM_BLACK "\n", // error_end 70 | XTERM_RED "! ", // msg_beg 71 | XTERM_BLACK "\n", // msg_end 72 | XTERM_BLUE ": ", // print_beg 73 | XTERM_BLACK "\n", // print_end 74 | "", // prompt_beg 75 | "", // prompt_end 76 | "", // ps_beg 77 | "", // ps_end 78 | "", // latex_beg 79 | "", // latex_end 80 | "", // math_beg 81 | "", // math_end 82 | "", // texverb_beg 83 | "", // texverb_end 84 | XTERM_MAGENTA "|", // ket_beg 85 | ">" XTERM_BLACK, // ket_end 86 | ";", // xor 87 | "i", // imag 88 | "...", // ldots 89 | " ", // mult 90 | "", // matrix_beg 91 | "", // matrix_cont 92 | "", // matrix_end 93 | "", // matrix_col 94 | "", // matrix_sep 95 | "" // matrix_nl 96 | }; 97 | 98 | const OutputFormat FormatDarkXTerm = { 99 | XTERM_WHITE, // output_beg 100 | XTERM_WHITE, // output_end 101 | XTERM_RED "! ", // error_beg 102 | XTERM_WHITE "\n", // error_end 103 | XTERM_RED "! ", // msg_beg 104 | XTERM_WHITE "\n", // msg_end 105 | XTERM_BLUE ": ", // print_beg 106 | XTERM_WHITE "\n", // print_end 107 | "", // prompt_beg 108 | "", // prompt_end 109 | "", // ps_beg 110 | "", // ps_end 111 | "", // latex_beg 112 | "", // latex_end 113 | "", // math_beg 114 | "", // math_end 115 | "", // texverb_beg 116 | "", // texverb_end 117 | XTERM_MAGENTA "|", // ket_beg 118 | ">" XTERM_WHITE, // ket_end 119 | ";", // xor 120 | "i", // imag 121 | "...", // ldots 122 | " ", // mult 123 | "", // matrix_beg 124 | "", // matrix_cont 125 | "", // matrix_end 126 | "", // matrix_col 127 | "", // matrix_sep 128 | "" // matrix_nl 129 | }; 130 | 131 | const OutputFormat FormatTeXmacs = { 132 | DATA_BEGIN "verbatim:", // output_beg 133 | DATA_END, // output_end 134 | DATA_BEGIN "latex:\\red\\verb~", // error_beg 135 | "~" DATA_END, // error_end 136 | DATA_BEGIN "latex:\\red\\verb~", // msg_beg 137 | "~" DATA_END, // msg_end 138 | DATA_BEGIN "latex:\\blue\\verb~", // print_beg 139 | "~" DATA_END, // print_end 140 | // prompt_beg 141 | DATA_BEGIN "channel:prompt" DATA_END DATA_BEGIN "latex:\\red\\verb~", 142 | "~" DATA_END, // prompt_end 143 | DATA_BEGIN "ps:", // ps_beg 144 | DATA_END, // ps_end 145 | DATA_BEGIN "latex:", // latex_beg 146 | DATA_END, // latex_end 147 | "$", // math_beg 148 | "$", // math_end 149 | "\\verb~", // texverb_beg 150 | "~", // texverb_end 151 | "{\\magenta|\\mathrm{", // ket_beg 152 | "}\\rangle}", // ket_end 153 | "\\oplus", // xor 154 | "i", // imag 155 | "\\ldots", // ldots 156 | "\\,", // mult 157 | "", // matrix_beg 158 | "", // matrix_cont 159 | "", // matrix_end 160 | "", // matrix_col 161 | "", // matrix_sep 162 | "" // matrix_nl 163 | }; 164 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for QCL 2 | # 3 | # This file is part of the Quantum Computation Language QCL. 4 | # 5 | # (c) Copyright by Bernhard Oemer 1998-2006 6 | # 7 | # This program comes without any warranty; without even the implied 8 | # warranty of merchantability or fitness for any particular purpose. 9 | # 10 | # This program is free software under the terms of the 11 | # GNU General Public Licence (GPL) version 2 or higher 12 | 13 | VERSION=0.6.3 14 | 15 | # Directory for Standard .qcl files 16 | 17 | QCLDIR = /scratch/ppham/local/lib/qcl 18 | 19 | # Path for qcl binaries 20 | 21 | QCLBIN = /scratch/ppham/local/bin 22 | 23 | ARCH = `g++ -dumpmachine || echo bin` 24 | 25 | # Comment out if you want to compile for a different target architecture 26 | # To build libqc.a, you will also have to edit qc/Makefile! 27 | 28 | #ARCH = i686-linux 29 | #ARCHOPT = -m32 -march=i686 30 | 31 | # Debugging and optimization options 32 | 33 | #DEBUG = -g -pg -DQCL_DEBUG -DQC_DEBUG 34 | #DEBUG = -g -DQCL_DEBUG -DQC_DEBUG 35 | DEBUG = -O2 -g -DQCL_DEBUG -DQC_DEBUG 36 | #DEBUG = -O2 37 | 38 | # Plotting support 39 | # 40 | # Comment out if you don't have GNU libplotter and X 41 | 42 | #PLOPT = -DQCL_PLOT 43 | #PLLIB = -L/usr/X11/lib -lplotter 44 | 45 | # Readline support 46 | # 47 | # Comment out if you don't have GNU readline on your system 48 | # explicit linking against libtermcap or libncurses may be required 49 | 50 | RLOPT = -DQCL_USE_READLINE 51 | #RLLIB = -lreadline 52 | RLLIB = -lreadline -lncurses 53 | 54 | # Interrupt support 55 | # 56 | # Comment out if your system doesn't support ANSI C signal handling 57 | 58 | IRQOPT = -DQCL_IRQ 59 | 60 | # Replace with lex and yacc on non-GNU systems (untested) 61 | 62 | LEX = /scratch/ppham/local/bin/flex 63 | YACC = bison 64 | INSTALL = install 65 | 66 | ##### You shouldn't have to edit the stuff below ##### 67 | 68 | DATE = `date +"%y.%m.%d-%H%M"` 69 | 70 | QCDIR = qc 71 | QCLIB = $(QCDIR)/libqc.a 72 | QCLINC = lib 73 | 74 | #CXX = g++ 75 | #CPP = $(CC) -E 76 | CXXFLAGS = -c $(ARCHOPT) -Wall $(DEBUG) $(PLOPT) $(RLOPT) $(IRQOPT) -I$(QCDIR) -DDEF_INCLUDE_PATH="\"$(QCLDIR)\"" -fpermissive 77 | LDFLAGS = $(ARCHOPT) -L/scratch/ppham/local/lib -L$(QCDIR) $(DEBUG) $(PLLIB) -lm -lfl -lqc $(RLLIB) 78 | 79 | FILESCC = $(wildcard *.cc) 80 | FILESH = $(wildcard *.h) 81 | 82 | SOURCE = $(FILESCC) $(FILESH) qcl.lex qcl.y Makefile 83 | 84 | OBJECTS = types.o syntax.o typcheck.o symbols.o error.o \ 85 | lex.o yacc.o print.o quheap.o extern.o eval.o exec.o \ 86 | parse.o options.o debug.o cond.o dump.o plot.o format.o 87 | 88 | all: do-it-all 89 | 90 | ifeq (.depend,$(wildcard .depend)) 91 | include .depend 92 | do-it-all: build 93 | else 94 | do-it-all: dep 95 | $(MAKE) 96 | endif 97 | 98 | #### Rules for depend 99 | 100 | dep: lex.cc yacc.cc yacc.h $(QCLIB) 101 | for i in *.cc; do \ 102 | $(CPP) -I$(QCDIR) -MM $$i; \ 103 | done > .depend 104 | 105 | lex.cc: qcl.lex yacc.h 106 | $(LEX) -olex.cc qcl.lex 107 | 108 | yacc.cc: qcl.y 109 | $(YACC) -t -d -o yacc.cc qcl.y 110 | 111 | yacc.h: yacc.cc 112 | mv yacc.*?h yacc.h 113 | 114 | $(QCLIB): 115 | cd $(QCDIR) && $(MAKE) libqc.a 116 | 117 | #### Rules for build 118 | 119 | build: qcl $(QCLINC)/default.qcl 120 | 121 | qcl: $(OBJECTS) qcl.o $(QCLIB) 122 | $(CXX) $(OBJECTS) qcl.o $(LDFLAGS) -o qcl 123 | 124 | $(QCLINC)/default.qcl: extern.cc 125 | grep "^//!" extern.cc | cut -c5- > $(QCLINC)/default.qcl 126 | 127 | checkinst: 128 | [ -f ./qcl -a -f $(QCLINC)/default.qcl ] || $(MAKE) build 129 | 130 | install: checkinst 131 | $(INSTALL) -m 0755 -d $(QCLBIN) $(QCLDIR) 132 | $(INSTALL) -m 0755 ./qcl $(QCLBIN) 133 | $(INSTALL) -m 0644 ./$(QCLINC)/*.qcl $(QCLDIR) 134 | 135 | uninstall: 136 | -rm -f $(QCLBIN)/qcl 137 | -rm -f $(QCLDIR)/*.qcl 138 | -rmdir $(QCLDIR) 139 | 140 | #### Other Functions 141 | 142 | edit: 143 | nedit $(SOURCE) & 144 | 145 | clean: 146 | rm -f *.o lex.* yacc.* 147 | cd $(QCDIR) && $(MAKE) clean 148 | 149 | clear: clean 150 | rm -f qcl $(QCLINC)/default.qcl .depend 151 | cd $(QCDIR) && $(MAKE) clear 152 | 153 | dist-src: dep 154 | mkdir qcl-$(VERSION) 155 | cp README CHANGES COPYING .depend $(SOURCE) qcl-$(VERSION) 156 | mkdir qcl-$(VERSION)/qc 157 | cp qc/Makefile qc/*.h qc/*.cc qcl-$(VERSION)/qc 158 | cp -r lib qcl-$(VERSION) 159 | tar czf qcl-$(VERSION).tgz --owner=0 --group=0 qcl-$(VERSION) 160 | rm -r qcl-$(VERSION) 161 | 162 | dist-bin: build 163 | mkdir qcl-$(VERSION)-$(ARCH) 164 | cp Makefile README CHANGES COPYING qcl qcl-$(VERSION)-$(ARCH) 165 | cp -r lib qcl-$(VERSION)-$(ARCH) 166 | tar czf qcl-$(VERSION)-$(ARCH).tgz --owner=0 --group=0 qcl-$(VERSION)-$(ARCH) 167 | rm -r qcl-$(VERSION)-$(ARCH) 168 | 169 | upload: dist-src 170 | scp qcl-$(VERSION)*.tgz oemer@tph.tuwien.ac.at:html/tgz 171 | 172 | scp: dist-src 173 | scp qcl-$(VERSION).tgz oemer@tph.tuwien.ac.at:bak/qcl-$(DATE).tgz 174 | -------------------------------------------------------------------------------- /qc/terms.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #ifndef _TERMS_H 16 | #define _TERMS_H 1 17 | 18 | #pragma interface 19 | 20 | #include 21 | #include 22 | 23 | using namespace std; 24 | 25 | #include "bitvec.h" 26 | 27 | typedef class complex complx; 28 | 29 | #define NONE (-1) 30 | #define EPSILON_PRINT (1E-5) 31 | 32 | DEBUG( extern int nterms; ) 33 | DEBUG( extern int ntermlists; ) 34 | DEBUG( extern int nprobtrees; ) 35 | 36 | class term { 37 | bitvec _vect; 38 | complx _ampl; 39 | public: 40 | term(); 41 | term(int n); 42 | term(const bitvec& v,const complx& z=0); 43 | term(const term& t); 44 | ~term(); 45 | term& operator = (const term& t); 46 | void set(const bitvec& v,const complx& z); 47 | void setvect(const bitvec& v); 48 | void setampl(const complx& z); 49 | inline const bitvec& vect() const; 50 | inline const complx& ampl() const; 51 | int nbits() const; 52 | }; 53 | 54 | class termlist { 55 | int _nterms; 56 | int _nbits; 57 | int listlen; 58 | int hashlen; 59 | term *list; 60 | term **hash; 61 | int hashmask; 62 | 63 | void newlist(); 64 | void dellist(); 65 | int hashfunct1(const bitvec& v) const; 66 | int hashfunct2(const bitvec& v) const; 67 | term *search(const bitvec& v) const; 68 | public: 69 | termlist(int bits,int len=256); 70 | termlist(const termlist& l); 71 | ~termlist(); 72 | termlist& operator = (const termlist& l); 73 | void add(const bitvec& v,const complx& z); 74 | 75 | void add(const term& t); 76 | void clear(); 77 | int nterms() const; 78 | int nbits() const; 79 | const term& operator [] (int i) const; 80 | complx ampl(int i) const; 81 | complx ampl(const bitvec& v) const; 82 | }; 83 | 84 | 85 | /* inline members */ 86 | 87 | // class term 88 | 89 | inline void term::setvect(const bitvec& v) { _vect=v; } 90 | 91 | inline void term::setampl(const complx& z) { _ampl=z; } 92 | 93 | inline const bitvec& term::vect() const { return _vect; } 94 | 95 | inline int term::nbits() const { return _vect.length(); } 96 | 97 | inline const complx& term::ampl() const { return _ampl; } 98 | 99 | inline term::term() { DEBUG( nterms++; ) } 100 | 101 | inline term::term(int n) { 102 | _vect.setlen(n); 103 | DEBUG( nterms++; ) 104 | } 105 | 106 | inline term::term(const bitvec& v,const complx& z) { 107 | _vect=v; 108 | _ampl=z; 109 | DEBUG( nterms++; ) 110 | } 111 | 112 | inline term::term(const term& t) { 113 | _vect=t.vect(); 114 | _ampl=t.ampl(); 115 | DEBUG( nterms++; ) 116 | } 117 | 118 | inline term::~term() { DEBUG( nterms--; ) } 119 | 120 | inline term& term::operator = (const term& t) { 121 | _vect=t.vect(); 122 | _ampl=t.ampl(); 123 | return *this; 124 | } 125 | 126 | inline void term::set(const bitvec& v,const complx& z) { 127 | _vect=v; 128 | _ampl=z; 129 | } 130 | 131 | // class termlist: private members 132 | 133 | inline void termlist::newlist() { 134 | list=new term[listlen]; 135 | hash=new term*[hashlen]; 136 | } 137 | 138 | inline void termlist::dellist() { 139 | qc_delarray(list); list=0; 140 | qc_delarray(hash); hash=0; 141 | } 142 | 143 | inline int termlist::hashfunct1(const bitvec& v) const { 144 | return v.hashfunct() & hashmask; 145 | } 146 | 147 | inline int termlist::hashfunct2(const bitvec& v) const { 148 | int f; 149 | 150 | f=v.hashfunct(); f+=(f>>3); 151 | return (f & hashmask) | 1; 152 | } 153 | 154 | inline term *termlist::search(const bitvec& v) const { 155 | int h; 156 | term *pt; 157 | 158 | h=hashfunct1(v); 159 | while(1) { 160 | pt=hash[h]; 161 | if(!pt || pt->vect()==v) return pt; 162 | h+=hashfunct2(v); 163 | }; 164 | } 165 | 166 | // class termlist: public members 167 | 168 | inline void termlist::add(const term& t) { 169 | add(t.vect(),t.ampl()); 170 | } 171 | 172 | inline void termlist::clear() { 173 | int i; 174 | 175 | _nterms=0; 176 | for(i=0;iampl() : complx(0); 198 | } 199 | 200 | /* other functions */ 201 | 202 | int duallog(int k); 203 | 204 | ostream& operator << (ostream& s,const term& t); 205 | istream& operator >> (istream& s,term& t); 206 | 207 | #endif 208 | 209 | -------------------------------------------------------------------------------- /lib/examples.qcl: -------------------------------------------------------------------------------- 1 | cond qufunct inc(qureg x) { // increment register 2 | int i; 3 | for i = #x-1 to 0 step -1 { 4 | CNot(x[i],x[0::i]); // apply controlled-not from 5 | } // MSB to LSB 6 | } 7 | qufunct cinc(qureg x,quconst e) { // increment register 8 | int i; 9 | for i = #x-1 to 0 step -1 { 10 | CNot(x[i],x[0::i] & e); // apply controlled-not from 11 | } // MSB to LSB 12 | } 13 | qufunct parity(quconst x,quvoid y) { 14 | int i; 15 | for i = 0 to #x-1 { 16 | CNot(y,x[i]); // flip parity for each set bit 17 | } 18 | } 19 | qufunct parity2(quconst x1,quconst x2,quvoid y) { 20 | quscratch j[2]; // allocate 2 scratch qubits 21 | parity(x1,j[0]); // store parity of x1 in j[0] 22 | parity(x2,j[1]); // store parity of x2 in j[1] 23 | CNot(y,j); // set y if x1 and x2 have odd 24 | } // parity 25 | operator expphase(qureg q) { 26 | if q[1] { 27 | if q[0] { 28 | Phase(pi/4); 29 | } else { 30 | Phase(pi/2); 31 | } 32 | } else { 33 | if q[0] { Phase(pi); } 34 | } 35 | } 36 | cond qufunct demux(quconst s,qureg o) { 37 | int i; 38 | int n = 0; 39 | for i=0 to #s-1 { // accumulate content of 40 | if s[i] { n=n+2^i; } // selection register 41 | } 42 | Not(o[n]); // flip selected output qubit 43 | } 44 | procedure resetregister(qureg q) { 45 | int i; 46 | int m; 47 | for i=0 to #q-1 { 48 | measure q[i],m; 49 | if m==1 { Not(q[i]); } 50 | } 51 | } 52 | qufunct operator mynot(qureg q) { 53 | SqrtNot(q); 54 | SqrtNot(q); 55 | } 56 | qufunct xreg(qureg a,int b) { // xor reg. a with binary number b 57 | int i; 58 | for i=0 to #a-1 { // iterate over qubits of a 59 | if bit(b,i) { Not(a[i]); } // invert i-th qubit of a if 60 | } // i-th bit of b is set 61 | } 62 | qufunct addto(qureg a,int b) { // add binary number b to reg. a 63 | int i; 64 | for i=0 to #a-1 { // iterate over qubits of a 65 | if bit(b,i) { // if i-th bit of b is set 66 | 67 | Not(a[i]); } // invert i-th qubit of a if 68 | } // i-th bit of b is set 69 | } 70 | qufunct rot(qureg q,int d) { 71 | int i; int j; int k; 72 | for i=0 to d*#q-d-1 { // iterate over qubits of q 73 | j=(i+d) mod #q; 74 | k=i mod #q; 75 | Swap(q[j],q[k]); 76 | } 77 | } 78 | operator ptrans(qureg q,real phi) { // Phase transformation 79 | V(phi,q[0]); // rotate LSB 80 | if #q>1 { // if there are higher qubits 81 | ptrans(q[1..#q-1],2*phi); // call ptrans with double 82 | } // phase 83 | } 84 | operator cphase(real phi,quconst q) { // Conditional phase gate 85 | qureg s[1]; // single scratch qubit 86 | CNot(s,q); 87 | RotZ(phi,s); 88 | CNot(s,q); 89 | } 90 | operator prepare(quvoid q) { 91 | H(q); 92 | ptrans(q,2*pi/2^#q); 93 | } 94 | qufunct bitcount(quconst q,quvoid p) { // count set bits in q 95 | int i; int j; 96 | if #q>=2^#p { // make sure that p is wide 97 | exit "target register too small"; // enough 98 | } 99 | for i=0 to #q-1 { // iterate over qubits in q 100 | for j=#p-1 to 0 step -1 { // increment p if q[i] 101 | CNot(p[j],p[0::j] & q[i]); // is set 102 | } 103 | } 104 | } 105 | int bc(int n) { 106 | int k=n; 107 | int b; 108 | while k>0 { 109 | b=b+(k mod 2); 110 | k=k/2; 111 | } 112 | return b; 113 | } 114 | qucond bcmp(quconst a,quconst b) { 115 | qucond c=false; 116 | int i; 117 | int j; 118 | for i=0 to 2^#a { 119 | for j=0 to 2^#b { 120 | if bc(i)==bc(j) { 121 | c=c or a==i and b==j; 122 | } 123 | } 124 | } 125 | return c; 126 | } 127 | 128 | qufunct bitcmp0(quconst a,quconst b,quvoid t,quvoid s) { 129 | bitcount(a,s); 130 | !bitcount(b,s); 131 | Not(s); 132 | CNot(t,s); 133 | } 134 | 135 | 136 | qufunct bitcmp(quconst a,quconst b,quvoid t) { 137 | quscratch s[ceil(log(max(#a,#b)+0.5,2))]; 138 | bitcmp0(a,b,t,s); 139 | } 140 | /* 141 | qufunct CNotRec(qureg q,quconst c) { 142 | quscratch 143 | cond qufunct Not(qureg q) { 144 | quvoid p=cond; 145 | qureg s[2]; 146 | int i; 147 | if #p<3 { 148 | if #p==0 { 149 | NOT(q); 150 | } else { 151 | CNOT(q,p); 152 | } 153 | } else { 154 | if q[ 155 | CNotRec(q,p); 156 | 157 | if #q>1 { 158 | for i=0 to #q { 159 | Not(q[i],p); 160 | } 161 | } 162 | */ 163 | 164 | operator pdlog(real phi,qureg q) { 165 | int i; 166 | for i=#q-1 to 0 step -1 { // iterate from MSB to LSB 167 | if q[i] { break; } // exit if qubit is set 168 | Phase(-phi); // rotate by -phi 169 | } 170 | } 171 | qufunct F(quconst x,qureg y) { 172 | // CNot(y,x); 173 | } 174 | procedure deutsch() { 175 | qureg x[1]; qureg y[1]; 176 | int m; 177 | Not(y); 178 | H(x & y); 179 | F(x,y); 180 | H(x); 181 | measure x,m; 182 | print "f(0) xor f(1) =",m; 183 | reset; 184 | } 185 | 186 | -------------------------------------------------------------------------------- /lib/modarith.qcl: -------------------------------------------------------------------------------- 1 | include "primes.qcl"; 2 | 3 | set library 1; 4 | 5 | // Conditional Xor 6 | 7 | cond qufunct cxor(quconst a,qureg b) { 8 | int i; 9 | for i=0 to #a-1 { 10 | CNot(b[i],a[i]); 11 | } 12 | } 13 | 14 | // Conditional multiplexed binary adder for one of 2 classical 15 | // bits and 1 qubit. 16 | // Full adder if #sum=2, half adder if #sum=1. 17 | 18 | cond qufunct muxaddbit(boolean a0,boolean a1,quconst sel,quconst b,qureg sum) { 19 | qureg s=sel; // redeclare sel as qureg 20 | quconst e=cond; // explicit enable register 21 | 22 | if (a0 xor a1) { // a0 and a1 differ? 23 | if a0 { Not(s); } // write a into sect qubit 24 | if #sum>1 { // set carry if available 25 | CNot(sum[1],sum[0] & s & e); 26 | } 27 | CNot(sum[0],s & e); // add a 28 | if a0 { Not(s); } // restore sect qubit 29 | } else { 30 | if a0 and a1 { 31 | if #sum>1 { // set carry if available 32 | CNot(sum[1],sum[0] & e); 33 | } 34 | CNot(sum[0],e); // add a 35 | } 36 | }; 37 | // Add qubit b 38 | if #sum>1 { // set carry if available 39 | CNot(sum[1],b & sum[0]); 40 | } 41 | CNot(sum[0],b); // add b 42 | } 43 | 44 | // conditional multiplexed binary adder for one of 2 integers 45 | // and 1 qureg. No output carry. 46 | 47 | cond qufunct muxadd(int a0,int a1,quconst sel,quconst b,quvoid sum) { 48 | int i; 49 | for i=0 to #b-2 { // fulladd first #b-1 bits 50 | muxaddbit(bit(a0,i),bit(a1,i),sel,b[i],sum[i:i+1]); 51 | } 52 | // half add last bit 53 | muxaddbit(bit(a0,#b-1),bit(a1,#b-1),sel,b[#b-1],sum[#b-1]); 54 | } 55 | 56 | // Comparison operator. flag is toggled if bMSB(b) 65 | CNot(flag,b[#b-1]); 66 | } else { 67 | Not(b[#b-1]); // disable further comparison 68 | CNot(j[#b-2],b[#b-1]); // if MSB(a)b[i] 75 | } else { 76 | Not(b[i]); 77 | CNot(j[i-1],j[i] & b[i]); 78 | } 79 | } 80 | if bit(a,0) { 81 | Not(b[0]); // if still undecided (j[0]=1) 82 | CNot(flag,j[0] & b[0]); // result is LSB(a)>LSB(b) 83 | } 84 | } 85 | 86 | // conditional addition mod n for 1 integer and 1 qureg 87 | // flag is set if a+b (a+sum) mod n 104 | 105 | cond qufunct oaddn(int a,int n,qureg sum) { 106 | qureg j[#sum]; 107 | qureg f[1]; 108 | quconst e=cond; // explicit enable register 109 | 110 | if e { addn(a,n,sum,f,j); } // junk -> a+b mod n 111 | Swap(sum,j); // swap junk and sum 112 | CNot(f,e); // toggle flag 113 | if e { !addn(n-a,n,sum,f,j); } // uncompute b to zero 114 | } 115 | 116 | // Conditional Multiplication mod n of an integer a by the qureg b, 117 | // prod <- ab mod n. 118 | 119 | cond qufunct muln(int a,int n,quconst b,qureg prod) { 120 | int i; 121 | 122 | for i=0 to #prod-1 { 123 | if bit(a,i) and b[0] { Not(prod[i]); } 124 | } 125 | for i=1 to #b-1 { 126 | if b[i] { oaddn(2^i*a mod n,n,prod); } 127 | } 128 | } 129 | 130 | // Conditional Overwriting multiplication mod n: b-> ab mod n 131 | 132 | cond qufunct omuln(int a,int n,qureg b) { 133 | qureg j[#b]; 134 | 135 | if gcd(a,n)>1 { 136 | exit "omuln: a and n have to be relativly prime"; 137 | } 138 | muln(a,n,b,j); 139 | !muln(invmod(a,n),n,j,b); 140 | cxor(j,b); 141 | cxor(b,j); 142 | } 143 | 144 | // Modular exponentiation: b -> x^a mod n 145 | 146 | cond qufunct expn(int a,int n,quconst b,quvoid ex) { 147 | int i; 148 | 149 | Not(ex[0]); // start with 1 150 | for i=0 to #b-1 { 151 | if b[i] { 152 | omuln(powmod(a,2^i,n),n,ex); // ex -> ex*a^2^i mod n 153 | } 154 | } 155 | } 156 | 157 | set library 0; 158 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | QCL version 0.6.1 by Bernhard Oemer 3 | ============================================================ 4 | 5 | 6 | Despite many common concepts with classical computer science, quantum 7 | computing is still widely considered as a special discipline within the 8 | broad field of theoretical physics. One reason for the slow adoption of 9 | QC by the computer science community is the confusing variety of 10 | formalisms (Dirac notation, matrices, gates, operators, etc.), none of 11 | which has any similarity with classical programming languages, as well 12 | as the rather ``physical'' terminology in most of the available 13 | literature. 14 | 15 | QCL (Quantum Computation Language) tries to fill this gap: QCL is a 16 | hight level, architecture independent programming language for quantum 17 | computers, with a syntax derived from classical procedural languages 18 | like C or Pascal. This allows for the complete implementation and 19 | simulation of quantum algorithms (including classical components) in one 20 | consistent formalism. 21 | 22 | 23 | Features: 24 | --------- 25 | 26 | - a classical control language with functions, flow-control, 27 | interactive i/o and various classical data types (int, real, 28 | complex, boolean, string) 29 | 30 | - 2 quantum operator types: general unitarian (operator) and 31 | reversible pseudo-classic gates (qufunct) 32 | 33 | - inverse execution, allowing for on-the-fly determination of the 34 | inverse operator though caching of operator calls 35 | 36 | - various quantum data types (qubit registers) for compile time 37 | information on access modes (qureg, quconst, quvoid, quscratch) 38 | 39 | - convenient functions to manipulate quantum registers (q[n] - 40 | qubit, q[n:m] - substring, q&p - combined register) 41 | 42 | - Quantum memory management (quheap) allowing for local quantum 43 | variables 44 | 45 | - Transparent integration of Bennet-style scratch space management 46 | 47 | - Easy adaption to individual sets of elementary operators 48 | 49 | - graphical output for (X11 and Postscript) (v0.5) 50 | 51 | - conditional operators and quantum if-statements (v0.5, experimental) 52 | 53 | 54 | Availability: 55 | ------------- 56 | 57 | QCL has been developed under Linux; version 0.5.1 is tested to compile 58 | with the GNU C++ compiler 2.95.3 under SuSE 7.3. It should - however - 59 | compile under any Unix system with minor modifications (see the Makefile 60 | for details). 61 | 62 | The current version of QCL (sources and i386 Linux binaries) is available from 63 | my homepage: 64 | 65 | http://tph.tuwien.ac.at/~oemer/qcl/ 66 | 67 | 68 | Documentation: 69 | -------------- 70 | 71 | The reference documentation for QCL is my master thesis in technical 72 | physics "A Procedural Formalism for Quantum Computing". It gives a 73 | complete reference to QCL with many examples and also features a brief 74 | introduction into Quantum Computing. Some knowledge about Quantum 75 | Physics and familiarity with the braket-formalism is required. 76 | 77 | A more basic introduction esp. for computing scientists to quantum 78 | computing, quantum algorithms and QCL is included in my CS master thesis 79 | "Quantum Programming in QCL" which also features an introductory chapter 80 | to quantum physics in general. 81 | 82 | Both documents are available online in Postscript or HTML format: 83 | 84 | http://tph.tuwien.ac.at/~oemer/qcl.html#doc 85 | 86 | 87 | Installation: 88 | ------------- 89 | 90 | Besides the usual C++ development tools, you will need to have flex, 91 | bison and (optionally) GNU readline installed on your system. 92 | 93 | Untar the source package, then cd to the QCL directory, edit the Makefile 94 | for your needs and type 95 | 96 | make 97 | make install 98 | 99 | This will, by default, install the binary qcl to /usr/local/bin and the QCL 100 | include files to /usr/local/lib/qcl. 101 | 102 | For plotting support, libplotter (the C++ bindings of of GNU libplot) is 103 | required. GNU libplot is part of the the GNU plotutils; see 104 | 105 | http://www.gnu.org/software/plotutils/ 106 | 107 | Since version 0.4.3, QCL also includes support for the TeXmacs mathematical 108 | text editor. Recent TeXmacs distributions (1.0.0.6 or newer) already provide 109 | the necessary interfaces, so no additional installation is required. You can 110 | get the latest TeXmacs sources from 111 | 112 | http://www.texmacs.org/ 113 | 114 | 115 | Credits: 116 | -------- 117 | 118 | Andrey G. Grozin 119 | - initial TeXmacs support 120 | - color XTerm support 121 | 122 | Muhammad Hussain Yusuf 123 | - maintainer of the debian QCL package 124 | - testing of QCL on many hardware plattforms 125 | 126 | 127 | Feedback: 128 | --------- 129 | 130 | If you encounter any bugs or miss any particular feature or just like 131 | QCL, please let me know. My email address is 132 | 133 | Bernhard Oemer 134 | 135 | The QCL interpreter is Open Source(tm) software, so please feel free to write 136 | your own ports and extentions. If you send me patches, I will most probably 137 | include them in future versions of QCL and maintain them to the best of my 138 | abilities. ;-) Since English isn't my native language, I also appreciate 139 | any orthographic and grammatical corrections. 140 | 141 | 142 | 143 | Bernhard Oemer 144 | 145 | -------------------------------------------------------------------------------- /dump.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include "dump.h" 19 | #include "quheap.h" 20 | #include "options.h" 21 | #include "error.h" 22 | 23 | /* 24 | 25 | bitvec trimvect(const bitvec& v) {} 26 | string vect2bin(const bitvec& v) {} 27 | string vect2dec(const bitvec& v) {} 28 | 29 | 30 | string vect2hex(const bitvec& v) { 31 | string s="0x"; 32 | int i,c; 33 | for(i=((v.length()-1) & ~3);i>=0;i-=4) { 34 | c=v.getword(i,(i+4<=v.length()) ? 4 : (v.length()-i)); 35 | if(c<=9) s+=(char)('0'+c); else s+=(char)('a'+c-10); 36 | } 37 | return format->ket_beg+string(s)+format->ket_end; 38 | } 39 | 40 | */ 41 | 42 | string regstr(const bitvec& v,int width=0) { 43 | int i,c,z=0; 44 | char s[v.length()+3]; 45 | char *p=s; 46 | 47 | if((optDumpFormat=='a'||optDumpFormat=='d') && v.length()>BPW || optDumpFormat=='x') { 48 | *(p++)='0'; *(p++)='x'; 49 | for(i=((v.length()-1) & ~3);i>=0;i-=4) { 50 | c=v.getword(i,(i+4<=v.length()) ? 4 : (v.length()-i)); 51 | z|=c; 52 | if(width && !z && i>=width) continue; 53 | if(c<=9) *(p++)=(char)('0'+c); else *(p++)=(char)('a'+c-10); 54 | } 55 | *(p++)=0; 56 | } else if(optDumpFormat=='d') { 57 | sprintf(s,"%lu",v.getword()); 58 | } else { 59 | for(i=v.length()-1;i>=0;i--) { 60 | z|=v[i]; 61 | if(width && !z && i>=width) continue; 62 | *(p++)=(v[i] ? '1' : '0'); 63 | } 64 | *(p++)=0; 65 | } 66 | return string(s); 67 | } 68 | 69 | string vectstr(const bitvec& v,int width=0,const QuHeap *qh=0) { 70 | if(optShowRegs && qh && qh->Regs()) { 71 | int i; 72 | bitvec m=bitvec(v.length()); 73 | string s=format->ket_beg; 74 | for(i=0;iRegs();i++) { 75 | const quState *q=qh->Reg(i); 76 | s+=regstr(q->map(v),0); 77 | m|=q->mapmask(); 78 | if(i+1Regs()) s+=','; 79 | } 80 | if(!zero(~m&v)) { 81 | quMask qm(*(qh->state()),~m); 82 | s+=';'; 83 | s+=regstr(qm.map(v),0); 84 | } 85 | s+=format->ket_end; 86 | return s; 87 | } else { 88 | return format->ket_beg+regstr(v,width)+format->ket_end; 89 | } 90 | } 91 | 92 | string probstr(tReal r) { 93 | char s[2*optDumpPrecision+80]; 94 | sprintf(s,"%.*g",optDumpPrecision,r); 95 | return s; 96 | } 97 | 98 | string amplstr(const tComplex &z,int cont=0) { 99 | const char *sg = ""; 100 | tReal r=z.real(); 101 | tReal i=z.imag(); 102 | int p=optDumpPrecision; 103 | char s[2*optDumpPrecision+80]; 104 | if(abs(r)imag); 115 | return s; 116 | } 117 | if(cont) sg=" + "; 118 | if(cont && r<0) { r=-r; sg=" - "; } 119 | if(cont && i<0) { i=-i; sg=" - "; } 120 | if(i==1 && r==0) { 121 | sprintf(s,"%s%s",sg,format->imag); 122 | } else if(i==-1 && r==0) { 123 | sprintf(s,"%s-%s",sg,format->imag); 124 | } else if(i!=0) { 125 | sprintf(s,"%s%.*g%s",sg,p,i,format->imag); 126 | } else { 127 | sprintf(s,"%s%.*g",sg,p,r); 128 | } 129 | return s; 130 | } 131 | 132 | string termstr(const tComplex &z,const bitvec& v,int cont=0,int width=0,const QuHeap *qh=0) { 133 | return amplstr(z,cont)+format->mult+vectstr(v,width,qh); 134 | } 135 | 136 | int report_state(QuHeap *qh) { 137 | int width= optTrucStates ? MAX(qh->nBits()-qh->nFree(),1) : 0; 138 | state_map *pm=qh->state()->new_state_map(optDumpEpsilon); 139 | state_iter i; 140 | 141 | cout << format->latex_beg; 142 | 143 | cout << "[" << qh->nBits()-qh->nFree() << "/" << qh->nBits() << "] "; 144 | if(optAutoDump && (int)pm->size()<=optAutoDump) { 145 | cout << format->math_beg; 146 | for(i=pm->begin();i!=pm->end();i++) 147 | cout << termstr((*i).second,(*i).first,i!=pm->begin(),width,qh); 148 | cout << format->math_end; 149 | } else if(pm->size()>4) { 150 | cout << format->math_beg; 151 | i=pm->begin(); 152 | cout << termstr((*i).second,(*i).first,0,width,qh); 153 | // i++; 154 | // cout << termstr((*i).second,(*i).first,1,width,qh); 155 | if(optTeXmacs) 156 | cout << " + \\ldots"; 157 | else 158 | cout << " + ..."; 159 | cout << termstr((*(pm->rbegin())).second,(*(pm->rbegin())).first,1,width,qh); 160 | cout << format->math_end; 161 | cout << " (" << pm->size() << " terms)"; 162 | } else { 163 | cout << " " << pm->size() << " terms"; 164 | } 165 | cout << "\n"; 166 | delete pm; 167 | cout << format->latex_end; 168 | return 0; 169 | } 170 | 171 | int dump_state(QuHeap *qh,ostream *o) { 172 | int width= optTrucStates ? MAX(qh->nBits()-qh->nFree(),1) : 0; 173 | state_iter i; 174 | ostream *f= o ? o : &cout; 175 | const OutputFormat *oldformat=format; 176 | 177 | if(o) format=&FormatPlain; 178 | (*f) << format->latex_beg; 179 | (*f) << format->math_beg; 180 | state_map *pm=qh->state()->new_state_map(optDumpEpsilon); 181 | for(i=pm->begin();i!=pm->end();i++) 182 | (*f) << termstr((*i).second,(*i).first,i!=pm->begin(),width); 183 | delete pm; 184 | (*f) << format->math_end; 185 | (*f) << "\n"; 186 | (*f) << format->latex_end; 187 | format=oldformat; 188 | return 0; 189 | } 190 | 191 | int dump_spectrum(quState *qs,ostream *o) { 192 | spectrum_iter i; 193 | ostream *f= o ? o : &cout; 194 | const OutputFormat *oldformat=format; 195 | 196 | if(o) format=&FormatPlain; 197 | (*f) << format->latex_beg; 198 | (*f) << format->math_beg; 199 | spectrum_map *pm=qs->new_spectrum_map(optDumpEpsilon); 200 | for(i=pm->begin();i!=pm->end();i++) { 201 | if(i!=pm->begin()) (*f) << ", "; 202 | (*f) << probstr((*i).second); 203 | (*f) << format->mult; 204 | (*f) << vectstr((*i).first); 205 | } 206 | delete pm; 207 | (*f) << format->math_end; 208 | (*f) << "\n"; 209 | (*f) << format->latex_end; 210 | format=oldformat; 211 | return 0; 212 | } 213 | 214 | -------------------------------------------------------------------------------- /plot.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include "plot.h" 19 | #include "error.h" 20 | #include "quheap.h" 21 | #include "options.h" 22 | 23 | #ifdef QCL_PLOT 24 | 25 | #include 26 | 27 | #define MARK_REAL 16 // filled circle 28 | #define MARK_IMAG 5 // cross 29 | 30 | ostream *plotfile; 31 | Plotter *plotter; 32 | 33 | inline long pow(int a,int b) { return (long)pow((double)a,b); } 34 | 35 | double vec2double(bitvec v) { 36 | if(v.length()<=BPW) 37 | return v.getword(); 38 | else 39 | return v.getword(v.length()-BPW,BPW)*pow(2,v.length()-BPW); 40 | } 41 | 42 | void open_plot() { 43 | plotfile=0; 44 | Plotter::parampl("PAGESIZE",(void*)optPlotPaper.c_str()); 45 | Plotter::parampl("BITMAPSIZE",(void*)"600x600"); 46 | if(optPlotFilename!="") { 47 | plotfile=new ofstream(optPlotFilename.c_str(),ios::out); 48 | if(!plotfile || !*plotfile) { 49 | if(plotfile) delete plotfile; 50 | throw tError(errIO,"cannot open plot-file "+optDumpFilename); 51 | } 52 | plotter=new PSPlotter(cin,*plotfile,cerr); 53 | } else if(optTeXmacs) { 54 | plotter=new PSPlotter(cin,cout,cerr); 55 | cout << format->ps_beg; 56 | } else { 57 | plotter=new XPlotter(cin,cout,cerr); 58 | } 59 | if(!plotter || plotter->openpl()<0) { 60 | if(plotter) delete plotter; 61 | if(plotfile) delete plotfile; 62 | throw tError(errINT,"cannot open plotter object"); 63 | } 64 | if(optPlotFilename=="" && optTeXmacs) 65 | plotter->fspace(-0.28,-0.58,1.28,1.58); 66 | else 67 | plotter->fspace(-0.08,-0.08,1.08,1.08); 68 | plotter->ffontsize(0.04); 69 | } 70 | 71 | void close_plot() { 72 | int r=-1; 73 | if(plotter) { 74 | r=plotter->closepl(); 75 | delete plotter; 76 | } 77 | if(plotfile) delete plotfile; 78 | if(optTeXmacs && optPlotFilename=="") cout << format->ps_end; 79 | if(r<0) throw tError(errINT,"cannot close plotter object"); 80 | } 81 | 82 | void plot_state(QuHeap *qh) { 83 | qclprint("PLOT STATE"); 84 | open_plot(); 85 | char buf[80]; 86 | int used=qh->nBits()-qh->nFree(); 87 | tComplex z; 88 | bitvec v; 89 | state_iter i; 90 | double x; 91 | double maxx = pow(2,MAX(used,1))-1; 92 | double maxy = 1/sqrt(maxx+1); 93 | double msize = 0.75/(maxx+1); 94 | 95 | if(msize<0.012) msize=0.012; 96 | if(msize>0.05) msize=0.05; 97 | 98 | state_map *pm=qh->state()->new_state_map(); 99 | for(i=pm->begin();i!=pm->end();i++) { 100 | x=vec2double((*i).first); 101 | if(x>maxx) maxx=x; 102 | z=(*i).second; 103 | if(abs(z.real())>maxy) maxy=abs(z.real()); 104 | if(abs(z.imag())>maxy) maxy=abs(z.imag()); 105 | } 106 | 107 | if(maxx>pow(2,used)) 108 | sprintf(buf,"basevectors |0> ... |%.0f>",maxx); 109 | else 110 | sprintf(buf,"%d used qubit%s, %d basevector%s", 111 | used,used==1?"":"s",(int)pow(2,used),used==0?"":"s"); 112 | plotter->fmove(0.5,-0.04); 113 | plotter->alabel('c','c',buf); 114 | 115 | plotter->color(0x4000,0x4000,0x4000); 116 | plotter->flinewidth(0.003); 117 | 118 | plotter->fmove(0,0.5); 119 | plotter->fcont(1,0.5); 120 | 121 | plotter->color(0,0,0); 122 | plotter->flinewidth(0.001); 123 | 124 | for(i=pm->begin();i!=pm->end();i++) { 125 | x=vec2double((*i).first)/maxx; 126 | z=(*i).second; 127 | plotter->fmove(x,0.5+abs(z)/(2*maxy)); 128 | plotter->fcont(x,0.5-abs(z)/(2*maxy)); 129 | plotter->fmarker(x,0.5+z.real()/(2*maxy),MARK_REAL,msize); 130 | plotter->fmarker(x,0.5+z.imag()/(2*maxy),MARK_IMAG,1.2*msize); 131 | } 132 | delete pm; 133 | close_plot(); 134 | } 135 | 136 | void plot_spectrum(quState *q,string lab) { 137 | qclprint("PLOT SPECTRUM "+lab); 138 | open_plot(); 139 | bitvec v; 140 | spectrum_iter i; 141 | double x,y; 142 | double maxx = pow(2,q->mapbits())-1; 143 | double maxy = 1/(maxx+1); 144 | spectrum_map *pm=q->new_spectrum_map(); 145 | for(i=pm->begin();i!=pm->end();i++) { 146 | y=(*i).second; 147 | if(y>maxy) maxy=y; 148 | } 149 | 150 | plotter->fmove(0.5,-0.04); 151 | plotter->alabel('c','c',lab.c_str()); 152 | 153 | plotter->color(0x4000,0x4000,0x4000); 154 | plotter->flinewidth(0.003); 155 | 156 | plotter->fmove(0,0); 157 | plotter->fcont(1,0); 158 | 159 | plotter->color(0,0,0); 160 | plotter->flinewidth(0.001); 161 | 162 | for(i=pm->begin();i!=pm->end();i++) { 163 | x=vec2double((*i).first)/maxx; 164 | y=(*i).second; 165 | plotter->fmove(x,0.0); 166 | plotter->fcont(x,y/maxy); 167 | plotter->fmarker(x,y/maxy,MARK_REAL,0.012); 168 | } 169 | delete pm; 170 | close_plot(); 171 | } 172 | 173 | void plot_spectrum2(quState *qx,quState *qy,string labx,string laby) { 174 | qclprint("PLOT XY-SPECTRUM "+labx+" / "+laby); 175 | open_plot(); 176 | 177 | bitvec v,vx,vy; 178 | spectrum_iter i; 179 | double x,y,z; 180 | int nx=qx->mapbits(); 181 | int ny=qy->mapbits(); 182 | double maxx = pow(2,nx); 183 | double maxy = pow(2,ny); 184 | double maxz = 1/(maxx*maxy); 185 | double dx=1/maxx; 186 | double dy=1/maxy; 187 | quCombState q(qx,qy); 188 | 189 | spectrum_map *pm=q.new_spectrum_map(); 190 | for(i=pm->begin();i!=pm->end();i++) { 191 | z=(*i).second; 192 | if(z>maxz) maxz=z; 193 | } 194 | maxz*=1.2; 195 | 196 | plotter->fmove(0.5,-0.04); 197 | plotter->alabel('c','c',labx.c_str()); 198 | plotter->textangle(90); 199 | plotter->fmove(-0.04,0.5); 200 | plotter->alabel('c','c',laby.c_str()); 201 | plotter->textangle(0); 202 | 203 | plotter->color(0x4000,0x4000,0x4000); 204 | plotter->flinewidth(0.003); 205 | 206 | plotter->fmove(-0.01,1); 207 | plotter->fcont(-0.01,-0.01); 208 | plotter->fcont(1,-0.01); 209 | 210 | plotter->color(0,0,0); 211 | plotter->flinewidth(0.001); 212 | plotter->filltype(0x8000); 213 | 214 | for(i=pm->begin();i!=pm->end();i++) { 215 | v=(*i).first; 216 | x=vec2double(v.getbits(0,nx))/maxx+dx/2; 217 | y=vec2double(v.getbits(nx,ny))/maxy+dy/2; 218 | z=sqrt((*i).second/maxz)/2; 219 | plotter->fellipse(x,y,z*dx,z*dy,0); 220 | // plotter->fbox(x-z*dx,y-z*dy,x+z*dx,y+z*dy); 221 | } 222 | delete pm; 223 | close_plot(); 224 | } 225 | 226 | #else 227 | 228 | void plot_state(QuHeap *qh) { 229 | qclmessage("this QCL binary doesn't contain plotting support."); 230 | } 231 | 232 | void plot_spectrum(quState *q,string lab) { 233 | qclmessage("this QCL binary doesn't contain plotting support."); 234 | } 235 | 236 | void plot_spectrum2(quState *qx,quState *qy,string labx,string laby) { 237 | qclmessage("this QCL binary doesn't contain plotting support."); 238 | } 239 | 240 | #endif 241 | -------------------------------------------------------------------------------- /lib/default.qcl: -------------------------------------------------------------------------------- 1 | 2 | /* generic matrix operator: |i> -> sum_j u[i,j] |j> */ 3 | 4 | extern operator Matrix(complex matrix u,qureg q); 5 | 6 | /* obsolete matrix operators */ 7 | 8 | extern operator Matrix2x2( 9 | complex u00,complex u01, 10 | complex u10,complex u11, 11 | qureg q); 12 | 13 | extern operator Matrix4x4( 14 | complex u00,complex u01,complex u02,complex u03, 15 | complex u10,complex u11,complex u12,complex u13, 16 | complex u20,complex u21,complex u22,complex u23, 17 | complex u30,complex u31,complex u32,complex u33, 18 | qureg q); 19 | 20 | extern operator Matrix8x8( 21 | complex u00,complex u01,complex u02,complex u03, 22 | complex u04,complex u05,complex u06,complex u07, 23 | complex u10,complex u11,complex u12,complex u13, 24 | complex u14,complex u15,complex u16,complex u17, 25 | complex u20,complex u21,complex u22,complex u23, 26 | complex u24,complex u25,complex u26,complex u27, 27 | complex u30,complex u31,complex u32,complex u33, 28 | complex u34,complex u35,complex u36,complex u37, 29 | complex u40,complex u41,complex u42,complex u43, 30 | complex u44,complex u45,complex u46,complex u47, 31 | complex u50,complex u51,complex u52,complex u53, 32 | complex u54,complex u55,complex u56,complex u57, 33 | complex u60,complex u61,complex u62,complex u63, 34 | complex u64,complex u65,complex u66,complex u67, 35 | complex u70,complex u71,complex u72,complex u73, 36 | complex u74,complex u75,complex u76,complex u77, 37 | qureg q); 38 | 39 | /* generic permutation operator: |i> -> |p[i]> */ 40 | 41 | extern qufunct Perm(int vector p,qureg q); 42 | 43 | /* obsolete permutation operators */ 44 | 45 | extern qufunct Perm2(int p0 ,int p1 ,qureg q); 46 | 47 | extern qufunct Perm4(int p0 ,int p1 ,int p2 ,int p3 ,qureg q); 48 | 49 | extern qufunct Perm8( 50 | int p0 ,int p1 ,int p2 ,int p3 ,int p4 ,int p5 ,int p6 ,int p7 , 51 | qureg q); 52 | 53 | extern qufunct Perm16( 54 | int p0 ,int p1 ,int p2 ,int p3 ,int p4 ,int p5 ,int p6 ,int p7 , 55 | int p8 ,int p9 ,int p10,int p11,int p12,int p13,int p14,int p15, 56 | qureg q); 57 | 58 | extern qufunct Perm32( 59 | int p0 ,int p1 ,int p2 ,int p3 ,int p4 ,int p5 ,int p6 ,int p7 , 60 | int p8 ,int p9 ,int p10,int p11,int p12,int p13,int p14,int p15, 61 | int p16,int p17,int p18,int p19,int p20,int p21,int p22,int p23, 62 | int p24,int p25,int p26,int p27,int p28,int p29,int p30,int p31, 63 | qureg q); 64 | 65 | extern qufunct Perm64( 66 | int p0 ,int p1 ,int p2 ,int p3 ,int p4 ,int p5 ,int p6 ,int p7 , 67 | int p8 ,int p9 ,int p10,int p11,int p12,int p13,int p14,int p15, 68 | int p16,int p17,int p18,int p19,int p20,int p21,int p22,int p23, 69 | int p24,int p25,int p26,int p27,int p28,int p29,int p30,int p31, 70 | int p32,int p33,int p34,int p35,int p36,int p37,int p38,int p39, 71 | int p40,int p41,int p42,int p43,int p44,int p45,int p46,int p47, 72 | int p48,int p49,int p50,int p51,int p52,int p53,int p54,int p55, 73 | int p56,int p57,int p58,int p59,int p60,int p61,int p62,int p63, 74 | qureg q); 75 | 76 | /* standard unconditional single-qubit gates */ 77 | 78 | extern operator H(qureg q); 79 | extern qufunct NOT(qureg q); 80 | extern qufunct X(qureg q); 81 | extern operator Y(qureg q); 82 | extern operator Z(quconst q); 83 | extern operator S(quconst q); 84 | extern operator T(quconst q); 85 | 86 | operator Pauli(int i,qureg q) { // Pauli Matrices 87 | if i==1 { X(q); } 88 | if i==2 { Y(q); } 89 | if i==3 { Z(q); } 90 | if i<0 or i>3 { exit "Unknown Pauli Gate"; } 91 | } 92 | 93 | /* The Mix-operator can be any operator which transforms */ 94 | /* the state |0> into an even superposition of all base- */ 95 | /* vector with phase 0, i.e. |0> -> 1/sqrt(N) sum |i> */ 96 | 97 | operator Mix(qureg q) { // Generic Mix-Operator 98 | H(q); // using the Hadamard 99 | } // transform 100 | 101 | /* unconditional controlled-not gate */ 102 | 103 | extern qufunct CNOT(qureg q,quconst c); 104 | 105 | /* The conditional versions of Not and CNot can either */ 106 | /* use the built-in conditional Not-gate or the generic */ 107 | /* unconditional NOT and CNOT gates */ 108 | 109 | // extern cond qufunct Not(qureg q); // conditional Not 110 | cond qufunct Not(qureg q) { // generic NOT/CNOT 111 | quconst e = cond; 112 | if #e>0 { CNOT(q,e); } else { NOT(q); } 113 | } 114 | 115 | cond qufunct CNot(qureg q,quconst c) { 116 | quconst e = cond; 117 | // if c and e { Not(q); }; // conditional Not 118 | CNOT(q,c & e); // generic CNOT 119 | }; 120 | 121 | /* unconditional V-gate (controlled phase rotation) */ 122 | 123 | extern operator V(real phi,quconst q); 124 | 125 | /* The conditional versions of Phase and CPhase can */ 126 | /* either use the built-in conditional Phase-gate or */ 127 | /* or the unconditional V-gate */ 128 | 129 | // extern cond operator Phase(real phi); // conditional Phase 130 | cond operator Phase(real phi) { // V-gate 131 | quconst c = cond; 132 | if #c>0 { V(phi,c); } 133 | } 134 | 135 | cond operator CPhase(real phi,quconst q) { 136 | quconst e = cond; 137 | // if q and e { Phase(phi); } // conditional Phase 138 | V(phi,q & e); // V-gate 139 | } 140 | 141 | /* obsolete single qubit rotation (period 4*pi) */ 142 | 143 | extern operator Rot(real theta,qureg q); 144 | 145 | /* Square root of Not */ 146 | 147 | extern operator SqrtNot(qureg q); 148 | 149 | /* Single qubit rotation about X-axis */ 150 | 151 | extern operator RotX(real theta,qureg q); 152 | 153 | /* Single qubit rotation about Y-axis */ 154 | 155 | extern operator RotY(real theta,qureg q); 156 | 157 | /* Single qubit rotation about Z-axis */ 158 | 159 | extern operator RotZ(real theta,qureg q); 160 | 161 | extern qufunct ModExp(int n,int x,quconst a,quvoid b); 162 | 163 | /* The Fanout operator is used internally for scratch */ 164 | /* space management. If you provide your own version, */ 165 | /* make sure it doesn't use local quscratch registers. */ 166 | 167 | /* generic Fanout operator */ 168 | 169 | extern cond qufunct Fanout(quconst a,quvoid b); 170 | 171 | /* alternative implementation; comment out if you want */ 172 | /* an explicit decomposition using CNot gates */ 173 | /* 174 | cond qufunct Fanout(quconst a,quvoid b) { 175 | int i; 176 | if #a!=#b { exit "fanout arguments must be of equal size"; } 177 | for i=0 to #a-1 { CNot(b[i],a[i]); } 178 | } 179 | */ 180 | 181 | 182 | /* generic Swap operator */ 183 | 184 | extern cond qufunct Swap(qureg a,qureg b); 185 | 186 | /* alternative implementation; comment out if you want */ 187 | /* an explicit decomposition using CNot gates */ 188 | /* 189 | cond qufunct Swap(qureg a,qureg b) { 190 | int i; 191 | if #a!=#b { exit "swap arguments must be of equal size"; } 192 | for i=0 to #a-1 { 193 | CNot(b[i],a[i]); 194 | CNot(a[i],b[i]); 195 | CNot(b[i],a[i]); 196 | } 197 | } 198 | */ 199 | 200 | /* Mathematical constants */ 201 | 202 | const pi = 3.141592653589793238462643383279502884197; 203 | const E = 2.718281828459045235360287471352662497757; 204 | const I = (0,1); 205 | 206 | /* Auxillary functions */ 207 | 208 | qufunct set(int n,qureg q) { 209 | int i; 210 | for i=0 to #q-1 { 211 | if bit(n,i) { Not(q[i]); } 212 | } 213 | } 214 | 215 | /* Randomize register (apply random single qubit rotations) */ 216 | 217 | procedure randomize(qureg q) { 218 | int i; 219 | for i=0 to #q-1 { 220 | RotZ(4*pi*random(),q[i]); 221 | RotY(4*pi*random(),q[i]); 222 | RotZ(4*pi*random(),q[i]); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /qc/bitvec.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #pragma implementation "bitvec.h" 16 | 17 | #include "bitvec.h" 18 | 19 | using namespace std; 20 | 21 | DEBUG( int nbitvecs=0; ) 22 | 23 | char* qc_check_txt = "QCLIB: qc_check failed on condition "; 24 | char* qc_check_stdmsg = 25 | "Can't continue. Provoking segfault to simplify backtracking.\n"; 26 | char* qc_check_msg = qc_check_stdmsg; 27 | 28 | char* qc_delete_txt = "QCLIB: qc_delete warning"; 29 | char* qc_delarray_txt = "QCLIB: qc_delarray warning"; 30 | char* qc_del_msg = 31 | "This should not happen (out of memory?). If the warning is reproducable,\n" 32 | "please send a bugreport to Bernhard Oemer .\n"; 33 | 34 | /* private members */ 35 | 36 | void bitvec::l_bitvec(word v) { 37 | int i,l; 38 | 39 | l=WORDS(len); 40 | pvec=new word[l]; 41 | pvec[0]=v; 42 | for(i=1;i>LDBPW);k++) v.pvec[k]=l_getword(i+(k<>LDBPW; 67 | v.pvec[k]=l_getword(i+(k<>LDBPW; 78 | w=(pvec[k]>>j)&MASK(l); 79 | if(l+j>BPW) w|=(pvec[k+1]<<(BPW-j))&MASK(l); 80 | return w; 81 | } 82 | 83 | void bitvec::l_setbits(int i,int l,word v) { 84 | int j,k; 85 | 86 | j=i&DBITS; 87 | k=i>>LDBPW; 88 | pvec[k]&=~(MASK(l)<>(BPW-j); 93 | } 94 | 95 | void bitvec::l_setbits(int i,const bitvec& v) { 96 | int k; 97 | 98 | for(k=0;k<(v.len>>LDBPW);k++) l_setbits(i+(k<>LDBPW; 101 | l_setbits(i+(k<>LDBPW;k>=0;k--) { 113 | if(pvec[k]v.pvec[k]) return 0; 115 | }; 116 | return 0; 117 | } 118 | 119 | word bitvec::hashfunct() const { 120 | int k; 121 | word f=len; 122 | 123 | if(len<=BPW) return vec+(vec>>(BPW/2))+(vec>>(BPW/4))+(vec>>(BPW/8)); 124 | for(k=0;k>(BPW/2)); 125 | return f; 126 | } 127 | 128 | bitvec& bitvec::qnot() { 129 | int k,l; 130 | 131 | if(len<=BPW) { 132 | vec=(~vec) & MASK(len); 133 | } else { 134 | l=WORDS(len); 135 | for(k=0;k=0;i-=4) { 215 | c=v.getword(i,(i+4<=v.length()) ? 4 : (v.length()-i)); 216 | if(c<=9) s << (char)('0'+c); else s << (char)('a'+c-10); 217 | } 218 | s << bitvec_hex_postfix; 219 | } else { 220 | for(i=v.length()-1;i>=0;i--) { 221 | s << (v[i] ? '1' : '0'); 222 | } 223 | } 224 | if(bitvec_format&BITVEC_FORMAT_KET) { 225 | s << bitvec_ket_postfix; 226 | } 227 | return s; 228 | } 229 | 230 | istream& operator >> (istream& s,bitvec& v) { 231 | int j=0,i=0,h=0,k=0; 232 | char *b; 233 | char c; 234 | 235 | if(!(b=new char[v.length()+3])) goto error; 236 | do { 237 | s >> c; 238 | if(!s) goto error; 239 | if(c=='|') k=1; 240 | } while(c==' ' || c=='\t' || c=='|'); 241 | while(1) { 242 | b[i++]=c; 243 | if(!(h && i<=(v.length()-1)/4) && !(!h && i> c; 245 | if(!s) goto error; 246 | if(c=='x' && b[i-1]=='0') { 247 | h=1; s >> c; i=0; 248 | continue; 249 | } 250 | if(c>='A' && c<='F') c+='a'-'A'; 251 | if((h && (c<'0' || c>'9') && (c<'a' || c>'f')) || 252 | (!h && c!='0' && c!='1')) goto error; 253 | } 254 | b[i--]=0; 255 | if(k) { 256 | s >> c; 257 | if(c!='>') goto error; 258 | } 259 | v=0; 260 | if(h) { 261 | for(j=0;i>=0 && j='0' && b[i]<='9' ? b[i]-'0' : b[i]-'a'+10)); 264 | } else { 265 | for(j=0;i>=0 && j, 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #ifndef _OPERATOR_H 16 | #define _OPERATOR_H 1 17 | 18 | #pragma interface 19 | 20 | #include "qustates.h" 21 | 22 | struct terminfo { 23 | quState *pqs; // the quatum register operated on 24 | bitvec frame; // vector of not affacted qubits 25 | term mapterm; // register term 26 | }; 27 | 28 | #ifndef PI 29 | #define PI M_PI 30 | #endif 31 | 32 | DEBUG( extern int noperators; ) 33 | 34 | class opOperator { 35 | int _bits; 36 | public: 37 | opOperator(int n) { _bits=n; DEBUG( noperators++; ) }; 38 | virtual ~opOperator(); 39 | int bits() const { return _bits; }; 40 | quState& operator () (quState& qs) const { 41 | QC_CHECK(_bits==qs.mapbits()); 42 | apply(qs); 43 | return qs; 44 | }; 45 | virtual void apply(quState& qs) const=0; 46 | virtual opOperator *newclone() const=0; 47 | 48 | friend class opVar; 49 | }; 50 | 51 | class opElementary : public opOperator { 52 | public: 53 | opElementary(int n) : opOperator(n) { }; 54 | virtual void apply(quState& qs) const; 55 | virtual void addterms(const terminfo& ti) const=0; 56 | }; 57 | 58 | class opMatrix : public opElementary { 59 | int len; 60 | protected: 61 | term **matrix; 62 | opMatrix(int bits); 63 | public: 64 | opMatrix(int n,term **m); 65 | virtual ~opMatrix(); 66 | virtual opOperator *newclone() const; 67 | virtual void addterms(const terminfo& ti) const; 68 | }; 69 | 70 | class opBit : public opMatrix { 71 | public: 72 | opBit(complx u00,complx u01,complx u10,complx u11,double norm=1.0); 73 | }; 74 | 75 | class opU2 : public opMatrix { 76 | public: 77 | opU2(double theta,double delta=0,double sigma=0,double tau=0); 78 | }; 79 | 80 | class opIdentity : public opElementary { 81 | public: 82 | opIdentity(int n) : opElementary(n) { }; 83 | virtual opOperator *newclone() const; 84 | virtual void apply(quState& qs) const; 85 | virtual void addterms(const terminfo& ti) const; 86 | }; 87 | 88 | class opSwap : public opElementary { 89 | int offs1,offs2; 90 | int len; 91 | public: 92 | opSwap(int n,int m,int o1,int o2) : opElementary(n) { 93 | QC_CHECK(o1+m<=n && o2+m<=n); 94 | QC_CHECK(o1+m<=o2 || o2+m<=o1); 95 | len=m; offs1=o1; offs2=o2; 96 | }; 97 | virtual opOperator *newclone() const; 98 | virtual void addterms(const terminfo& ti) const; 99 | }; 100 | 101 | class opPermutation : public opElementary { 102 | int len; 103 | protected: 104 | term *perm; 105 | opPermutation(int bits); 106 | public: 107 | opPermutation(int n,term *p); 108 | virtual ~opPermutation(); 109 | virtual opOperator *newclone() const; 110 | virtual void addterms(const terminfo& ti) const; 111 | }; 112 | 113 | class opFunction : public opElementary { 114 | int _arg; 115 | int _fct; 116 | public: 117 | opFunction(int arg,int fct) : opElementary(arg+fct) { 118 | _arg=arg; _fct=fct; 119 | }; 120 | int arg() const { return _arg; }; 121 | int fct() const { return _fct; }; 122 | virtual void addterms(const terminfo& ti) const; 123 | virtual term funct(const bitvec& v) const=0; 124 | }; 125 | 126 | class opEXPN : public opFunction { 127 | word _x; 128 | word _num; 129 | public: 130 | opEXPN(int arg,int fct,word x,word num) : opFunction(arg,fct) { 131 | QC_CHECK(arg<=BPW && (num<(1ul<<(BPW/2))) && xbits()) { 241 | QC_CHECK(in->bits()==out->bits()); 242 | inner=in; 243 | outer=out; 244 | }; 245 | virtual ~opComposition(); 246 | virtual void apply(quState& qs) const; 247 | virtual opOperator *newclone() const; 248 | }; 249 | 250 | class opEmbedded : public opOperator { 251 | int _offs; 252 | opOperator *_op; 253 | public: 254 | opEmbedded(int n,int offs,const opOperator& op) 255 | : opOperator(n) { 256 | QC_CHECK(op.bits()+offs<=n); 257 | _offs=offs; 258 | _op=op.newclone(); 259 | }; 260 | opEmbedded(int n,int offs,opOperator *op) 261 | : opOperator(n) { 262 | QC_CHECK(op->bits()+offs<=n); 263 | _offs=offs; 264 | _op=op; 265 | }; 266 | virtual ~opEmbedded(); 267 | virtual void apply(quState& qs) const; 268 | virtual opOperator *newclone() const; 269 | }; 270 | 271 | class opVar : public opOperator { 272 | opOperator *_op; 273 | public: 274 | opVar() : opOperator(0) { 275 | _op=0; 276 | }; 277 | opVar(const opVar& op) : opOperator(op.bits()) { 278 | _op=op.newclone(); 279 | }; 280 | opVar(const opOperator& op) : opOperator(op.bits()) { 281 | _op=op.newclone(); 282 | }; 283 | const opVar& operator = (const opVar& op) { 284 | if(_op) delete _op; 285 | _op=op.newclone(); 286 | _bits=op.bits(); 287 | return op; 288 | }; 289 | const opOperator& operator = (const opOperator& op) { 290 | if(_op) delete _op; 291 | _op=op.newclone(); 292 | _bits=op.bits(); 293 | return op; 294 | }; 295 | const opOperator& operator *= (const opOperator& op) { 296 | if(_op) { 297 | QC_CHECK(bits()==op.bits()); 298 | _op=new opComposition(_op,op.newclone()); 299 | } else { 300 | _op=op.newclone(); 301 | _bits=op.bits(); 302 | }; 303 | return *_op; 304 | }; 305 | virtual ~opVar(); 306 | virtual void apply(quState& qs) const; 307 | virtual opOperator *newclone() const; 308 | }; 309 | 310 | /* functions */ 311 | 312 | inline opComposition operator * (const opOperator& out,const opOperator& in) { 313 | return opComposition(in,out); 314 | } 315 | 316 | inline opComposition operator / (const opOperator& low,const opOperator& high) { 317 | int n=low.bits()+high.bits(); 318 | return opComposition(new opEmbedded(n,0,low), 319 | new opEmbedded(n,low.bits(),high)); 320 | } 321 | 322 | #endif 323 | 324 | -------------------------------------------------------------------------------- /qcl.lex: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | /********************************************************************** 4 | 5 | This file is part of the Quantum Computation Language QCL. 6 | 7 | (c) Copyright by Bernhard Oemer , 1998 8 | 9 | This program comes without any warranty; without even the implied 10 | warranty of merchantability or fitness for any particular purpose. 11 | 12 | This program is free software under the terms of the 13 | GNU General Public Licence (GPL) version 2 or higher 14 | 15 | ************************************************************************/ 16 | 17 | #include "types.h" 18 | #include "syntax.h" 19 | #include "parse.h" 20 | #include "yacc.h" 21 | 22 | YY_BUFFER_STATE include_stack[YYMAXINCLUDE]; 23 | YY_BUFFER_STATE string_buffer; 24 | FILE* toplevel_file; 25 | 26 | double cnum_real,cnum_imag; 27 | 28 | %} 29 | 30 | %option noyywrap 31 | %option yylineno 32 | 33 | %x STR 34 | %x REM 35 | %x COM 36 | %x INC 37 | %x SET 38 | 39 | %x SCINC 40 | 41 | ALPHA [a-zA-Z] 42 | DIGIT [0-9] 43 | ALPHANUM {ALPHA}|{DIGIT} 44 | SPECIAL [^a-zA-Z0-9] 45 | UNSIGNED {DIGIT}+ 46 | REAL {DIGIT}+"."{DIGIT}* 47 | CNUM [ \t]*[+\-]?{DIGIT}+("."{DIGIT}*)?[ \t]* 48 | COMPLEX "("{CNUM}","{CNUM}")" 49 | ID {ALPHA}{ALPHANUM}* 50 | %% 51 | 52 | "const" yylval.OBJ=0; return tokCONST; 53 | "cond" yylval.OBJ=0; return tokCOND; 54 | "extern" yylval.OBJ=0; return tokEXTERN; 55 | "operator" yylval.OBJ=0; return tokOP; 56 | "procedure" yylval.OBJ=0; return tokPROC; 57 | "qufunct" yylval.OBJ=0; return tokQUFUN; 58 | "for" yylval.OBJ=0; return tokFOR; 59 | "to" yylval.OBJ=0; return tokTO; 60 | "while" yylval.OBJ=0; return tokWHILE; 61 | "until" yylval.OBJ=0; return tokUNTIL; 62 | "break" yylval.OBJ=0; return tokBREAK; 63 | "return" yylval.OBJ=0; return tokRETURN; 64 | "if" yylval.OBJ=0; return tokIF; 65 | "else" yylval.OBJ=0; return tokELSE; 66 | "and" yylval.OBJ=0; return tokAND; 67 | "or" yylval.OBJ=0; return tokOR; 68 | "xor" yylval.OBJ=0; return tokXOR; 69 | "not" yylval.OBJ=0; return tokNOT; 70 | "mod" yylval.OBJ=0; return tokMOD; 71 | "step" yylval.OBJ=0; return tokSTEP; 72 | "input" yylval.OBJ=0; return tokINPUT; 73 | "print" yylval.OBJ=0; return tokPRINT; 74 | "exit" yylval.OBJ=0; return tokEXIT; 75 | "measure" yylval.OBJ=0; return tokMEASURE; 76 | "reset" yylval.OBJ=0; return tokRESET; 77 | "dump" yylval.OBJ=0; return tokDUMP; 78 | "plot" yylval.OBJ=0; return tokPLOT; 79 | "list" yylval.OBJ=0; return tokINSPECT; 80 | "load" yylval.OBJ=0; return tokLOAD; 81 | "save" yylval.OBJ=0; return tokSAVE; 82 | "shell" yylval.OBJ=0; return tokSHELL; 83 | 84 | "<->" yylval.OBJ=0; return tokSWAP; 85 | "->" yylval.OBJ=0; return tokTRANS; 86 | "<-" yylval.OBJ=0; return tokINVTRANS; 87 | "==" yylval.OBJ=0; return tokEQ; 88 | "<=" yylval.OBJ=0; return tokLEEQ; 89 | ">=" yylval.OBJ=0; return tokGREQ; 90 | "!=" yylval.OBJ=0; return tokNOTEQ; 91 | "\\" yylval.OBJ=0; return tokRANGE_LENGTH; 92 | "::" yylval.OBJ=0; return tokRANGE_LENGTH; 93 | ":" yylval.OBJ=0; return tokRANGE_END; 94 | ".." yylval.OBJ=0; return tokRANGE_END; 95 | 96 | "("|")"|"["|"]" yylval.OBJ=0; return *yytext; 97 | "+"|"-"|"*"|"/"|"^" yylval.OBJ=0; return *yytext; 98 | "<"|">"|"="|"#" yylval.OBJ=0; return *yytext; 99 | "!"|"&"|"," yylval.OBJ=0; return *yytext; 100 | 101 | "{"[ \t\n\r;]* yylval.OBJ=0; return '{'; 102 | "}"[ \t\n\r;]* yylval.OBJ=0; return '}'; 103 | ";"[ \t\n\r;]* yylval.OBJ=0; return ';'; 104 | 105 | "boolean" yylval.TYPE=tBOOLEAN; return tokTYPE; 106 | "int" yylval.TYPE=tINTEGER; return tokTYPE; 107 | "real" yylval.TYPE=tREAL; return tokTYPE; 108 | "complex" yylval.TYPE=tCOMPLEX; return tokTYPE; 109 | "string" yylval.TYPE=tSTRING; return tokTYPE; 110 | "qureg" yylval.TYPE=tQUREG; return tokTYPE; 111 | "quconst" yylval.TYPE=tQUCONST; return tokTYPE; 112 | "quvoid" yylval.TYPE=tQUVOID; return tokTYPE; 113 | "quscratch" yylval.TYPE=tQUSCR; return tokTYPE; 114 | "qucond" yylval.TYPE=tQUCOND; return tokTYPE; 115 | 116 | "vector" yylval.TENSOR=1; return tokTENSOR; 117 | "matrix" yylval.TENSOR=2; return tokTENSOR; 118 | "tensor"[3-9] yylval.TENSOR=yytext[6]-'0'; return tokTENSOR; 119 | 120 | "exp(" yylval.OBJTYPE=sEXP; return tokBASEFUNCT; 121 | "sin(" yylval.OBJTYPE=sSIN; return tokBASEFUNCT; 122 | "cos(" yylval.OBJTYPE=sCOS; return tokBASEFUNCT; 123 | "tan(" yylval.OBJTYPE=sTAN; return tokBASEFUNCT; 124 | "cot(" yylval.OBJTYPE=sCOT; return tokBASEFUNCT; 125 | "sinh(" yylval.OBJTYPE=sSINH; return tokBASEFUNCT; 126 | "cosh(" yylval.OBJTYPE=sCOSH; return tokBASEFUNCT; 127 | "tanh(" yylval.OBJTYPE=sTANH; return tokBASEFUNCT; 128 | "coth(" yylval.OBJTYPE=sCOTH; return tokBASEFUNCT; 129 | "abs(" yylval.OBJTYPE=sABS; return tokBASEFUNCT; 130 | "Re(" yylval.OBJTYPE=sRE; return tokBASEFUNCT; 131 | "Im(" yylval.OBJTYPE=sIM; return tokBASEFUNCT; 132 | "conj(" yylval.OBJTYPE=sCONJ; return tokBASEFUNCT; 133 | "floor(" yylval.OBJTYPE=sFLOOR; return tokBASEFUNCT; 134 | "ceil(" yylval.OBJTYPE=sCEIL; return tokBASEFUNCT; 135 | "sqrt(" yylval.OBJTYPE=sSQRT; return tokBASEFUNCT; 136 | "not(" yylval.OBJTYPE=sINOT; return tokBASEFUNCT; 137 | "int(" yylval.OBJTYPE=sINT; return tokBASEFUNCT; 138 | "real(" yylval.OBJTYPE=sREAL; return tokBASEFUNCT; 139 | "complex(" yylval.OBJTYPE=sCOMPLEX; return tokBASEFUNCT; 140 | "string(" yylval.OBJTYPE=sSTRING; return tokBASEFUNCT; 141 | 142 | "log(" yylval.OBJTYPE=sLOG; return tokLISTFUNCT; 143 | "random(" yylval.OBJTYPE=sRANDOM; return tokLISTFUNCT; 144 | "min(" yylval.OBJTYPE=sMIN; return tokLISTFUNCT; 145 | "max(" yylval.OBJTYPE=sMAX; return tokLISTFUNCT; 146 | "gcd(" yylval.OBJTYPE=sGCD; return tokLISTFUNCT; 147 | "lcm(" yylval.OBJTYPE=sLCM; return tokLISTFUNCT; 148 | "bit(" yylval.OBJTYPE=sBIT; return tokLISTFUNCT; 149 | "and(" yylval.OBJTYPE=sIAND; return tokLISTFUNCT; 150 | "or(" yylval.OBJTYPE=sIOR; return tokLISTFUNCT; 151 | "xor(" yylval.OBJTYPE=sIXOR; return tokLISTFUNCT; 152 | 153 | "vector(" yylval.OBJTYPE=sVECTOR; return tokLISTFUNCT; 154 | "matrix(" yylval.OBJTYPE=sMATRIX; return tokLISTFUNCT; 155 | "tensor"[3-9]"(" { 156 | yylval.OBJTYPE=(ObjType)(sSCALAR+(yytext[6]-'0')); 157 | return tokLISTFUNCT; 158 | } 159 | 160 | yylval.OBJTYPE=sMATRIX; return tokLISTFUNCT; 161 | 162 | "set"[ \t]+ BEGIN(SET); 163 | [a-zA-Z\-]+ { 164 | BEGIN(0); 165 | yylval.STRING=YYNEW(string(yytext)); 166 | return tokSET; 167 | } 168 | 169 | "include"[ \t]+\" BEGIN(INC); 170 | [^\"\n\t]+ { 171 | yylval.STRING=YYNEW(string(yytext)); 172 | return tokINCLUDE; 173 | } 174 | \" BEGIN(0); 175 | 176 | 177 | "true" { 178 | yylval.OBJ=YYNEW(sConst(tValue(TRUE))); 179 | return tokCONS; 180 | } 181 | 182 | "false" { 183 | yylval.OBJ=YYNEW(sConst(tValue(FALSE))); 184 | return tokCONS; 185 | } 186 | 187 | {UNSIGNED} { 188 | yylval.OBJ=YYNEW(sConst(tValue((tInt)atol(yytext)))); 189 | return tokCONS; 190 | } 191 | 192 | {UNSIGNED}".." { 193 | yylval.OBJ=YYNEW(sConst(tValue((tInt)atol(yytext)))); 194 | unput('.'); unput('.'); 195 | return tokCONS; 196 | } 197 | 198 | {REAL} { 199 | yylval.OBJ=YYNEW(sConst(tValue((tReal)atof(yytext)))); 200 | return tokCONS; 201 | } 202 | 203 | {COMPLEX} { 204 | sscanf(yytext,"(%lf,%lf)",&cnum_real,&cnum_imag); 205 | yylval.OBJ=YYNEW(sConst(tValue(tComplex(cnum_real,cnum_imag)))); 206 | return tokCONS; 207 | } 208 | 209 | {ID}"(" yylval.ID=YYNEW(tId(yytext,strlen(yytext)-1)); return tokIDCALL; 210 | {ID} yylval.ID=YYNEW(tId(yytext)); return tokID; 211 | 212 | \"\" yylval.OBJ=YYNEW(sConst(tValue(string("")))); return tokCONS; 213 | 214 | \" BEGIN(STR); 215 | [^\"\n\t]* { 216 | yylval.OBJ=YYNEW(sConst(tValue((char*)yytext))); 217 | return tokCONS; 218 | } 219 | 220 | \" BEGIN(0); 221 | 222 | "/*" BEGIN(REM); 223 | [^*\n]* ; 224 | "*"+[^*/\n]* ; 225 | \n ; 226 | "*"+"/" BEGIN(0); 227 | 228 | "//" BEGIN(COM); 229 | [^\n]* ; 230 | "\n" BEGIN(0); 231 | 232 | ^"<<"[ \t]* BEGIN(SCINC); 233 | 234 | [^\"\n \t;]+ { 235 | BEGIN(0); 236 | yylval.STRING=YYNEW(string(yytext)); 237 | return tokINCLUDE; 238 | } 239 | 240 | ^"?" yylval.OBJ=0; return tokPRINT; 241 | 242 | 243 | [ \t\n\r] ; 244 | 245 | <> yylval.OBJ=0; return tokEOF; 246 | 247 | . yylval.OBJ=0; return tokERROR; 248 | 249 | %% 250 | 251 | void yyScanString(string s) { 252 | YY_FLUSH_BUFFER; 253 | if(yyStringBufferActive) yy_delete_buffer(string_buffer); 254 | 255 | string_buffer=yy_scan_string(s.c_str()); 256 | yyIncludeStackPt=0; 257 | yyStringBufferActive=1; 258 | yyToplevelFile=0; 259 | yylineno=1; 260 | } 261 | 262 | void yyScanFile(FILE *f) { 263 | YY_FLUSH_BUFFER; 264 | if(yyStringBufferActive) yy_delete_buffer(string_buffer); 265 | yyrestart(f); 266 | yyIncludeStackPt=0; 267 | yyStringBufferActive=0; 268 | yyToplevelFile=f; 269 | yylineno=1; 270 | } 271 | 272 | void yyCleanUp() { 273 | int i; 274 | YY_FLUSH_BUFFER; 275 | yyrestart(stdin); 276 | if(yyToplevelFile) fclose (yyToplevelFile); 277 | if(yyStringBufferActive) yy_delete_buffer(string_buffer); 278 | yyToplevelFile=0; 279 | yyStringBufferActive=0; 280 | for(i=0;i, 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include "types.h" 19 | #include "cond.h" 20 | #include "options.h" 21 | #include "error.h" 22 | 23 | #include 24 | #include 25 | 26 | #ifdef QCL_DEBUG 27 | int n_object=0; 28 | int n_value=0; 29 | #endif 30 | const char *FALSE_STR="false"; 31 | const char *TRUE_STR="true"; 32 | 33 | const char *BASETYPE_STR[] = {"%UNDEF%", "%ERROR%", "procedure", "operator", 34 | "qufunct", "boolean", "int", "real", "complex", "string", "quconst", 35 | "qureg", "quvoid", "quscratch", "qucond" }; 36 | 37 | string sdec(long n,const char *format) { 38 | static char buf[256]; 39 | snprintf(buf,256,format,n); 40 | return string(buf); 41 | } 42 | 43 | int tensordim(int ord, int elem) { 44 | if(ord==1) return elem; 45 | int dim; 46 | if(ord==2) 47 | dim=(int)floor(sqrt((double)elem)+0.1); 48 | else 49 | dim=(int)floor(pow((double)elem,(double)1.0/ord)+0.1); 50 | if((int)pow((double)dim,(int)ord)!=elem) return 0; 51 | return dim; 52 | } 53 | 54 | int tensorelem(int ord, int dim) { 55 | int n=1; 56 | while(ord--) n*=dim; 57 | return n; 58 | } 59 | 60 | ostream& operator << (ostream& s, const tType& t) { 61 | s << t.str(); 62 | return s; 63 | } 64 | 65 | string tType::str() const { 66 | string s; 67 | if(basetype()<=tQUCOND) 68 | s=BASETYPE_STR[basetype()]; 69 | else 70 | s="unknown type"; 71 | if(ord()==1) 72 | s+=" vector"; 73 | else if(ord()==2) 74 | s+=" matrix"; 75 | else if(ord()>2) 76 | s+=" tensor"+sdec(ord()); 77 | return s; 78 | } 79 | 80 | ostream& operator << (ostream& s, const tValue& v) { 81 | return s << v.str(); 82 | } 83 | 84 | void tValue::error(const char* m) const { 85 | SEGFAULT; 86 | throw tError(errINT,string(m)); 87 | } 88 | 89 | void tValue::delpointer() { 90 | if(ord()) { 91 | if(_val.pt->refs>1) { 92 | _val.pt->refs--; 93 | } else { 94 | if(_val.pt->refs==1) { 95 | switch(basetype()) { 96 | case tINTEGER: qcl_delarray(_val.pt->pi); break; 97 | case tREAL: qcl_delarray(_val.pt->pr); break; 98 | case tCOMPLEX: qcl_delarray(_val.pt->pz); break; 99 | default: error("invalid tensor type"); 100 | } 101 | } 102 | qcl_delete(_val.pt); 103 | } 104 | } else { 105 | switch(basetype()) { 106 | case tCOMPLEX: qcl_delete(_val.pz); return; 107 | case tSTRING: qcl_delete(_val.ps); return; 108 | case tQUCONST: 109 | case tQUREG: 110 | case tQUVOID: 111 | case tQUSCR: if(!_val.pq->isbasestate()) 112 | qcl_delete(_val.pq); 113 | return; 114 | case tQUCOND: qcl_delete(_val.pc); return; 115 | default: ; 116 | } 117 | } 118 | } 119 | 120 | void tValue::copytensor() { 121 | tensor *a=_val.pt; 122 | tensor *b=new tensor; 123 | b->dim=a->dim; 124 | b->len=a->len; 125 | b->refs=1; 126 | a->refs--; 127 | int i; 128 | switch(basetype()) { 129 | case tINTEGER: 130 | b->pi=new tInt[b->len]; 131 | for(i=0;ilen;i++) b->pi[i]=a->pi[i]; 132 | break; 133 | case tREAL: 134 | b->pr=new tReal[b->len]; 135 | for(i=0;ilen;i++) b->pr[i]=a->pr[i]; 136 | break; 137 | case tCOMPLEX: 138 | b->pz=new tComplex[b->len]; 139 | for(i=0;ilen;i++) b->pz[i]=a->pz[i]; 140 | break; 141 | default: throw tError(errINT,"invalid tensor type"); 142 | } 143 | _val.pt=b; 144 | } 145 | 146 | void tValue::inittensor(const tType& t,int d) { 147 | if(!t.ord()) { 148 | init(t); 149 | return; 150 | } 151 | _type=t; 152 | tensor *b=new tensor; 153 | b->dim=d; 154 | b->len=tensorelem(ord(),d); 155 | b->refs=1; 156 | int i; 157 | switch(basetype()) { 158 | case tINTEGER: 159 | b->pi=new tInt[b->len]; 160 | for(i=0;ilen;i++) b->pi[i]=0; 161 | break; 162 | case tREAL: 163 | b->pr=new tReal[b->len]; 164 | for(i=0;ilen;i++) b->pr[i]=0; 165 | break; 166 | case tCOMPLEX: 167 | b->pz=new tComplex[b->len]; 168 | for(i=0;ilen;i++) b->pz[i]=0; 169 | break; 170 | default: error("invalid tensor type"); 171 | } 172 | _val.pt=b; 173 | } 174 | 175 | QuCond tValue::toQuCond() const { 176 | if(_type==tQUCOND) return *_val.pc; 177 | if(isQuExpr()) return _val.pq; 178 | if(isBoolean()) 179 | return toBool() ? QCTRUE(optBits) : QCFALSE(optBits); 180 | #ifdef QCL_DEBUG 181 | cerr << "toQuCond: " << str() << " is not conditional\n"; 182 | #endif 183 | return QuCond(); 184 | } 185 | 186 | tValue tValue::convert(const tType& t) const { 187 | if(ord()) { 188 | tensor *b=new tensor; 189 | b->dim=dim(); 190 | b->len=elem(); 191 | b->refs=1; 192 | tValue v; 193 | v._type=t; 194 | v._val.pt=b; 195 | int i; 196 | switch(v.basetype()) { 197 | case tINTEGER: 198 | b->pi=new tInt[b->len]; 199 | for(i=0;ilen;i++) b->pi[i]=(*this)[i].toInt(); 200 | break; 201 | case tREAL: 202 | b->pr=new tReal[b->len]; 203 | for(i=0;ilen;i++) b->pr[i]=(*this)[i].toReal(); 204 | break; 205 | case tCOMPLEX: 206 | b->pz=new tComplex[b->len]; 207 | for(i=0;ilen;i++) b->pz[i]=(*this)[i].toComplex(); 208 | break; 209 | default: error("tensor convert failed"); 210 | } 211 | return v; 212 | } else { 213 | switch(t.basetype()) { 214 | case tINTEGER: return toInt(); 215 | case tREAL: return toReal(); 216 | case tCOMPLEX: return toComplex(); 217 | case tQUCOND: return toQuCond(); 218 | default: 219 | if(!isQuExpr() || !t.isQuExpr()) 220 | error("scalar convert failed"); 221 | tValue v=*this; 222 | v._type=t; 223 | return v; 224 | } 225 | } 226 | return tValue(); 227 | } 228 | 229 | string tValue::str() const { 230 | if(ord()) { 231 | int i; 232 | string ostr="["; 233 | for(i=0;iimag())real()).str(); 264 | else 265 | return "("+tValue(_val.pz->real()).str()+","+ 266 | tValue(_val.pz->imag()).str()+")"; 267 | } else { 268 | sprintf(s,"(%.*f,%.*f)",optPrintPrecision,_val.pz->real(), 269 | optPrintPrecision,_val.pz->imag()); 270 | return s; 271 | } 272 | case tSTRING: return (string)*(_val.ps); 273 | case tQUCONST: 274 | case tQUREG: 275 | case tQUVOID: 276 | case tQUSCR: 277 | if(optQuregMask) { 278 | bitvec b(_val.pq->basebits()),c; 279 | string ostr="|"; 280 | int i,j; 281 | for(i=_val.pq->basebits()-1;i>=0;i--) { 282 | b.setbit(i,1); 283 | c=_val.pq->map(b); 284 | if(zero(c)) { 285 | ostr+="."; 286 | } else { 287 | for(j=0;j<_val.pq->mapbits();j++) { 288 | if(c[j]) { ostr+=(char)(j<10 ? '0'+j : 'a'+j-10); break; } 289 | } 290 | } 291 | b.setbit(i,0); 292 | } 293 | return ostr+">"; 294 | } else { 295 | if(isEmpty()) return "<>"; 296 | string ostr="<"; 297 | int i; 298 | for(i=0;;i++) { 299 | ostr+=sdec(_val.pq->mapindex(i)); 300 | if(i>=_val.pq->mapbits()-1) break; 301 | ostr+=","; 302 | } 303 | return ostr+">"; 304 | } 305 | //sprintf(s,"[%d / %d qubits]",_val.pq->mapbits(),_val.pq->basebits()); 306 | case tQUCOND: return _val.pc->str(); 307 | default: return _type.str(); 308 | }; 309 | return ""; 310 | } 311 | 312 | -------------------------------------------------------------------------------- /syntax.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Language QCL. 4 | 5 | (c) Copyright by Bernhard Oemer , 1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | 16 | #pragma implementation 17 | 18 | #include 19 | #include 20 | 21 | #include "syntax.h" 22 | #include "error.h" 23 | #include "quheap.h" 24 | #include "debug.h" 25 | #include "options.h" 26 | #include "dump.h" 27 | 28 | #define ERR (-1) 29 | #define RET (-2) 30 | #define BRK (-3) 31 | 32 | #define EXERR(e,s) { \ 33 | err->report(e,this); \ 34 | err->remark(s); \ 35 | err->line(prtstr(),0); \ 36 | if(optDebug) qclshell(loc,gl,qh,this,err,DB_ERROR); \ 37 | return ERR; \ 38 | } 39 | 40 | sVarDef CONDDEF(tQUCONST,new string(CONDID)); 41 | 42 | void sRoutDef::invoke(SymTable *loc,SymTable *gl,QuHeap *qh,int inv) { 43 | int i; 44 | void *c; 45 | sDef *p; 46 | tValue *pv,*qv; 47 | tValue v; 48 | int f; 49 | ostream *log=&cout; 50 | 51 | if(optCheck) { 52 | for_plist(p,args(),c) { 53 | if(!inv && p->type().isQuVoid() || p->type().isQuScr()) { 54 | pv=loc->getRef(p->id()); 55 | if(!pv || !pv->isQuExpr()) 56 | throw tError(errINT,"invalid quantum parameter",this); 57 | i=pv->qustate()->mapbits(); 58 | if(pv->qustate()->prob(bitvec(i))<(1.0-EPSILON_CHECK)) 59 | throw tError(errMEM,"void or scratch register not empty",this); 60 | } 61 | } 62 | } 63 | 64 | if(irqFlag==IRQ_SHELL) qclshell(loc,gl,qh,this,DB_IRQ); 65 | if(irqFlag==IRQ_EXIT) throw tError(errIRQ,"execution aborted"); 66 | 67 | if(isExtern()) { 68 | if(optLog) { 69 | if(optLogfile) log=optLogfile; 70 | *log << "@ "; 71 | if(inv) *log << "!"; 72 | *log << id() << "("; 73 | f=0; 74 | for_plist(p,args(),c) { 75 | if(f) *log << ","; else f=1; 76 | *log << p->prtstr() << "="; 77 | if((pv=loc->getRef(p->id()))) { 78 | *log << pv->str(); 79 | } else { 80 | *log << "undefined"; 81 | } 82 | } 83 | if(isCondDef() && (pv=loc->getRef(CONDID))) 84 | *log << ";" CONDID "=" << pv->str(); 85 | *log << ")\n"; 86 | }; 87 | if(!optTest) { 88 | isStateModified=1; 89 | (pext)(this,loc,inv); 90 | if(optLogState) dump_state(qh,optLogfile); 91 | } 92 | return; 93 | } 94 | 95 | SymTab l; 96 | SymTabComb lcomb((SymTable*)&l,loc); 97 | QuHeap lqh(qh,isQuDef()); 98 | 99 | if(isBennet()) { 100 | for_plist(p,args(),c) { 101 | if(p->type().isQuVoid()) { 102 | pv=loc->getRef(p->id()); 103 | if(!pv || !pv->isQuExpr()) 104 | throw tError(errINT,"invalid quantum parameter",this); 105 | v=lqh.qualloc(pv->qustate()->mapbits()); 106 | if(v.isError()) 107 | throw tError(errMEM,"can't allocate internal scratch space",this); 108 | l.put(p,v); 109 | } 110 | } 111 | } 112 | 113 | if(isCondDef() && isCond()) { 114 | pv=loc->getRef(CONDID); 115 | if(!pv || !pv->isQuConst()) 116 | throw tError(errINT,"undefined quantum condition"); 117 | lqh.qcond(pv->qustate(),gl); 118 | } 119 | 120 | QuHeap *pqh=&lqh; 121 | int forks=0; 122 | 123 | do { 124 | SymTab ll; 125 | SymTabComb llcomb((SymTable*)&ll,&lcomb); 126 | forks++; 127 | if(forks>1) pqh=new QuHeap(&lqh); 128 | try { 129 | defs()->define(&llcomb,gl,pqh); 130 | body()->exec(&llcomb,gl,&lqh); 131 | } catch(sBreak *p) { 132 | } 133 | if(forks>1) delete pqh; 134 | } while(lqh.qendfork(gl)); 135 | 136 | if(isBennet()) { 137 | lqh.apply(gl,0); 138 | for_plist(p,args(),c) { 139 | if(p->type().isQuVoid()) { 140 | pv=loc->getRef(p->id()); 141 | if(!pv || !pv->isQuExpr()) 142 | throw tError(errINT,"parameter "+p->id()+" not found",this); 143 | qv=l.getRef(p->id()); 144 | if(!qv || !qv->isQuExpr()) 145 | throw tError(errINT,"temporary register not found",this); 146 | lqh.call(FANOUTID,gl,!inv,0,*qv,*pv); 147 | } 148 | } 149 | lqh.apply(gl,1); 150 | } else { 151 | lqh.apply(gl,inv); 152 | } 153 | 154 | if(optCheck) { 155 | term t; 156 | for_plist(p,args(),c) { 157 | if(inv && p->type().isQuVoid() || p->type().isQuScr()) { 158 | pv=loc->getRef(p->id()); 159 | if(!pv || !pv->isQuExpr()) 160 | throw tError(errINT,"temporary register not found",this); 161 | i=pv->qustate()->mapbits(); 162 | if(pv->qustate()->prob(bitvec(i))<(1.0-EPSILON_CHECK)) 163 | throw tError(errMEM,"void or scratch register not empty",this); 164 | } 165 | } 166 | for(i=0;istate()->baseterms();i++) { 167 | t=qh->state()->baseterm(i); 168 | if(!zero(t.vect()&qh->mFree()) && norm(t.ampl())>EPSILON_CHECK) 169 | throw tError(errMEM,"quantum heap is corrupted",this); 170 | } 171 | } 172 | } 173 | 174 | void sFunctDef::invoke(SymTable *loc,SymTable *gl,QuHeap *qh,int inv) { 175 | SymTab l; 176 | SymTabComb lcomb((SymTable*)&l,loc); 177 | pdefs->define(&lcomb,gl,qh); 178 | body()->exec(&lcomb,gl,qh); 179 | } 180 | 181 | 182 | #define ENTRY(s,n) case n: return s; 183 | 184 | string sObject::objstr() const { 185 | switch(object()) { 186 | ENTRY("sVOID",sVOID); 187 | 188 | ENTRY("sOBJECT",sOBJECT); 189 | ENTRY("sLIST",sLIST); 190 | 191 | ENTRY("sEXPR",sEXPR); 192 | ENTRY("sEXPRLIST",sEXPRLIST); 193 | ENTRY("sCONST",sCONST); 194 | ENTRY("sVAR",sVAR); 195 | ENTRY("sSUBSCRIPT",sSUBSCRIPT); 196 | ENTRY("sSUBRANGE",sSUBRANGE); 197 | ENTRY("sFUNCTCALL",sFUNCTCALL); 198 | ENTRY("sUNOP",sUNOP); 199 | ENTRY("sNEG",sNEG); 200 | ENTRY("sNOT",sNOT); 201 | ENTRY("sLENGTH",sLENGTH); 202 | ENTRY("sBINOP",sBINOP); 203 | ENTRY("sADD",sADD); 204 | ENTRY("sSUB",sSUB); 205 | ENTRY("sMULT",sMULT); 206 | ENTRY("sDIV",sDIV); 207 | ENTRY("sMOD",sMOD); 208 | ENTRY("sPOW",sPOW); 209 | ENTRY("sLESS",sLESS); 210 | ENTRY("sEQUAL",sEQUAL); 211 | ENTRY("sLEEQ",sLEEQ); 212 | ENTRY("sNOTEQ",sNOTEQ); 213 | ENTRY("sAND",sAND); 214 | ENTRY("sOR",sOR); 215 | ENTRY("sXOR",sXOR); 216 | ENTRY("sCONCAT",sCONCAT); 217 | ENTRY("sBASEFUNCT",sBASEFUNCT); 218 | ENTRY("sEXP",sEXP); 219 | ENTRY("sSIN",sSIN); 220 | ENTRY("sCOS",sCOS); 221 | ENTRY("sTAN",sTAN); 222 | ENTRY("sCOT",sCOT); 223 | ENTRY("sSINH",sSINH); 224 | ENTRY("sCOSH",sCOSH); 225 | ENTRY("sTANH",sTANH); 226 | ENTRY("sCOTH",sCOTH); 227 | ENTRY("sABS",sABS); 228 | ENTRY("sRE",sRE); 229 | ENTRY("sIM",sIM); 230 | ENTRY("sCONJ",sCONJ); 231 | ENTRY("sFLOOR",sFLOOR); 232 | ENTRY("sCEIL",sCEIL); 233 | ENTRY("sSQRT",sSQRT); 234 | ENTRY("sINOT",sINOT); 235 | ENTRY("sINT",sINT); 236 | ENTRY("sREAL",sREAL); 237 | ENTRY("sCOMPLEX",sCOMPLEX); 238 | ENTRY("sSTRING",sSTRING); 239 | 240 | ENTRY("sLISTFUNCT",sLISTFUNCT); 241 | ENTRY("sLOG",sLOG); 242 | ENTRY("sRANDOM",sRANDOM); 243 | ENTRY("sMIN",sMIN); 244 | ENTRY("sMAX",sMAX); 245 | ENTRY("sGCD",sGCD); 246 | ENTRY("sLCM",sLCM); 247 | ENTRY("sBIT",sBIT); 248 | ENTRY("sIAND",sIAND); 249 | ENTRY("sIOR",sIOR); 250 | ENTRY("sIXOR",sIXOR); 251 | ENTRY("sSCALAR",sSCALAR); 252 | ENTRY("sVECTOR",sVECTOR); 253 | ENTRY("sMATRIX",sMATRIX); 254 | ENTRY("sTENSOR3",sTENSOR3); 255 | ENTRY("sTENSOR4",sTENSOR4); 256 | ENTRY("sTENSOR5",sTENSOR5); 257 | ENTRY("sTENSOR6",sTENSOR6); 258 | ENTRY("sTENSOR7",sTENSOR7); 259 | ENTRY("sTENSOR8",sTENSOR8); 260 | ENTRY("sTENSOR9",sTENSOR9); 261 | 262 | ENTRY("sSTMT",sSTMT); 263 | ENTRY("sSTMTLIST",sSTMTLIST); 264 | ENTRY("sCALL",sCALL); 265 | ENTRY("sASSIGN",sASSIGN); 266 | ENTRY("sFOR",sFOR); 267 | ENTRY("sIF",sIF); 268 | ENTRY("sLOOP",sLOOP); 269 | ENTRY("sWHILE",sWHILE); 270 | ENTRY("sUNTIL",sUNTIL); 271 | ENTRY("sBREAK",sBREAK); 272 | ENTRY("sRETURN",sRETURN); 273 | ENTRY("sINPUT",sINPUT); 274 | ENTRY("sPRINT",sPRINT); 275 | ENTRY("sEXIT",sEXIT); 276 | ENTRY("sMEASURE",sMEASURE); 277 | ENTRY("sINCLUDE",sINCLUDE); 278 | ENTRY("sRESET",sRESET); 279 | ENTRY("sDUMP",sDUMP); 280 | ENTRY("sPLOT",sPLOT); 281 | ENTRY("sINSPECT",sINSPECT); 282 | ENTRY("sLOAD",sLOAD); 283 | ENTRY("sSAVE",sSAVE); 284 | ENTRY("sSET",sSET); 285 | ENTRY("sSHELL",sSHELL); 286 | 287 | ENTRY("sDEF",sDEF); 288 | ENTRY("sDEFLIST",sDEFLIST); 289 | ENTRY("sROUTDEF",sROUTDEF); 290 | ENTRY("sFUNCTDEF",sFUNCTDEF); 291 | ENTRY("sPROCDEF",sPROCDEF); 292 | ENTRY("sQUOPDEF",sQUOPDEF); 293 | ENTRY("sQUFUNDEF",sQUFUNDEF); 294 | ENTRY("sARGDEF",sARGDEF); 295 | ENTRY("sVARDEF",sVARDEF); 296 | ENTRY("sCONSTDEF",sCONSTDEF); 297 | 298 | ENTRY("sEOF",sEOF); 299 | ENTRY("sMSG",sMSG); 300 | default: ; 301 | } 302 | return "UNKNOWN_OBJECT"; 303 | } 304 | 305 | #undef ENTRY 306 | -------------------------------------------------------------------------------- /qc/operator.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #pragma implementation 16 | 17 | #include "operator.h" 18 | 19 | DEBUG( int noperators=0; ) 20 | 21 | /* opOperator */ 22 | 23 | opOperator::~opOperator() { DEBUG( noperators--; ) } 24 | 25 | /* opElementary */ 26 | 27 | void opElementary::apply(quState& qs) const { 28 | int i,n; 29 | terminfo ti; 30 | bitvec m; 31 | 32 | if(!qs.mapbits()) return; 33 | qs.opbegin(); 34 | ti.pqs=&qs; 35 | m=~qs.mapmask(); 36 | n=qs.baseterms(); 37 | for(i=0;ivect().length()) { 84 | ti.pqs->opadd(ti.frame | ti.pqs->unmap(pt->vect()),z*pt->ampl()); 85 | pt++; 86 | }; 87 | } 88 | 89 | opOperator *opMatrix::newclone() const { 90 | return new opMatrix(bits(),matrix); 91 | } 92 | 93 | /* opBit */ 94 | 95 | opBit::opBit(complx u00,complx u01,complx u10,complx u11,double norm) 96 | : opMatrix(1) { 97 | matrix[0]=new term[3]; 98 | matrix[1]=new term[3]; 99 | matrix[0][0].set(bitvec(1,0),u00*norm); 100 | matrix[0][1].set(bitvec(1,1),u10*norm); 101 | matrix[1][0].set(bitvec(1,0),u01*norm); 102 | matrix[1][1].set(bitvec(1,1),u11*norm); 103 | } 104 | 105 | /* opU2 */ 106 | 107 | opU2::opU2(double theta,double delta,double sigma,double tau) 108 | : opMatrix(1) { 109 | complx d,s,t; 110 | double cs,si; 111 | 112 | matrix[0]=new term[3]; 113 | matrix[1]=new term[3]; 114 | cs=cos(theta/2); 115 | si=sin(theta/2); 116 | d=exp(complx(0,delta)); 117 | s=exp(complx(0,sigma)); 118 | t=exp(complx(0,tau)); 119 | matrix[0][0].set(bitvec(1,0),d*s*t*cs); 120 | matrix[0][1].set(bitvec(1,1),-d*conj(s)*t*si); 121 | matrix[1][0].set(bitvec(1,0),conj(d)*conj(s)*t*si); 122 | matrix[1][1].set(bitvec(1,1),d*conj(s)*conj(t)*cs); 123 | } 124 | 125 | /* opIdentity */ 126 | 127 | void opIdentity::apply(quState& qs) const { } 128 | 129 | void opIdentity::addterms(const terminfo& ti) const { } 130 | 131 | opOperator *opIdentity::newclone() const { 132 | return new opIdentity(bits()); 133 | } 134 | 135 | /* opSwap */ 136 | 137 | void opSwap::addterms(const terminfo& ti) const { 138 | bitvec v,w; 139 | 140 | v=ti.mapterm.vect(); 141 | w=v.getbits(offs1,len); 142 | v.setbits(offs1,v.getbits(offs2,len)); 143 | v.setbits(offs2,w); 144 | ti.pqs->opadd(ti.frame | ti.pqs->unmap(v),ti.mapterm.ampl()); 145 | } 146 | 147 | opOperator *opSwap::newclone() const { 148 | return new opSwap(bits(),len,offs1,offs2); 149 | } 150 | 151 | /* opPermutation */ 152 | 153 | opPermutation::opPermutation(int n) : opElementary(n) { 154 | QC_CHECK(bits()<=BPW); 155 | len=1<opadd(ti.frame | ti.pqs->unmap(perm[w].vect()),z*perm[w].ampl()); 179 | } 180 | 181 | opOperator *opPermutation::newclone() const { 182 | return new opPermutation(bits(),perm); 183 | } 184 | 185 | /* opFunction */ 186 | 187 | void opFunction::addterms(const terminfo& ti) const { 188 | term t; 189 | bitvec v,w; 190 | //QC_CHECK(zero(ti.mapterm.vect().getbits(_arg,_fct))); 191 | 192 | v=ti.mapterm.vect().getbits(0,_arg); 193 | w=ti.mapterm.vect().getbits(_arg,_fct); 194 | t=funct(v); 195 | w^=t.vect(); 196 | ti.pqs->opadd(ti.frame|ti.pqs->unmap(v+w),ti.mapterm.ampl()*t.ampl()); 197 | } 198 | 199 | /* opEXPN */ 200 | 201 | term opEXPN::funct(const bitvec& v) const { 202 | word a,y,u; 203 | int i; 204 | 205 | a=v.getword(); y=1; u=_x; 206 | for(i=0;iopadd(ti.frame|ti.pqs->unmap(t.vect()),ti.mapterm.ampl()*t.ampl()); 225 | } 226 | 227 | /* opCNot */ 228 | 229 | void opCNot::apply(quState& qs) const { 230 | int i,n; 231 | bitvec m,me,mo; 232 | term t; 233 | 234 | if(!qs.mapbits()) return; 235 | qs.opbegin(); 236 | m=bitvec(bits()); 237 | for(i=0;iapply(qs); 354 | outer->apply(qs); 355 | } 356 | 357 | opOperator *opComposition::newclone() const { 358 | return new opComposition(*inner,*outer); 359 | } 360 | 361 | opComposition::~opComposition() { 362 | if(inner) qc_delete(inner); 363 | if(outer) qc_delete(outer); 364 | } 365 | 366 | /* opEmbedded */ 367 | 368 | void opEmbedded::apply(quState& qs) const { 369 | quState *pqs; 370 | 371 | if(!qs.mapbits()) return; 372 | pqs=qs.newsubstring(_op->bits(),_offs); 373 | _op->apply(*pqs); 374 | if(!pqs->isbasestate()) qc_delete(pqs); 375 | } 376 | 377 | opOperator *opEmbedded::newclone() const { 378 | return new opEmbedded(bits(),_offs,*_op); 379 | } 380 | 381 | opEmbedded::~opEmbedded() { 382 | if(_op) delete _op; 383 | } 384 | 385 | /* opVar */ 386 | 387 | void opVar::apply(quState& qs) const { 388 | if(_op) _op->apply(qs); 389 | } 390 | 391 | opOperator *opVar::newclone() const { 392 | if(_op) return _op->newclone(); else return new opVar(); 393 | } 394 | 395 | opVar::~opVar() { 396 | if(_op) delete _op; 397 | } 398 | 399 | -------------------------------------------------------------------------------- /qc/shor.cc: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "operator.h" 20 | 21 | extern char *optarg; 22 | extern int optind; 23 | 24 | // global variables 25 | 26 | int seed=time(0); // random seed value 27 | int quiet=0; // quiet mode 28 | int verbose=0; // verbose mode 29 | int show=0; // show state spectrums 30 | int dump=0; // dump quantum state 31 | int maxtries=3; // max. number of selections 32 | int maxgates=-1; // max. number of cond. phase gates per bit in FFT 33 | int iter=0; // total number of tries 34 | 35 | 36 | // returns 0 and sets *a and *b if n = (*a) * (*b) 37 | // returns 1 if n is a prime number 38 | 39 | int factorize(word n,word *a,word *b) { 40 | word i,m; 41 | 42 | m=(word)ceil(sqrt((double)n)); 43 | for(i=2;i<=m;i++) { 44 | if(n%i==0) { 45 | *a=i; 46 | *b=n/i; 47 | return 0; 48 | }; 49 | }; 50 | return 1; 51 | } 52 | 53 | // returns 1 if p is a power of b and 0 otherwise 54 | 55 | int testpower(word p,word b) { 56 | if(pa) return gcd(b,a); 79 | return a%b ? gcd(a,a%b) : b; 80 | } 81 | 82 | // returns a random number 1 < r < (n-1) coprime to n 83 | 84 | int randcoprime(int n) { 85 | int x; 86 | 87 | while(1) { 88 | x=qc_lrand()%(n-3)+2; 89 | if(gcd(x,n)==1) return x; 90 | } 91 | } 92 | 93 | // finds the best rational approximation (*p)/(*q) to x with 94 | // denominator < qmax and sets *p and *q accordingly. 95 | 96 | void approx(double x,word qmax,word *p,word *q) { 97 | word p0,p1,p2; 98 | word q0,q1,q2; 99 | word a; 100 | double y,z,e; 101 | 102 | e=1.0/(2.0*(double)qmax*(double)qmax); 103 | y=x; a=(int)floor(y); 104 | p0=1; p1=a; 105 | q0=0; q1=1; 106 | 107 | while(1) { 108 | z=y-floor(y); 109 | if(zqmax) break; 115 | p0=p1; p1=p2; 116 | q0=q1; q1=q2; 117 | }; 118 | *p=p1; *q=q1; 119 | } 120 | 121 | // performs a fast fourier transformation on qs using 122 | // Coppersmith's algorithm 123 | 124 | opVar opFFT(int n) { 125 | int i,j,m; 126 | opVar op; 127 | 128 | for(i=0;i0) { m=i-maxgates; if(m<0) m=0; } else m=0; 130 | for(j=m;j set random seed value\n"; 142 | cerr << " -t set max. no. of selections from same state.\n"; 143 | cerr << " -g set max. no. of cond. phase gates per bit in FFT.\n"; 144 | cerr << " -q operate quietly, -v verbose output\n"; 145 | } 146 | 147 | // main program 148 | 149 | int main(int argc,char **argv) { 150 | 151 | word number; // number to be factored 152 | word factor; // found factor 153 | int width; // length of N in bits 154 | int starttime; // starttime 155 | 156 | { // reading command line parameters 157 | 158 | int c; 159 | 160 | while(1) { 161 | c=getopt(argc,argv,"s:t:g:qvld"); 162 | if(c<0) break; 163 | switch(c) { 164 | case 's': seed=atoi(optarg); break; 165 | case 't': maxtries=atoi(optarg); break; 166 | case 'g': maxgates=atoi(optarg); break; 167 | case 'q': quiet=1; verbose=0; break; 168 | case 'v': verbose=1; quiet=0; break; 169 | case 'l': show=1; break; 170 | case 'd': dump=1; break; 171 | default: usage(); exit(1); 172 | }; 173 | }; 174 | if(optind!=argc-1 || (number=atoi(argv[optind]))<1 ) { usage(); exit(1); }; 175 | qc_srand(seed); 176 | }; 177 | 178 | { // testing number 179 | 180 | word a,b; 181 | 182 | if(number%2==0) { 183 | cerr << "number must be odd !\n"; 184 | exit(1); 185 | }; 186 | if(factorize(number,&a,&b)) { 187 | cerr << number << " is a prime number !\n"; 188 | exit(1); 189 | }; 190 | if(testpower(b,a)) { 191 | cerr << number << " is a prime power of " << a << " !\n"; 192 | exit(1); 193 | }; 194 | }; 195 | 196 | if(!quiet) { 197 | cout << "factoring " << number << ": random seed = " << seed; 198 | cout << ", tries = " << maxtries; 199 | if(maxgates>=0) cout << ", maxgates = " << maxgates; 200 | cout << ".\n"; 201 | }; 202 | 203 | cout.setf(ios::fixed,ios::floatfield); 204 | cout.precision(4); 205 | 206 | starttime=time(0); 207 | width=duallog(number); 208 | if(verbose) cout << "allocating " << (3*width) << " quBits with " << 209 | (1<<(2*width)) << " terms.\n"; 210 | 211 | { // Shors's algorithm 212 | 213 | int nreg1=2*width,nreg2=width; 214 | quBaseState qubase(nreg1+nreg2,1<\n"; 229 | 230 | qubase.reset(); // reseting state 231 | 232 | if(!quiet) cout << "FFT: performing 1st fourier transformation.\n"; 233 | 234 | opFFT(nreg1)(reg1); // 1st fourier transformaion 235 | 236 | x=randcoprime(number); // selecting random x 237 | 238 | if(!quiet) cout << "EXPN: trying x = " << x << ". |a,0> --> |a," << 239 | x << "^a mod " << number << ">\n"; 240 | 241 | opEXPN(nreg1,nreg2,x,number)(qubase); // modular exponentiation 242 | 243 | mreg2=reg2.measure().getword(); // measure 2nd register 244 | 245 | if(!quiet) cout << "MEASURE: 2nd register: |*," << mreg2 << ">\n"; 246 | if(!quiet) cout << "FFT: performing 2nd fourier transformation.\n"; 247 | 248 | opFFT(nreg1)(reg1); // 2nd fourier transformation 249 | 250 | qmax=1<\n"; 259 | tries++; 260 | iter++; 261 | if(mreg1==0) { 262 | if(!quiet) cout << " " << "measured zero in 1st register. "; 263 | if(tries "; 280 | if(!quiet) cout << "odd period " << q << ". "; 281 | if(2*q1 && (factor=gcd(number,a))>1) break; 305 | if(b>1 && (factor=gcd(number,b))>1) break; 306 | 307 | if(!quiet) cout << " " << a << " and " << b << 308 | " have no common factors with " << number << ". "; 309 | 310 | if(tries, 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #ifndef _BITVEC_H 16 | #define _BITVEC_H 1 17 | 18 | #pragma interface 19 | 20 | #include 21 | 22 | using namespace std; 23 | 24 | #define WORDTYPE unsigned long 25 | #define BPW ((int)(8*sizeof(WORDTYPE))) 26 | #define LDBPW (BPW==16 ? 4 : (BPW==32 ? 5 : (BPW==64 ? 6 : 7))) 27 | #define UBITS (~(BPW-1)) 28 | #define DBITS (BPW-1) 29 | 30 | #define MASK(l) ((l)>=BPW ? (~0) : ((1<<(l))-1)) 31 | #define WORDS(l) (((l)+BPW-1)>>LDBPW) 32 | 33 | extern char* qc_check_txt; 34 | extern char* qc_check_msg; 35 | extern char* qc_delete_txt; 36 | extern char* qc_delarray_txt; 37 | extern char* qc_del_msg; 38 | 39 | #define SEGFAULT while(*((int*)0)) 40 | 41 | #ifdef QC_DEBUG 42 | #define QC_WHERE " in " __FILE__ ":" << __LINE__ << "\n" 43 | #define QC_CHECK(cond) if(!(cond)) { \ 44 | std::cerr << qc_check_txt << #cond QC_WHERE << qc_check_msg; \ 45 | SEGFAULT; \ 46 | } 47 | #define DEBUG(d) d 48 | #define qc_delete(p) { \ 49 | if(!p) { \ 50 | std::cerr << qc_delete_txt << QC_WHERE << qc_del_msg; \ 51 | } else { delete p; p=0; } \ 52 | } 53 | #define qc_delarray(p) { \ 54 | if(!p) { \ 55 | std::cerr << qc_delarray_txt << QC_WHERE << qc_del_msg; \ 56 | } else { delete[] p; p=0; } \ 57 | } 58 | #else 59 | #define QC_CHECK(cond) 60 | #define DEBUG(d) 61 | #define qc_delete(p) { if(p) { delete p; p=0; } } 62 | #define qc_delarray(p) { if(p) { delete[] p; p=0; } } 63 | #endif 64 | 65 | typedef WORDTYPE word; 66 | 67 | DEBUG( extern int nbitvecs; ) 68 | 69 | class bitvec { 70 | int len; 71 | union { 72 | word *pvec; 73 | word vec; 74 | }; 75 | void l_bitvec(word v=0); 76 | void l_bitvec(const bitvec& v); 77 | void l_append(const bitvec& v); 78 | bitvec l_getbits(int i,int l) const; 79 | word l_getword(int i,int l) const; 80 | void l_setbits(int i,int l,word v); 81 | void l_setbits(int i,const bitvec& v); 82 | public: 83 | bitvec(int l=0, word v=0); 84 | bitvec(const bitvec& v); 85 | ~bitvec(); 86 | void setlen(int l); 87 | bitvec& operator = (word v); 88 | bitvec& operator = (const bitvec& v); 89 | bitvec& operator += (const bitvec& v); 90 | int operator [] (int i) const; 91 | int length() const; 92 | bitvec getbits(int i,int l) const; 93 | word getword(int i,int l) const; 94 | word getword() const; 95 | void setbit(int i,int b=1); 96 | void setbits(int i,int l,word v=~0); 97 | void setbits(int i,const bitvec& v); 98 | // bitvec operator + (const bitvec& v) const; 99 | int testeq(const bitvec& v) const; 100 | int testzero() const; 101 | bitvec& operator &= (const bitvec& v); 102 | bitvec& operator |= (const bitvec& v); 103 | bitvec& operator ^= (const bitvec& v); 104 | 105 | word hashfunct() const; 106 | int testless(const bitvec& v) const; 107 | bitvec& qnot(); 108 | void push(int b); 109 | int pop(); 110 | int top() const; 111 | int nset() const; 112 | bitvec& swap(); 113 | }; 114 | 115 | /* inline members */ 116 | 117 | inline bitvec::bitvec(int l, word v) { 118 | len=l; 119 | if(l<=BPW) vec=v&MASK(l); else l_bitvec(v); 120 | DEBUG( nbitvecs++; ) 121 | } 122 | 123 | inline bitvec::bitvec(const bitvec& v) { 124 | len=v.len; 125 | if(len<=BPW) vec=v.vec; else l_bitvec(v); 126 | DEBUG( nbitvecs++; ) 127 | } 128 | 129 | inline bitvec::~bitvec() { 130 | if(len>BPW) qc_delarray(pvec); 131 | DEBUG( nbitvecs--; ) 132 | } 133 | 134 | inline void bitvec::setlen(int l) { 135 | QC_CHECK(l>=0); 136 | if(WORDS(l)!=WORDS(len)) { 137 | if(len>BPW) qc_delarray(pvec); 138 | if(l>BPW) pvec=new word[WORDS(l)]; 139 | }; 140 | len=l; 141 | } 142 | 143 | inline bitvec& bitvec::operator = (word v) { 144 | int i; 145 | 146 | if(len<=BPW) { 147 | vec=v; 148 | } else { 149 | pvec[0]=v; 150 | for(i=1;i>i)&1 : (pvec[i>>LDBPW]>>(i&DBITS))&1; 180 | } 181 | 182 | inline int bitvec::length() const { return len; } 183 | 184 | inline bitvec bitvec::getbits(int i,int l) const { 185 | QC_CHECK(i+l<=len); 186 | return len<=BPW ? bitvec(l,vec>>i) : l_getbits(i,l); 187 | } 188 | 189 | inline word bitvec::getword(int i,int l) const { 190 | QC_CHECK(i+l<=len); 191 | QC_CHECK(l<=BPW); 192 | return len<=BPW ? (vec>>i)&MASK(l) : l_getword(i,l); 193 | } 194 | 195 | inline word bitvec::getword() const { 196 | QC_CHECK(len<=BPW); 197 | 198 | return vec; 199 | } 200 | 201 | inline void bitvec::setbit(int i,int b) { 202 | QC_CHECK(i>LDBPW] |= (1<<(i&DBITS)); 208 | else 209 | pvec[i>>LDBPW] &= ~(1<<(i&DBITS)); 210 | }; 211 | } 212 | 213 | inline void bitvec::setbits(int i,int l,word v) { 214 | QC_CHECK(i+l<=len); 215 | QC_CHECK(l<=BPW); 216 | if(len<=BPW) { 217 | vec&=~(MASK(l)<1) { 321 | int i; 322 | word *p=new word[WORDS(len-1)]; 323 | for(i=0;i (const bitvec& a,const bitvec& b) { return b.testless(a); } 352 | 353 | inline int operator <= (const bitvec& a,const bitvec& b) { return !b.testless(a); } 354 | 355 | inline int operator >= (const bitvec& a,const bitvec& b) { return !a.testless(b); } 356 | 357 | inline bitvec operator + (const bitvec& a,const bitvec& b) { 358 | bitvec v(a); 359 | v+=b; 360 | return v; 361 | } 362 | 363 | inline bitvec operator ~ (const bitvec& a) { 364 | bitvec v(a); 365 | 366 | v.qnot(); 367 | return v; 368 | } 369 | 370 | inline bitvec operator & (const bitvec& a,const bitvec& b) { 371 | bitvec v(a); 372 | 373 | v&=b; 374 | return v; 375 | } 376 | 377 | inline bitvec operator | (const bitvec& a,const bitvec& b) { 378 | bitvec v(a); 379 | 380 | v|=b; 381 | return v; 382 | } 383 | 384 | inline bitvec operator ^ (const bitvec& a,const bitvec& b) { 385 | bitvec v(a); 386 | 387 | v^=b; 388 | return v; 389 | } 390 | 391 | inline int zero(const bitvec& v) { 392 | return v.testzero(); 393 | } 394 | 395 | inline bitvec swap(const bitvec& v) { 396 | bitvec s=v; 397 | s.swap(); 398 | return s; 399 | } 400 | 401 | /* other functions */ 402 | 403 | #define BITVEC_FORMAT_BIN 0 404 | #define BITVEC_FORMAT_HEX 1 405 | #define BITVEC_FORMAT_PLAIN 0 406 | #define BITVEC_FORMAT_KET 2 407 | 408 | extern int bitvec_format; 409 | extern int bitvec_min_width; 410 | 411 | ostream& operator << (ostream& s,const bitvec& v); 412 | istream& operator >> (istream& s,bitvec& v); 413 | 414 | #endif 415 | 416 | -------------------------------------------------------------------------------- /qcl.y: -------------------------------------------------------------------------------- 1 | %{ 2 | 3 | /********************************************************************** 4 | 5 | This file is part of the Quantum Computation Language QCL. 6 | 7 | (c) Copyright by Bernhard Oemer , 1998 8 | 9 | This program comes without any warranty; without even the implied 10 | warranty of merchantability or fitness for any particular purpose. 11 | 12 | This program is free software under the terms of the 13 | GNU General Public Licence (GPL) version 2 or higher 14 | 15 | ************************************************************************/ 16 | 17 | 18 | #include 19 | #include "syntax.h" 20 | #include "parse.h" 21 | 22 | extern int yyerror (char *s); /* Called by yyparse on error */ 23 | extern objlist *yyObjList; 24 | 25 | extern int yylex(); 26 | 27 | #define YYERROR_VERBOSE 1 28 | 29 | %} 30 | 31 | 32 | %union { 33 | objlist* OBJLIST; 34 | BaseType TYPE; 35 | int TENSOR; 36 | ObjType OBJTYPE; 37 | tId* ID; 38 | sObject* OBJ; 39 | sConst* CONST; 40 | sExpr* EXPR; 41 | sExprList* EXPRLIST; 42 | sStmt* STMT; 43 | sStmtList* STMTLIST; 44 | sDef* DEF; 45 | sDefList* DEFLIST; 46 | string* STRING; 47 | } 48 | 49 | %type objlist 50 | %type obj eof 51 | %type expr 52 | %type exprlist 53 | %type stmt 54 | %type stmtlist block bodystm 55 | %type arg constdef vardef functdef quopdef procdef qufundef 56 | %type deflist arglist bodydef 57 | 58 | %token tokTYPE 400 59 | %token tokTENSOR 401 60 | %token tokID 402 61 | %token tokCONS 403 62 | %token tokBASEFUNCT 404 63 | %token tokLISTFUNCT 405 64 | %token tokINCLUDE 406 65 | %token tokSET 407 66 | %token tokIDCALL 408 67 | 68 | %token tokCONST 500 69 | %token tokCOND 501 70 | %token tokEXTERN 502 71 | %token tokOP 503 72 | %token tokPROC 504 73 | %token tokQUFUN 505 74 | %token tokFOR 506 75 | %token tokTO 507 76 | %token tokWHILE 508 77 | %token tokUNTIL 509 78 | %token tokBREAK 510 79 | %token tokRETURN 511 80 | %token tokIF 512 81 | %token tokELSE 513 82 | %token tokRANGE_LENGTH 514 83 | %token tokRANGE_END 515 84 | %token tokSTEP 516 85 | %token tokINPUT 517 86 | %token tokPRINT 518 87 | %token tokEXIT 519 88 | %token tokMEASURE 520 89 | %token tokRESET 521 90 | 91 | %token tokDUMP 601 92 | %token tokINSPECT 602 93 | %token tokLOAD 603 94 | %token tokSAVE 604 95 | %token tokPLOT 605 96 | %token tokSHELL 606 97 | 98 | %token tokEOF 900 99 | %token tokERROR 901 100 | 101 | 102 | %nonassoc tokTRANS tokINVTRANS tokSWAP 103 | %left tokOR tokXOR 104 | %left tokAND 105 | %left tokNOT 106 | %nonassoc tokEQ tokLEEQ tokGREQ tokNOTEQ '<' '>' 107 | %left '+' '-' '&' 108 | %left tokMOD 109 | %left '*' '/' 110 | %left tokNEG 111 | %left '^' 112 | %left '#' 113 | 114 | %% 115 | 116 | objlist: obj { $$ = YYNEW(objlist); YYTRY($$->push_back($1)); } 117 | | eof { yyObjList = $$ = YYNEW(objlist); YYACCEPT; } 118 | | objlist obj { YYTRY($1->push_back($2)); $$=$1; } 119 | | objlist eof { yyObjList = $$ = $1; YYACCEPT; } 120 | ; 121 | 122 | eof: tokEOF { $$ = 0; } 123 | | ';' eof { $$ = 0; } 124 | ; 125 | 126 | obj: functdef { $$ = $1; } 127 | | quopdef { $$ = $1; } 128 | | qufundef { $$ = $1; } 129 | | procdef { $$ = $1; } 130 | | vardef { $$ = $1; } 131 | | constdef { $$ = $1; } 132 | | stmt { $$ = $1; } 133 | | block { $$ = $1; } 134 | | tokINCLUDE ';'{ $$ = YYNEW(sInclude(*$1)); } 135 | | ';' obj { $$ = $2; } 136 | ; 137 | 138 | functdef: tokTYPE tokIDCALL arglist ')' bodydef bodystm { 139 | $$ = YYNEW(sFunctDef(tType($1),$2,$3,$5,$6)); } 140 | | tokTYPE tokTENSOR tokIDCALL arglist ')' bodydef bodystm { 141 | $$ = YYNEW(sFunctDef(tType($1,$2),$3,$4,$6,$7)); } 142 | ; 143 | 144 | quopdef: tokOP tokIDCALL arglist ')' bodydef bodystm { 145 | $$ = YYNEW(sQuOpDef($2,$3,$5,$6)); } 146 | | tokEXTERN tokOP tokIDCALL arglist ')' ';' { 147 | $$ = YYNEW(sQuOpDef($3,$4,0,0,0,1)); } 148 | | tokCOND tokOP tokIDCALL arglist ')' bodydef bodystm { 149 | $$ = YYNEW(sQuOpDef($3,$4,$6,$7,1)); } 150 | | tokEXTERN tokCOND tokOP tokIDCALL arglist ')' ';' { 151 | $$ = YYNEW(sQuOpDef($4,$5,0,0,1,1)); } 152 | ; 153 | 154 | qufundef: tokQUFUN tokIDCALL arglist ')' bodydef bodystm { 155 | $$ = YYNEW(sQuFunDef($2,$3,$5,$6)); } 156 | | tokEXTERN tokQUFUN tokIDCALL arglist ')' ';' { 157 | $$ = YYNEW(sQuFunDef($3,$4,0,0,0,1)); } 158 | | tokCOND tokQUFUN tokIDCALL arglist ')' bodydef bodystm { 159 | $$ = YYNEW(sQuFunDef($3,$4,$6,$7,1)); } 160 | | tokEXTERN tokCOND tokQUFUN tokIDCALL arglist ')' ';' { 161 | $$ = YYNEW(sQuFunDef($4,$5,0,0,1,1)); } 162 | | tokQUFUN tokOP tokIDCALL arglist ')' bodydef bodystm { 163 | $$ = YYNEW(sQuFunDef($3,$4,$6,$7)); 164 | YYTRY($$->setFlag(flagFUNOP)); } 165 | | tokCOND tokQUFUN tokOP tokIDCALL arglist ')' bodydef bodystm { 166 | $$ = YYNEW(sQuFunDef($4,$5,$7,$8,1)); 167 | YYTRY($$->setFlag(flagFUNOP)); } 168 | ; 169 | 170 | procdef: tokPROC tokIDCALL arglist ')' bodydef bodystm { 171 | $$ = YYNEW(sProcDef($2,$3,$5,$6)); } 172 | | tokPROC tokIDCALL ')' bodydef bodystm { 173 | $$ = YYNEW(sProcDef($2,new sDefList(),$4,$5)); } 174 | ; 175 | 176 | vardef: tokTYPE tokID ';' { $$ = YYNEW(sVarDef(tType($1),$2)); } 177 | | tokTYPE tokID '[' expr ']' ';' { $$ = YYNEW(sVarDef(tType($1),$2,$4,0)); } 178 | | tokTYPE tokTENSOR tokID '[' expr ']' ';' { $$ = YYNEW(sVarDef(tType($1,$2),$3,$5,0)); } 179 | | tokTYPE tokID '=' expr ';' { $$ = YYNEW(sVarDef(tType($1),$2,0,$4)); } 180 | | tokTYPE tokTENSOR tokID '=' expr ';' { $$ = YYNEW(sVarDef(tType($1,$2),$3,0,$5)); } 181 | | tokTYPE tokID '=' tokCOND ';' { 182 | $$ = YYNEW(sVarDef(tType($1),$2,0,new sVar(new tId(CONDID)))); 183 | YYTRY($$->setFlag(flagCONDDEF)); 184 | } 185 | ; 186 | 187 | constdef: tokCONST tokID '=' expr ';' { $$ = YYNEW(sConstDef($2,$4)); }; 188 | 189 | block: '{' stmtlist '}' { $$ = $2; } 190 | | '{' '}' { $$ = YYNEW(sStmtList()); } 191 | ; 192 | 193 | bodydef: '{' deflist { $$ = $2; } 194 | | '{' { $$ = YYNEW(sDefList()); } 195 | ; 196 | 197 | bodystm: stmtlist '}' { $$ = $1; } 198 | | '}' { $$ = YYNEW(sStmtList()); } 199 | ; 200 | 201 | deflist: vardef { $$ = YYNEW(sDefList()); YYTRY($$->append($1)); } 202 | | constdef { $$ = YYNEW(sDefList()); YYTRY($$->append($1)); } 203 | | deflist vardef { YYTRY($1->append($2)); $$=$1; } 204 | | deflist constdef { YYTRY($1->append($2)); $$=$1; } 205 | ; 206 | 207 | arg: tokTYPE tokID { $$ = YYNEW(sArgDef(tType($1),$2)); } 208 | | tokTYPE tokTENSOR tokID { $$ = YYNEW(sArgDef(tType($1,$2),$3)); } 209 | ; 210 | 211 | arglist: arg { $$ = YYNEW(sDefList()); YYTRY($$->append($1)); } 212 | | arglist ',' arg { YYTRY($1->append($3)); $$=$1; } 213 | ; 214 | 215 | stmtlist: stmt { $$ = YYNEW(sStmtList()); YYTRY($$->append($1)); } 216 | | stmtlist stmt { YYTRY($1->append($2)); $$=$1; } 217 | ; 218 | 219 | stmt: tokIDCALL exprlist ')' ';' { $$ = YYNEW(sCall($1,$2)); } 220 | | tokIDCALL ')' ';' { $$ = YYNEW(sCall($1,new sExprList())); } 221 | | '!' tokIDCALL exprlist ')' ';' { $$ = YYNEW(sCall($2,$3,1)); } 222 | | tokID '=' expr ';' { $$ = YYNEW(sAssign(new sVar($1),$3)); } 223 | | tokID '[' exprlist ']' '=' expr ';' { $$ = YYNEW(sAssign(new sVar($1),$6,$3)); } 224 | | expr tokSWAP expr ';' { $$ = YYNEW(sCall(new tId(SWAPID),new sExprList($1,$3))); } 225 | | expr tokTRANS expr ';' { $$ = YYNEW(sCall(new tId(FANOUTID),new sExprList($1,$3))); } 226 | | expr tokINVTRANS expr ';' { $$ = YYNEW(sCall(new tId(FANOUTID),new sExprList($1,$3),1)); } 227 | | tokFOR tokID '=' expr tokTO expr block { $$ = YYNEW(sFor(new sVar($2),$4,$6,$7)); } 228 | | tokFOR tokID '=' expr tokTO expr tokSTEP expr block { $$ = YYNEW(sFor(new sVar($2),$4,$6,$9,$8)); } 229 | | tokIF expr block { $$ = YYNEW(sIf($2,$3)); } 230 | | tokIF expr block tokELSE block { $$ = YYNEW(sIf($2,$3,$5)); } 231 | | tokWHILE expr block { $$ = YYNEW(sWhile($2,$3)); } 232 | | block tokUNTIL expr ';' { $$ = YYNEW(sUntil($3,$1)); } 233 | | tokBREAK ';' { $$ = YYNEW(sBreak()); } 234 | | tokRETURN expr ';' { $$ = YYNEW(sReturn($2)); } 235 | | tokINPUT tokID ';' { $$ = YYNEW(sInput(new sVar($2),0)); } 236 | | tokINPUT expr ',' tokID ';' { $$ = YYNEW(sInput(new sVar($4),$2)); } 237 | | tokPRINT ';' { $$ = YYNEW(sPrint(new sExprList())); } 238 | | tokPRINT exprlist ';' { $$ = YYNEW(sPrint($2)); } 239 | | tokEXIT ';' { $$ = YYNEW(sExit(0)); } 240 | | tokEXIT expr ';' { $$ = YYNEW(sExit($2)); } 241 | | tokMEASURE expr ';' { $$ = YYNEW(sMeasure($2,0)); } 242 | | tokMEASURE expr ',' tokID ';' { $$ = YYNEW(sMeasure($2,new sVar($4))); } 243 | | tokRESET ';' { $$ = YYNEW(sReset()); } 244 | | tokDUMP ';' { $$ = YYNEW(sDump(0)); } 245 | | tokDUMP expr ';' { $$ = YYNEW(sDump($2)); } 246 | | tokPLOT ';' { $$ = YYNEW(sPlot()); } 247 | | tokPLOT expr ';' { $$ = YYNEW(sPlot($2)); } 248 | | tokPLOT expr ',' expr ';' { $$ = YYNEW(sPlot($2,$4)); } 249 | | tokINSPECT ';' { $$ = YYNEW(sInspect(0)); } 250 | | tokINSPECT exprlist ';' { $$ = YYNEW(sInspect($2)); } 251 | | tokLOAD ';' { $$ = YYNEW(sLoad(0)); } 252 | | tokLOAD expr ';' { $$ = YYNEW(sLoad($2)); } 253 | | tokSAVE ';' { $$ = YYNEW(sSave(0)); } 254 | | tokSAVE expr ';' { $$ = YYNEW(sSave($2)); } 255 | | tokSHELL ';' { $$ = YYNEW(sShell()); } 256 | | tokSET ';' { $$ = YYNEW(sSet(*$1,0)); } 257 | | tokSET expr ';' { $$ = YYNEW(sSet(*$1,$2)); } 258 | ; 259 | 260 | exprlist: expr { $$ = YYNEW(sExprList()); YYTRY($$->append($1)); } 261 | | exprlist ',' expr { YYTRY($1->append($3)); $$=$1; } 262 | ; 263 | 264 | expr: tokCONS { $$ = $1; } 265 | | tokID { $$ = YYNEW(sVar($1)); } 266 | | tokID '[' exprlist ']' { $$ = YYNEW(sSubscript(new sVar($1),$3)); } 267 | | tokID '[' expr tokRANGE_LENGTH expr ']' { $$ = YYNEW(sSubRange(new sVar($1),$3,$5,SUBRANGE_LENGTH)); } 268 | | tokID '[' expr tokRANGE_END expr ']' { $$ = YYNEW(sSubRange(new sVar($1),$3,$5,SUBRANGE_END)); } 269 | | tokIDCALL exprlist ')' { $$ = YYNEW(sFunctCall($1,$2)); } 270 | | '-' expr %prec tokNEG { $$ = YYNEW(sNeg($2)); } 271 | | tokNOT expr { $$ = YYNEW(sNot($2)); } 272 | | '#' expr { $$ = YYNEW(sLength($2)); } 273 | | expr tokOR expr { $$ = YYNEW(sOr($1,$3)); } 274 | | expr tokXOR expr { $$ = YYNEW(sXor($1,$3)); } 275 | | expr tokAND expr { $$ = YYNEW(sAnd($1,$3)); } 276 | | expr tokEQ expr { $$ = YYNEW(sEqual($1,$3)); } 277 | | expr tokLEEQ expr { $$ = YYNEW(sLeEq($1,$3)); } 278 | | expr tokGREQ expr { $$ = YYNEW(sLeEq($3,$1)); } 279 | | expr tokNOTEQ expr { $$ = YYNEW(sNotEq($1,$3)); } 280 | | expr '<' expr { $$ = YYNEW(sLess($1,$3)); } 281 | | expr '>' expr { $$ = YYNEW(sLess($3,$1)); } 282 | | expr '+' expr { $$ = YYNEW(sAdd($1,$3)); } 283 | | expr '-' expr { $$ = YYNEW(sSub($1,$3)); } 284 | | expr '&' expr { $$ = YYNEW(sConcat($1,$3)); } 285 | | expr tokMOD expr { $$ = YYNEW(sMod($1,$3)); } 286 | | expr '*' expr { $$ = YYNEW(sMult($1,$3)); } 287 | | expr '/' expr { $$ = YYNEW(sDiv($1,$3)); } 288 | | expr '^' expr { $$ = YYNEW(sPow($1,$3)); } 289 | | '(' expr ')' { $$ = $2; } 290 | | tokBASEFUNCT expr ')' { $$ = YYNEW(sBaseFunct($1,$2)); } 291 | | tokLISTFUNCT exprlist ')' { $$ = YYNEW(sListFunct($1,$2)); } 292 | | tokLISTFUNCT ')' { $$ = YYNEW(sListFunct($1,new sExprList())); } 293 | ; 294 | 295 | -------------------------------------------------------------------------------- /qc/qustates.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | 3 | This file is part of the Quantum Computation Library (QCLIB). 4 | 5 | (c) Copyright by Bernhard Oemer , 1996-1998 6 | 7 | This program comes without any warranty; without even the implied 8 | warranty of merchantability or fitness for any particular purpose. 9 | 10 | This program is free software under the terms of the 11 | GNU General Public Licence (GPL) version 2 or higher 12 | 13 | ************************************************************************/ 14 | 15 | #ifndef _QUSTATES_H 16 | #define _QUSTATES_H 1 17 | 18 | #pragma interface 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "bitvec.h" 25 | #include "terms.h" 26 | 27 | #define EPSILON (1E-10) 28 | 29 | long qc_lrand(); 30 | double qc_drand(); 31 | void qc_srand(long seed); 32 | 33 | 34 | DEBUG( extern int nstates; ) 35 | 36 | typedef map state_map; 37 | typedef map spectrum_map; 38 | typedef state_map::const_iterator state_iter; 39 | typedef spectrum_map::const_iterator spectrum_iter; 40 | typedef state_map::const_reverse_iterator state_riter; 41 | typedef spectrum_map::const_reverse_iterator spectrum_riter; 42 | 43 | class quBaseState; 44 | 45 | typedef const quBaseState* baseid; 46 | 47 | class quState { 48 | int _mapbits; 49 | public: 50 | quState(int bits); 51 | virtual ~quState(); 52 | 53 | int mapbits() const; 54 | virtual bitvec mapmask() const; 55 | bitvec measure(); 56 | void opterm(const term& t); 57 | void printvect(ostream& s,const bitvec& v) const; 58 | quState* newclone(); 59 | 60 | bitvec select() const; 61 | void reduce(const bitvec& v); 62 | void normalize(double epsilon=EPSILON); 63 | 64 | virtual void reset(const bitvec& v=bitvec(0))=0; 65 | virtual baseid base() const=0; 66 | virtual int basebits() const=0; 67 | virtual quState* newsubstring(int bits,int offs)=0; 68 | virtual int isbasestate() const=0; 69 | virtual double prob(const bitvec& v) const=0; 70 | virtual int baseterms() const=0; 71 | virtual const term& baseterm(int i) const=0; 72 | virtual void opbegin()=0; 73 | virtual void opadd(const bitvec& v,const complx& z)=0; 74 | void opadd(const term& t) { opadd(t.vect(),t.ampl()); }; 75 | virtual void opend()=0; 76 | virtual bitvec map(const bitvec& v) const=0; 77 | virtual bitvec unmap(const bitvec& v) const=0; 78 | virtual int mapindex(int i) const=0; 79 | int operator [] (int i) const { return mapindex(i); }; 80 | virtual void _printvect(ostream& s,const bitvec& v) const; 81 | state_map *new_state_map(double epsilon=EPSILON) const; 82 | spectrum_map *new_spectrum_map(double epsilon=EPSILON) const; 83 | 84 | friend class quVar; 85 | }; 86 | 87 | class quBaseState : public quState { 88 | termlist *pterms; 89 | termlist *ptermbuf; 90 | public: 91 | quBaseState(int bits,int buflen=256); 92 | virtual ~quBaseState(); 93 | 94 | virtual void reset(const bitvec& v=bitvec(0)); 95 | virtual baseid base() const; 96 | virtual int basebits() const; 97 | virtual quState* newsubstring(int bits,int offs); 98 | virtual int isbasestate() const; 99 | virtual bitvec mapmask() const; 100 | virtual double prob(const bitvec& v) const; 101 | virtual int baseterms() const; 102 | virtual const term& baseterm(int i) const; 103 | virtual void opbegin(); 104 | virtual void opadd(const bitvec& v,const complx& z); 105 | virtual void opend(); 106 | virtual bitvec map(const bitvec& v) const; 107 | virtual bitvec unmap(const bitvec& v) const; 108 | virtual int mapindex(int i) const; 109 | }; 110 | 111 | class quSubState : public quState { 112 | protected: 113 | quState *pbase; 114 | public: 115 | quSubState(int bits); 116 | virtual ~quSubState(); 117 | 118 | virtual void reset(const bitvec& v=bitvec(0)); 119 | virtual baseid base() const; 120 | virtual int basebits() const; 121 | virtual int isbasestate() const; 122 | virtual double prob(const bitvec& v) const; 123 | virtual int baseterms() const; 124 | virtual const term& baseterm(int i) const; 125 | virtual void opbegin(); 126 | virtual void opadd(const bitvec& v,const complx& z); 127 | virtual void opend(); 128 | }; 129 | 130 | class quEmpty : public quSubState { 131 | public: 132 | quEmpty(quState& qs); 133 | virtual double prob(const bitvec& v) const; 134 | virtual void opbegin(); 135 | virtual void opadd(const bitvec& v,const complx& z); 136 | virtual void opend(); 137 | virtual quState* newsubstring(int bits,int offs); 138 | virtual bitvec mapmask() const; 139 | virtual bitvec map(const bitvec& v) const; 140 | virtual bitvec unmap(const bitvec& v) const; 141 | virtual int mapindex(int i) const; 142 | }; 143 | 144 | class quVar : public quSubState { 145 | public: 146 | quVar(); 147 | quVar(quVar& qs); 148 | quVar(quState& qs); 149 | quVar(quState* qs); 150 | quVar& operator = (quVar& qs); 151 | quState& operator = (quState& qs); 152 | 153 | virtual quState* newsubstring(int bits,int offs); 154 | virtual bitvec mapmask() const; 155 | virtual bitvec map(const bitvec& v) const; 156 | virtual bitvec unmap(const bitvec& v) const; 157 | virtual int mapindex(int i) const; 158 | }; 159 | 160 | class quMask : public quSubState { 161 | bitvec _mask; 162 | public: 163 | quMask(quState& qs,bitvec m); 164 | 165 | virtual quState* newsubstring(int bits,int offs); 166 | virtual bitvec mapmask() const; 167 | virtual bitvec map(const bitvec& v) const; 168 | virtual bitvec unmap(const bitvec& v) const; 169 | virtual int mapindex(int i) const; 170 | }; 171 | 172 | class quSwap : public quSubState { 173 | public: 174 | quSwap(quState& qs); 175 | quSwap(quState* qs); 176 | 177 | virtual quState* newsubstring(int bits,int offs); 178 | virtual bitvec mapmask() const; 179 | virtual bitvec map(const bitvec& v) const; 180 | virtual bitvec unmap(const bitvec& v) const; 181 | virtual int mapindex(int i) const; 182 | }; 183 | 184 | class quCombState : public quSubState { 185 | quState *ptail; 186 | quCombState(int bits); 187 | int delflag; 188 | public: 189 | quCombState(quState& head,quState& tail); 190 | quCombState(quState* head,quState* tail,int d=0); 191 | virtual ~quCombState(); 192 | 193 | virtual quState* newsubstring(int bits,int offs); 194 | virtual bitvec mapmask() const; 195 | virtual bitvec map(const bitvec& v) const; 196 | virtual bitvec unmap(const bitvec& v) const; 197 | virtual int mapindex(int i) const; 198 | virtual void _printvect(ostream& s,const bitvec& v) const; 199 | }; 200 | 201 | class quSubString : public quSubState { 202 | int _mapoffs; 203 | public: 204 | quSubString(int bits,int offs,quState& base); 205 | 206 | int mapoffs() const; 207 | 208 | virtual quState* newsubstring(int bits,int offs); 209 | virtual bitvec map(const bitvec& v) const; 210 | virtual bitvec unmap(const bitvec& v) const; 211 | virtual int mapindex(int i) const; 212 | }; 213 | 214 | class quBit : public quSubString { 215 | public: 216 | quBit(int offs,quState& base); 217 | void set(int v); 218 | int get(); 219 | }; 220 | 221 | class quWord : public quSubString { 222 | public: 223 | quWord(int bits,int offs,quState& base); 224 | void set(word v); 225 | word get(); 226 | 227 | virtual quState* newsubstring(int bits,int offs); 228 | virtual void _printvect(ostream& s,const bitvec& v) const; 229 | }; 230 | 231 | /* inline members */ 232 | 233 | /* quState */ 234 | 235 | inline quState::quState(int bits) { 236 | _mapbits=bits; 237 | DEBUG( nstates++; ) 238 | } 239 | 240 | inline int quState::mapbits() const { return _mapbits; } 241 | 242 | inline bitvec quState::measure() { 243 | bitvec v; 244 | 245 | v=select(); 246 | reduce(v); 247 | return v; 248 | } 249 | 250 | inline void quState::opterm(const term& t) { opadd(t.vect(),t.ampl()); } 251 | 252 | inline void quState::printvect(ostream& s,const bitvec& v) const { 253 | s << '|'; 254 | _printvect(s,v); 255 | s << '>'; 256 | } 257 | 258 | inline quState *quState::newclone() { 259 | return newsubstring(mapbits(),0); 260 | } 261 | 262 | /* quBaseState */ 263 | 264 | inline quBaseState::quBaseState(int bits,int buflen) 265 | : quState(bits) { 266 | pterms=new termlist(bits,buflen); 267 | ptermbuf=new termlist(bits,buflen); 268 | reset(); 269 | } 270 | 271 | /* quSubState */ 272 | 273 | inline quSubState::quSubState(int bits) 274 | : quState(bits) { 275 | pbase=0; 276 | } 277 | 278 | /* quEmpty */ 279 | 280 | inline quEmpty::quEmpty(quState& qs) : quSubState(0) { 281 | pbase=(quState*)qs.base(); 282 | } 283 | 284 | /* quMask */ 285 | 286 | inline quMask::quMask(quState& qs,bitvec m) : quSubState(m.nset()) { 287 | QC_CHECK(m.length()==qs.mapbits()); 288 | _mask=m; 289 | pbase=qs.newclone(); 290 | } 291 | 292 | /* quSwap */ 293 | 294 | inline quSwap::quSwap(quState& qs) : quSubState(qs.mapbits()) { 295 | pbase=qs.newclone(); 296 | } 297 | 298 | inline quSwap::quSwap(quState* qs) : quSubState(qs->mapbits()) { 299 | pbase=qs; 300 | } 301 | 302 | /* quVar */ 303 | 304 | inline quVar::quVar() : quSubState(0) { 305 | pbase=0; 306 | } 307 | 308 | inline quVar::quVar(quVar& qs) : quSubState(qs.mapbits()) { 309 | pbase=qs.newclone(); 310 | } 311 | 312 | inline quVar::quVar(quState& qs) : quSubState(qs.mapbits()) { 313 | pbase=qs.newclone(); 314 | } 315 | 316 | inline quVar::quVar(quState* qs) : quSubState(qs->mapbits()) { 317 | pbase=qs; 318 | } 319 | 320 | 321 | inline quVar& quVar::operator = (quVar& qs) { 322 | if(pbase && !pbase->isbasestate()) qc_delete(pbase); 323 | pbase=qs.newclone(); 324 | _mapbits=qs.mapbits(); 325 | return qs; 326 | } 327 | 328 | inline quState& quVar::operator = (quState& qs) { 329 | if(pbase && !pbase->isbasestate()) qc_delete(pbase); 330 | pbase=qs.newclone(); 331 | _mapbits=qs.mapbits(); 332 | return qs; 333 | } 334 | 335 | /* quCombState */ 336 | 337 | inline quCombState::quCombState(quState& head,quState& tail) 338 | : quSubState(head.mapbits()+tail.mapbits()) { 339 | QC_CHECK(head.base()==tail.base()); 340 | QC_CHECK(zero(head.mapmask() & tail.mapmask())); 341 | 342 | delflag=1; 343 | pbase=head.newclone(); 344 | ptail=tail.newclone(); 345 | } 346 | 347 | inline quCombState::quCombState(quState* head,quState* tail,int d) 348 | : quSubState(head->mapbits()+tail->mapbits()) { 349 | QC_CHECK(head->base()==tail->base()); 350 | QC_CHECK(zero(head->mapmask() & tail->mapmask())); 351 | 352 | delflag=d; 353 | pbase=head; 354 | ptail=tail; 355 | } 356 | 357 | inline quCombState::quCombState(int bits) 358 | : quSubState(bits) { 359 | ptail=0; 360 | } 361 | 362 | /* quSubString */ 363 | 364 | inline quSubString::quSubString(int bits,int offs,quState& base) 365 | : quSubState(bits) { 366 | _mapoffs=offs; 367 | pbase=base.newclone(); 368 | } 369 | 370 | inline int quSubString::mapoffs() const { return _mapoffs; } 371 | 372 | /* quBit */ 373 | 374 | inline quBit::quBit(int offs,quState& base) 375 | : quSubString(1,offs,base) {} 376 | 377 | inline void quBit::set(int v) { 378 | reduce(bitvec(1,v!=0)); 379 | } 380 | 381 | inline int quBit::get() { 382 | return !measure().testzero(); 383 | } 384 | 385 | /* quWord */ 386 | 387 | inline quWord::quWord(int bits,int offs,quState& base) 388 | : quSubString(bits,offs,base) { 389 | QC_CHECK(bits<=BPW); 390 | } 391 | 392 | inline void quWord::set(word v) { 393 | reduce(bitvec(mapbits(),v)); 394 | } 395 | 396 | /* other functions */ 397 | 398 | inline quCombState operator / (quState& head,quState& tail) { 399 | return quCombState(head,tail); 400 | } 401 | 402 | 403 | inline word quWord::get() { 404 | return measure().getword(0,mapbits()); 405 | } 406 | 407 | #endif 408 | 409 | --------------------------------------------------------------------------------