Skip to content
This repository
Browse code

Compilable version

  • Loading branch information...
commit 7779e1d0353fad31818fe7af7758fbb9c2649822 1 parent f1ea06a
ckroxigor authored December 06, 2012
45  AUTHORS.txt
... ...
@@ -1,17 +1,28 @@
1  
-Contributors:
2  
-
3  
-[put your names and @mail here]
4  
-Guillaume Raschia <guillaume.raschia@univ-nantes.fr>
5  
-
6  
-
7  
-Parser based on previous work from:
8  
-Xavier Leroy <xavier.leroy@inria.fr>
9  
-Julien Cohen >julien.cohen@univ-nantes.fr> 
10  
-
11  
-
12  
-PostgreSQL connection based on previous work from:
13  
-Alain Frisch <alain.frisch@lexifi.com>
14  
-Markus Mottl <markus.mottl@gmail.com>
15  
-
16  
-
17  
-Current maintainters:
  1
+Contributors:
  2
+Jaume Ferrarons <ckroxigor@gmail.com>
  3
+Grigory Antipov <antigregory@gmail.com>
  4
+Sandra Pietrowska <sandra.pietrowska@gmail.com>
  5
+Lukas Toma <toma.lukas@gmail.com>
  6
+
  7
+
  8
+Datalog interpreteur based on previous work of:
  9
+Guillaume Raschia <guillaume.raschia@univ-nantes.fr>
  10
+
  11
+
  12
+Parser based on previous work from:
  13
+Xavier Leroy <xavier.leroy@inria.fr>
  14
+Julien Cohen >julien.cohen@univ-nantes.fr> 
  15
+
  16
+
  17
+
  18
+
  19
+PostgreSQL connection based on previous work from:
  20
+Alain Frisch <alain.frisch@lexifi.com>
  21
+Markus Mottl <markus.mottl@gmail.com>
  22
+
  23
+
  24
+
  25
+
  26
+Current maintainters:
  27
+Jaume Ferrarons <ckroxigor@gmail.com>
  28
+Grigory Antipov <antigregory@gmail.com>
22  CHANGES.txt
... ...
@@ -1,8 +1,16 @@
1  
-
2  
-2012-09-26:  New minor release version 0.2:
3  
-				
4  
-				* Added PostgreSQL connection
5  
-				* Switched to OCamlFind for the build process (see Makefile)
6  
-				* Added function Eval.is_prog for educational purpose
7  
-
  1
+2012-11-18:  WP1 release version 0.3:
  2
+
  3
+
  4
+                                * Full processing of Conjunctive Queries
  5
+                                * Added negation and equality
  6
+                                * Added command for reconnection to different database
  7
+                                * Added "quit" command
  8
+                        
  9
+2012-09-26:  New minor release version 0.2:
  10
+                                
  11
+                                * Added PostgreSQL connection
  12
+                                * Switched to OCamlFind for the build process (see Makefile)
  13
+                                * Added function Eval.is_prog for educational purpose
  14
+
  15
+
8 16
 2012-09-24:  First beta release, with basic parsing and fake SQL generation.
82  COPYING.txt
... ...
@@ -1,2 +1,80 @@
1  
-[put licensing terms here. Take car of all the dependencies and "viral"
2  
-behaviors of free software licenses linked with your code.]
  1
+FREEWARE LICENSE
  2
+END-USER LICENSE AGREEMENT
  3
+For Yadi-1.0
  4
+By ADB DreamTeam
  5
+
  6
+
  7
+NOTICE TO USER:
  8
+Please, read this carefully. By using all or any portion of the Software you accept all the terms and conditions of this Agreement. If you do not agree, do not use this Software.
  9
+
  10
+
  11
+
  12
+
  13
+1. DEFINITIONS
  14
+When used in this Agreement, the following terms shall have the respective meanings indicated, such meanings to be applicable to both the singular and plural forms of the terms defined:
  15
+
  16
+
  17
+"Licensor" means ADB DreamTeam.
  18
+
  19
+
  20
+"Licensee" means You or Your Company, unless otherwise indicated.
  21
+
  22
+
  23
+"Software" means (a) all of the contents of the files with which this Agreement is provided, including but not limited to ((i) related explanatory written materials or files ("Documentation"); and (ii) Software setup files and code samples; and (b) upgrades, modified versions, updates, additions, and copies of the Software, if any, licensed to you by ADB DreamTeam (collectively, "Updates").
  24
+
  25
+
  26
+"Use" or "Using" means to access, install, download, copy or otherwise benefit from using the functionality of the Software in accordance with the Documentation.
  27
+
  28
+
  29
+"System" means Windows OS, GNU/Linux or Mac OS X, or any virtual machine.
  30
+
  31
+
  32
+2. GENERAL USE 
  33
+You are granted a non-exclusive License to Use the downloaded Software for any purposes for an unlimited period of time.
  34
+The software product under this License is provided free of charge. Even though a license fee is not paid for the use of such software, it does not mean that there are no conditions for using such software.
  35
+
  36
+
  37
+2.1. The Software may be installed and Used by the Licensee for any legal purpose.
  38
+2.2. The Software may be installed and Used by the Licensee on any number of systems.
  39
+2.3. The Software can be copied and distributed under the condition that original copyright notice and disclaimer of warranty will stay intact and the Licensee will not charge money or fees for the Software product, except to cover distribution costs.
  40
+2.4. The Licensee will not have any proprietary rights in and to the Software. The Licensee acknowledges and agrees that the Licensor retains all copyrights and other proprietary rights in and to the Software.
  41
+2.5 Use within the scope of this License is free of charge and no royalty or licensing fees shall be paid by the Licensee.
  42
+
  43
+
  44
+3. INTELLECTUAL PROPERTY RIGHTS
  45
+3.1 This License does not transmit any intellectual rights on the Software. The Software and any copies that the Licensee is authorized by the Licensor to make are the intellectual property of and are owned by the Licensor. 
  46
+3.2 The Software is protected by copyright, including without limitation by Copyright Law and international treaty provisions. 
  47
+3.3 Any copies that the Licensee is permitted to make pursuant to this Agreement must contain the same copyright and other proprietary notices that appear on or in the Software. 
  48
+3.4 The structure, organization and code of the Software are the valuable trade secrets and confidential information of the Licensor. The Licensee agrees not to decompile, disassemble or otherwise attempt to discover the source code of the Software.
  49
+3.5 Any attempts to reverse-engineer, copy, clone, modify or alter in any way the installer program without the Licensor's specific approval are strictly prohibited. The Licensee is not authorized to use any plug-in or enhancement that permits to save modifications to a file with software licensed and distributed by the Licensor.
  50
+
  51
+
  52
+4. WARRANTY
  53
+4.1 The Licensor warrants that:
  54
+4.1.1 The Licensor owns the Software and documentation and/or is in possession of valid and existing licenses that support the terms of this Agreement;
  55
+4.1.2 the Software conforms to specifications and functionality as specified in Documentation;
  56
+4.1.3 to the best of the Licensor's knowledge, the Software does not infringe upon or violate any intellectual property right of any third party;
  57
+4.1.4 the Software does not contain any routine, intentionally designed by the Licensor to disable a computer program, or computer instructions that may alter, destroy or inhibit the processing environment.
  58
+
  59
+
  60
+4.2 Except those warranties specified in section 4.1 above, the Software is being delivered to the Licensee "AS IS" and the Licensor makes no warranty as to its use or performance.
  61
+
  62
+
  63
+The Licensor does not and cannot warrant the performance or results the Licensee may obtain by using the Software. The entire risk arising out of use or performance of the Software remains with the Licensee.
  64
+
  65
+
  66
+The Licensor gives no warranty, express or implied, that (i) the Software will be of satisfactory quality, suitable for any particular purpose or for any particular use under specified conditions, notwithstanding that such purpose, use, or conditions may be known to the Licensor; or (ii) that the Software will operate error free or without interruption or that any errors will be corrected.
  67
+
  68
+
  69
+5. LIMITATION OF LIABILITY
  70
+In no event will the Licensor be liable for any damages, claims or costs whatsoever or any consequential, indirect, incidental damages, or any lost profits or lost savings, even if the Licensor has been advised of the possibility of such loss, damages, claims or costs or for any claim by any third party. 
  71
+
  72
+
  73
+In no event will the Licensee be liable to the Licensor on condition that the Licensee complies with all terms and conditions stated in this License.
  74
+
  75
+
  76
+6. NON-WAIVER
  77
+If a portion of this agreement is held unenforceable, the remainder shall be valid. It means that if one section of the Agreement is not lawful, the rest of the Agreement is still in force. A party's failure to exercise any right under this Agreement will not constitute a waiver of (a) any other terms or conditions of this Agreement, or (b) a right at any time thereafter to require exact and strict compliance with the terms of this Agreement.
  78
+
  79
+
  80
+© 2012 ADB DreamTeam. All rights reserved.
53  INSTALL.txt
... ...
@@ -1,23 +1,30 @@
1  
-This is the INSTALL file for the YADI software distribution.
2  
-
3  
-Dependencies
4  
-============
5  
-
6  
-In order to compile this software, you will need:
7  
-* ocaml (>= 4.0.0)
8  
-* PostgreSQL (>= 9.0)
9  
-* postgresql-ocaml (>=2.0.1) 
10  
-* findlib (>= 1.3.1)
11  
-
12  
-Installing
13  
-==========
14  
-
15  
-1. Uncompress the source archive and go to the root directory 
16  
-2. Run 'make'
17  
-
18  
-[Remark: autoconf and automake greatly help in the installation process. I recommend you use them for your own development.]
19  
-
20  
-Uninstalling
21  
-============
22  
-
23  
-TODO
  1
+This is the INSTALL file for the YADI software distribution.
  2
+
  3
+
  4
+Dependencies
  5
+============
  6
+
  7
+
  8
+In order to compile this software, you will need:
  9
+* ocaml (>= 4.0.0)
  10
+* PostgreSQL (>= 9.0)
  11
+* postgresql-ocaml (>=2.0.1) 
  12
+* findlib (>= 1.3.1)
  13
+
  14
+
  15
+Installing
  16
+==========
  17
+
  18
+
  19
+1. Uncompress the source archive and go to the root directory 
  20
+2. Run 'make'
  21
+
  22
+
  23
+
  24
+
  25
+Uninstalling
  26
+============
  27
+
  28
+
  29
+1. Run 'make clean' 
  30
+2. Delete the folder containing Yadi.
27  README
@@ -6,20 +6,22 @@ YADI - Yet Another Datalog Interpreter
6 6
 What is YADI?
7 7
 -------------------------
8 8
 
9  
-TODO
  9
+YADI is a basic Datalog2SQL interpreter.
10 10
 
11  
-Pre-requisites
12  
--------------------------
  11
+    Copyright (C) 2012, DreamTeamADB and contributors
  12
+
  13
+    This program is free software: you can redistribute it and/or modify
  14
+    it under the terms of the license file.
13 15
 
14  
-It is madatory to connect a PostgreSQL server, with a role, a database and at least one populated table to formulate queries against that table.
  16
+    This program is distributed in the hope that it will be useful,
  17
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
15 19
 
16  
-Howto randomly poppopulate a table (for testing puropose only): 
17  
-	
18  
-	psql> create table test as SELECT id, md5(random()::text) AS descr FROM
19  
-          (SELECT * FROM generate_series(1,100) AS id) AS x;
  20
+    By using this software you agree to general terms of use stated in the icluded file COPYING.txt
20 21
 
21 22
 Usage
22 23
 -------------------------
  24
+It is madatory to connect a PostgreSQL server, with a role, a database and at least one populated table to formulate queries against that 	table.
23 25
 
24 26
 ./yadi <connexion info>
25 27
 
@@ -27,7 +29,7 @@ Example:
27 29
 
28 30
 ./yadi "host=localhost port=5432 user=test password=test dbname=test_db"
29 31
 
30  
-
  32
+For all the necessary information on the Datalog grammar used for Yadi, check 'datalog_spec.txt'.
31 33
 ---------------------------------------------------------------------------
32 34
 
33 35
 Contact Information and Contributing
@@ -36,10 +38,13 @@ Contact Information and Contributing
36 38
 In the case of bugs, feature requests, contributions and similar, please
37 39
 contact the maintainers:
38 40
 
39  
-  * Guillaume Raschia <guillaume.raschia@univ-nantes.fr>
  41
+	*Jaume Ferrasons <ckroxigor@gmail.com>
  42
+	*Grigory Antipov <antigregory@gmail.com>
  43
+	*Sandra Pietrowska <sandra.pietrowska@gmail.com>
  44
+	*Lukas Toma <toma.lukas@gmail.com>
40 45
 
41 46
 Up-to-date information should be available at:
42  
-<https://url-of-my-project>
  47
+<https://github.com/DreamTeamADB/Code>
43 48
 
44 49
 Enjoy!
45 50
 
291  datalog_spec.txt
... ...
@@ -1,155 +1,136 @@
1  
-[Here must be defined your actual Datalog-like BNF grammar.]
2  
-
3  
-TODO
4  
-
5  
-*************************************************************
6  
-Below is an example of a quite complete Datalog-like grammar.
7  
-
8  
-Source: The IRIS Reasoner Project
9  
-http://iris-reasoner.org/syntax#grammar
10  
-
11  
-This page provides you with the definition of the IRIS Datalog syntax, 
12  
-it has been generated from the BNF grammar.
13  
-
14  
-Productions
15  
-
16  
-program	= expr*
17  
-
18  
-expr	= {rule}	rule
19  
-|	{fact}	fact
20  
-|	{query}	query
21  
-
22  
-rule	= [head]: litlist ':-' [body]: litlist '.'
23  
-
24  
-fact	= predicate '.'
25  
-
26  
-query	= '?-' litlist '.'
27  
-
28  
-litlist	= literal
29  
-|	{and}	litlist 'and' literal
30  
-|	{comma}	litlist ',' literal
31  
-
32  
-literal	= {negated}	 '!' predicate
33  
-|		predicate
34  
-|	{builtin}	builtin
35  
-
36  
-predicate	= alpha+ paramlist?
37  
-
38  
-paramlist	= '(' termlist? ')'
39  
-
40  
-termlist	= {term}	term
41  
-|		termlist ',' term
42  
-
43  
-intlist	=	intlist ',' t_int
44  
-|	{int}	t_int
45  
-
46  
-term	=	{function}	alpha+ paramlist
47  
-|	{var}	t_variable
48  
-|	{integer}	t_int
49  
-|	{integerl}	t_pre_integer '(' t_int ')'
50  
-|	{string}	t_str
51  
-|	{stringl}	t_pre_string '(' t_str ')'
52  
-|	{decimal}	t_dec
53  
-|	{decimall}	t_pre_decimal '(' t_dec ')'
54  
-|	{sqname}	t_sq
55  
-|	{sqnamel}	t_pre_sqname '(' t_sq ')'
56  
-|	{iri}	t_unders t_str
57  
-|	{iril}	t_pre_iri '(' t_str ')'
58  
-|	{boolean}	t_pre_boolean '(' t_str ')'
59  
-|	{double}	t_pre_double '(' t_dec ')'
60  
-|	{float}	t_pre_float '(' t_dec ')'
61  
-|	{date}	t_pre_date '(' intlist ')'
62  
-|	{duration}	t_pre_duration '(' intlist ')'
63  
-|	{datetime}	t_pre_datetime '(' intlist ')'
64  
-|	{time}	t_pre_time '(' intlist ')'
65  
-|	{gday}	t_pre_gday '(' t_int ')'
66  
-|	{gmonth}	t_pre_gmonth '(' t_int ')'
67  
-|	{gyear}	t_pre_gyear '(' t_int ')'
68  
-|	{gyearmonth}	t_pre_gyearmonth '(' intlist ')'
69  
-|	{gmonthday}	t_pre_gmonthday '(' intlist ')'
70  
-|	{base64binary}	t_pre_base64 '(' t_str ')'
71  
-|	{hexbinary}	t_pre_hex '(' t_str ')'
72  
-
73  
-builtin	= {binary}	[first]: term t_bin_op [second]: term
74  
-|	{equals}	[first]: term t_eq [second]: term
75  
-|	{ternary}	[first]: term t_ter_op [second]: term t_eq [third]: term
76  
-
77  
-
78  
-Helpers
79  
-
80  
-all	=	 [ 0x0 .. 0xffff ]
81  
-tab	=	9
82  
-cr	=	13
83  
-lf	=	10
84  
-eol	=	cr lf | cr | lf
85  
-alpha	=	 [ 'a' .. 'z' ] | [ 'A' .. 'Z' ]
86  
-num	=	 [ '0' .. '9' ]
87  
-alphanum	=	alpha | num
88  
-anychar	=	alphanum | ' ' | tab | '/' | '#' | ':' | '.' | ',' | ';'
89  
-min	=	'-'
90  
-dot	=	'.'
91  
-comma	=	','
92  
-comment	=	'//' [ all - [ cr+ lf ] ]* eol
93  
-blank	=	 ( ' ' | tab | eol )+
94  
-delim	=	'''
95  
-eq	=	'='
96  
-ne	=	'!' eq
97  
-add	=	'+'
98  
-sub	=	'-'
99  
-mul	=	'*'
100  
-div	=	'/'
101  
-lt	=	'<'
102  
-le	=	lt eq
103  
-gt	=	'>'
104  
-ge	=	gt eq
105  
-
106  
-
107  
-Tokens
108  
-
109  
-t_blank	=	blank
110  
-t_comment	=	comment
111  
-t_dot	=	dot
112  
-t_impliedby	=	':-'
113  
-t_and	=	'and'
114  
-t_not	=	'not' | 'naf' | '!'
115  
-t_comma	=	comma
116  
-t_lpar	=	'('
117  
-t_rpar	=	')'
118  
-t_variable	=	'?' alphanum+
119  
-'?-'	=	'?-'
120  
-t_id	=	alpha+
121  
-t_delim	=	delim
122  
-t_unders	=	'_'
123  
-t_bin_op	=	ne | lt | le | gt | ge
124  
-t_ter_op	=	add | sub | mul | div
125  
-t_eq	=	eq
126  
-t_int	=	min? num+
127  
-t_dec	=	min? num+ ( dot num+ )?
128  
-t_str	=	delim anychar+ delim
129  
-t_sq	=	alphanum+ '#' alphanum+
130  
-t_pre_integer	=	'_integer'
131  
-t_pre_string	=	'_string'
132  
-t_pre_decimal	=	'_decimal'
133  
-t_pre_double	=	'_double'
134  
-t_pre_float	=	'_float'
135  
-t_pre_base64	=	'_base64binary'
136  
-t_pre_boolean	=	'_boolean'
137  
-t_pre_date	=	'_date'
138  
-t_pre_datetime	=	'_datetime'
139  
-t_pre_duration	=	'_duration'
140  
-t_pre_gday	=	'_gday'
141  
-t_pre_gmonthday	=	'_gmonthday'
142  
-t_pre_gmonth	=	'_gmonth'
143  
-t_pre_gyearmonth	=	'_gyearmonth'
144  
-t_pre_gyear	=	'_gyear'
145  
-t_pre_hex	=	'_hexbinary'
146  
-t_pre_iri	=	'_iri'
147  
-t_pre_sqname	=	'_sqname'
148  
-t_pre_time	=	'_time'
149  
-
150  
-
151  
-Ignored Tokens
152  
-
153  
-t_blank
154  
-t_comment
155  
-
  1
+*************************************************************
  2
+This page provides you with the definition of the Yadi-0.3 Datalog syntax,
  3
+
  4
+
  5
+
  6
+
  7
+/* Grammar */
  8
+  main: EOP        { failwith "main: where's my program?!"}
  9
+  | program EOP 
  10
+  | commlist EOP        
  11
+    
  12
+  program:
  13
+  | exprlist 
  14
+  
  15
+  commlist:
  16
+  | command        
  17
+                
  18
+  exprlist:
  19
+  | expr        
  20
+  | exprlist expr 
  21
+  
  22
+  expr:
  23
+  | rule        
  24
+  | query        
  25
+    
  26
+  command:
  27
+  | TESTCOMM RELNAME 
  28
+  | RECONNECT reconn_param VAL reconn_param pass_param reconn_param  /* host port user password db_name*/
  29
+  | QUITCOMM        
  30
+  | UNKNOWNCOMM 
  31
+  
  32
+  reconn_param:
  33
+  | ANYNAME 
  34
+  | RELNAME 
  35
+  | VARNAME 
  36
+  
  37
+  pass_param:
  38
+  | ANYNAME 
  39
+  | RELNAME 
  40
+  | VARNAME 
  41
+  | PASSNAME 
  42
+  
  43
+  rule:
  44
+  head IMPLIEDBY body DOT          
  45
+
  46
+
  47
+  head:
  48
+  predicate        
  49
+
  50
+
  51
+  body:
  52
+  litlist        
  53
+
  54
+
  55
+  query:
  56
+  | QMARK predicate DOT        
  57
+
  58
+
  59
+  litlist: /* empty */        
  60
+  | literal        
  61
+  | litlist AND literal        
  62
+  
  63
+  literal:
  64
+  | predicate        
  65
+  | NOT predicate 
  66
+  | equality        
  67
+  | NOT equality        
  68
+
  69
+
  70
+  predicate:
  71
+  RELNAME LPAREN termlist RPAREN        
  72
+
  73
+
  74
+  equality:        
  75
+  VARNAME EQ VAL        
  76
+
  77
+
  78
+  termlist: /* empty */        
  79
+  | term        
  80
+  | term SEP termlist         /* \!/ rec. on the right */
  81
+
  82
+
  83
+  term:
  84
+  VARNAME        
  85
+
  86
+
  87
+/* tokens declaration */
  88
+
  89
+
  90
+%token <int> VAL /* token with int value */
  91
+%token <string> RELNAME /* token with string value */
  92
+%token <string> VARNAME /* token with string value */
  93
+  
  94
+%token QMARK DOT IMPLIEDBY
  95
+%token AND NOT
  96
+%token EQ
  97
+%token LPAREN RPAREN SEP
  98
+%token EOP
  99
+%token ANON /* fake token to stop the grammar in the fact rule */
  100
+%token TESTCOMM RECONNECT QUITCOMM UNKNOWNCOMM
  101
+
  102
+
  103
+%token <string> ANYNAME /* mytoken with string value */
  104
+%token <string> PASSNAME /* mytoken with string value */
  105
+
  106
+
  107
+/* associativity and precedence when needed */
  108
+%nonassoc IMPLIEDBY
  109
+
  110
+
  111
+/*Helpers*/
  112
+
  113
+
  114
+QMARK            = '-?'
  115
+DOT                 = '.'
  116
+IMPLIEDBY        = ':-'        
  117
+AND                = 'and'
  118
+NOT                = 'not'
  119
+LPAREN                = '('
  120
+RPAREN                = ')'
  121
+SEP                = ','
  122
+EQ                = '='
  123
+EOP                = '/'
  124
+ANYNAME                = ['A'-'Z' 'a'-'z']['A'-'Z' 'a'-'z' '0'-'9' '_' '-']* 
  125
+PASSNAME        = ['A'-'Z' 'a'-'z' '0'-'9' '_' '-']+
  126
+RELNAME                = ['A'-'Z']['a'-'z']*
  127
+VAL                = ['0'-'9']
  128
+RECONNECT        = #reconnect
  129
+QUITCOMM          = #quit
  130
+
  131
+
  132
+
  133
+
  134
+
  135
+
  136
+*************************************************************
168  eval.ml
@@ -64,17 +64,17 @@ let get_command c = match c with
64 64
 ;;
65 65
 
66 66
 
67  
-let eval_command c aux_arg = match c with
  67
+let eval_command c aux_arg outch = match c with
68 68
 	| TestComm p -> printf "This is the first test command! Argument is %s\n" p; aux_arg := ""; "";
69 69
 	| ReconnComm (host_name, port_name, user_name, password_name, db_name) -> aux_arg := "reconnect"; "host=" ^ host_name ^ " port=" ^ string_of_int port_name ^ " user=" ^ user_name ^ " password=" ^ password_name ^ " dbname=" ^ db_name;
70 70
 	| ChangeOutComm f -> aux_arg := "changeout"; f;
71 71
 	| ReadScriptComm f -> aux_arg := "readscript"; f;
72 72
 	| HelpCommand h -> (match h with
73  
-				| Select -> aux_arg := ""; fprintf stdout "Form the query as Head(x) :- Body(x,y)., which selects x from the table.\nExample: Q(x) :- R(x,y). \n"; flush stdout; "";
74  
-				| Join -> aux_arg := ""; fprintf stdout "Use 'and' to perform the join, such as Head(x,z) :- Body1(x,y) and Body2(y,z)., which performs join on Body1.y = Body2.y.\nExample: Q(x,Z) :- R(x,y) and P(y,z). \n"; flush stdout; "";
75  
-				| Where -> aux_arg := ""; fprintf stdout "Use 'and' to add WHERE condition, such as Head(x) :- Body1(x,y) and y \'comparison\' \'condition\'.\n\nFollowing symbols are permitted as \'comparison\': <, >, =, <=, >=, <> (not equal).\nConstant or variable is permitted as \'condition\'.\n\nExample1: Q(x) :- R(x,y) and y=6. \nExample2: Q(x) :- R(x,y,z) and y<z.\n"; flush stdout; "";
76  
-				| WhereNot -> aux_arg := ""; fprintf stdout "WHERE NOT clause can be expressed in two ways:\n\n1.in the WHERE condition with adding \'not\' before condition\n\nExample1: Q(x) :- R(x,y) and not y=6.\n\n2.by putting \'not\' keyword in front of relation in the body, which we want to negate\n\nExample2: Q(x) :- not R(x,y,z) and y<3.\n"; flush stdout; "";
77  
-				| Other	-> aux_arg := "unknown"; fprintf stderr "Enter valid SQL keyword to see help!\n"; flush stderr;"";)
  73
+				| Select -> aux_arg := ""; fprintf outch "Form the query as Head(x) :- Body(x,y)., which selects x from the table.\nExample: Q(x) :- R(x,y). \n"; flush outch; "";
  74
+				| Join -> aux_arg := ""; fprintf outch "Use 'and' to perform the join, such as Head(x,z) :- Body1(x,y) and Body2(y,z)., which performs join on Body1.y = Body2.y.\nExample: Q(x,Z) :- R(x,y) and P(y,z). \n"; flush outch; "";
  75
+				| Where -> aux_arg := ""; fprintf outch "Use 'and' to add WHERE condition, such as Head(x) :- Body1(x,y) and y \'comparison\' \'condition\'.\n\nFollowing symbols are permitted as \'comparison\': <, >, =, <=, >=, <> (not equal).\nConstant or variable is permitted as \'condition\'.\n\nExample1: Q(x) :- R(x,y) and y=6. \nExample2: Q(x) :- R(x,y,z) and y<z.\n"; flush outch; "";
  76
+				| WhereNot -> aux_arg := ""; fprintf outch "WHERE NOT clause can be expressed in two ways:\n\n1.in the WHERE condition with adding \'not\' before condition\n\nExample1: Q(x) :- R(x,y) and not y=6.\n\n\n2.by putting \'not\' keyword in front of relation in the body, which we want to negate\n\nExample2: Q(x) :- not R(x,y,z) and y<3.\n"; flush outch; "";
  77
+				| Other	-> aux_arg := "unknown"; fprintf stderr "Enter valid SQL keyword to see help!\n"; flush stderr; "";)
78 78
 	| TabinfoCommand table_name -> aux_arg := "tabinfo"; "select column_name, data_type, is_nullable from information_schema.columns where table_name=\'" ^ table_name ^ "\';";
79 79
 	| GettablesCommand -> aux_arg := "tabinfo"; "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';";
80 80
 	| GetdbCommand -> aux_arg := "tabinfo"; "SELECT datname FROM pg_database;";
@@ -124,7 +124,8 @@ let rec get_predname t = match t with
124 124
 	| Rel r			-> ( match r with
125 125
 							| Pred (x, vl) -> x 
126 126
 						)
127  
-	| Comp	(s, c, i)	-> c
  127
+	| Comp	(s, c, i)	-> s
  128
+	| Comp2 (s, c, i)	-> s
128 129
 	| Not t			-> get_predname t
129 130
 	| BPred (x, vl) -> x 
130 131
 ;;
@@ -134,7 +135,8 @@ let rec get_varlist t = match t with
134 135
 	| Rel r			-> ( match r with
135 136
 							| Pred (x, vl) -> vl
136 137
 						)
137  
-	| Comp	(s, c, i)	-> s :: [i]
  138
+	| Comp	(s, c, i)	-> s :: []
  139
+	| Comp2 (s, c, s2)	-> s :: []
138 140
 	| Not t			-> get_varlist t
139 141
 	| BPred (x, vl) -> vl
140 142
 ;;
@@ -179,28 +181,21 @@ let rec search_non_empty_list l pos =
179 181
 ;;
180 182
 
181 183
 let prepare_literal l = match l with 
182  
-	| Rel r			-> [get_predname(l); (String.concat "," (List.map(fun x -> param_to_string x)(get_varlist l)))]
183  
-	| Comp  (s, c, i)	-> [Expr.param_to_string s; c; Expr.param_to_string i]
  184
+	| Rel r			-> [get_predname(l); (String.concat "," (get_varlist (l)))]
  185
+	| Comp  (s, c, i)	-> [get_predname(l); c; string_of_int i]
  186
+	| Comp2 (s, c, i)	-> [get_predname(l); c; i]
184 187
 	| Not t			-> []
185 188
 	| BPred (x, vl) -> let len = List.length vl in
186 189
 						match x with
187 190
 							| "_isEven" -> if len != 1 then raise (QueryError ("Boolean predicate '_isEven' expects one parameter."))
188  
-											else [param_to_string (List.hd vl); "%2 = 0"]
  191
+											else [List.hd vl; "%2 = 0"]
189 192
 							| "_isOdd" -> if len != 1 then raise (QueryError ("Boolean predicate '_isOdd' expects one parameter."))
190  
-											else [param_to_string (List.hd vl); "%2 = 1"]
  193
+											else [List.hd vl; "%2 = 1"]
191 194
 							| _ -> raise (QueryError ("Unrecognized boolean predicate '"^x^"'."))
192 195
 ;;
193 196
 
194 197
 let split_relation l =
195  
-	[get_predname(l); (String.concat "," (List.map(fun x -> param_to_string x)(get_varlist l)))]
196  
-;;
197  
-
198  
-let relation_head l =
199  
-	get_predname(l)
200  
-;;
201  
-
202  
-let relation_tail l =
203  
-	(get_varlist l)
  198
+	[get_predname(l); (String.concat "," (get_varlist (l)))]
204 199
 ;;
205 200
 
206 201
 let extract_term_from_not l = match l with 
@@ -281,37 +276,15 @@ let prepare_variables_selection cols as_name =
281 276
 	let hash_names = Hashtbl.create 10 in
282 277
 	Hashtbl.add hash_names "_ANONVAR_" 1; (* ignoring anonymous variables *)
283 278
 	(String.concat ", " (List.filter(fun x -> (String.compare x "") != 0) (List.mapi(fun n x -> 
284  
-		match x with
285  
-			| ParamI i -> ""
286  
-			| ParamS s ->
287  
-				begin
288  
-				try 
289  
-					let _ = Hashtbl.find hash_names s in
290  
-						""
291  
-				with Not_found ->
292  
-					(*Init the list in the hash*)
293  
-					Hashtbl.add hash_names s 1;
294  
-					(param_to_string (List.nth cols n))^" AS "^s
295  
-				end
296  
-	) as_name)))
297  
-;;
298  
-
299  
-(*Returns an string containing the select information deleting the repeated names for strings in cols*)
300  
-let s_prepare_variables_selection cols as_name =
301  
-	let hash_names = Hashtbl.create 10 in
302  
-	(String.concat ", " (List.filter(fun x -> (String.compare x "") != 0) (List.mapi(fun n x -> 
303  
-		match x with
304  
-			| ParamI i -> ""
305  
-			| ParamS s ->
306  
-				begin
307  
-				try 
308  
-					let _ = Hashtbl.find hash_names s in
309  
-						""
310  
-				with Not_found ->
311  
-					(*Init the list in the hash*)
312  
-					Hashtbl.add hash_names s 1;
313  
-					(List.nth cols n)^" AS "^s
314  
-				end
  279
+		begin
  280
+		try 
  281
+			let _ = Hashtbl.find hash_names x in
  282
+				""
  283
+		with Not_found ->
  284
+			Hashtbl.add hash_names x 1;
  285
+			(*Init the list in the hash*)
  286
+			(List.nth cols n)^" AS "^x
  287
+		end
315 288
 	) as_name)))
316 289
 ;;
317 290
 
@@ -319,43 +292,21 @@ let s_prepare_variables_selection cols as_name =
319 292
 let generate_select_restrictions cols as_name =
320 293
 	let hash_names = Hashtbl.create 10 in
321 294
 	(List.filter(fun x -> (String.compare x "") != 0) (List.mapi(fun n x -> 
322  
-		match x with
323  
-			| ParamI i -> (param_to_string (List.nth cols n))^" = "^string_of_int i
324  
-			| ParamS s ->
325  
-				begin
326  
-				try 
327  
-					let c = Hashtbl.find hash_names x in
328  
-						(param_to_string (List.nth cols n))^" = "^c
329  
-				with Not_found ->
330  
-					(*Init the list in the hash*)
331  
-					Hashtbl.add hash_names x (param_to_string (List.nth cols n));
332  
-					""
333  
-				end
334  
-	) as_name))
335  
-;;
336  
-
337  
-(*Returns a list of queries generated by repeated variables in the predicates for string in the columns*)
338  
-let s_generate_select_restrictions cols as_name =
339  
-	let hash_names = Hashtbl.create 10 in
340  
-	(List.filter(fun x -> (String.compare x "") != 0) (List.mapi(fun n x -> 
341  
-		match x with
342  
-			| ParamI i -> (List.nth cols n)^" = "^string_of_int i
343  
-			| ParamS s ->
344  
-				begin
345  
-				try 
346  
-					let c = Hashtbl.find hash_names x in
347  
-						(List.nth cols n)^" = "^c
348  
-				with Not_found ->
349  
-					(*Init the list in the hash*)
350  
-					Hashtbl.add hash_names x (List.nth cols n);
351  
-					""
352  
-				end
  295
+		begin
  296
+		try 
  297
+			let c = Hashtbl.find hash_names x in
  298
+				(List.nth cols n)^" = "^c
  299
+		with Not_found ->
  300
+			(*Init the list in the hash*)
  301
+			Hashtbl.add hash_names x (List.nth cols n);
  302
+			""
  303
+		end
353 304
 	) as_name))
354 305
 ;;
355 306
 
356 307
 (* Subquery generator *)
357 308
 let rec get_subquery e name col_names =
358  
-	let num_queried_columns = List.length col_names in
  309
+	let num_queried_columns = (List.length(Str.split (Str.regexp ",") col_names)) in
359 310
 	(*Printf.printf "Parameters(%i): '%s'\n" (List.length(Str.split (Str.regexp ",") col_names)) col_names;*)
360 311
 	(*Printf.printf "Call %s\n" name; flush stdout;*)
361 312
 	let predicates = get_fullrelation e name in
@@ -366,10 +317,10 @@ let rec get_subquery e name col_names =
366 317
 			raise (QueryError ("Relation '"^name^"' has "^(string_of_int (List.length edb_cols))^" columns but you queried "^(string_of_int num_queried_columns)^"."))	
367 318
 		else
368 319
 			"(SELECT "^
369  
-			(s_prepare_variables_selection edb_cols col_names )^
  320
+			(prepare_variables_selection (get_column name) (Str.split (Str.regexp ",") col_names) )^
370 321
 			" FROM "^
371 322
 			name^
372  
-			(let where = s_generate_select_restrictions edb_cols col_names in
  323
+			(let where = generate_select_restrictions (get_column name) (Str.split (Str.regexp ",") col_names) in
373 324
 				if List.length where > 0 then " WHERE "^(String.concat " AND " where )
374 325
 				else "")^
375 326
 			") AS foo"
@@ -382,12 +333,12 @@ let rec get_subquery e name col_names =
382 333
 			if num_queried_columns > (List.length head_cols) then
383 334
 				raise (QueryError ("Relation '"^name^"' has "^(string_of_int (List.length head_cols))^" columns but you queried "^(string_of_int num_queried_columns)^"."))	
384 335
 			else
385  
-			let sel = (prepare_variables_selection head_cols col_names) in
  336
+			let sel = (prepare_variables_selection head_cols (Str.split (Str.regexp ",") col_names)) in
386 337
 				(String.concat " " [
387 338
 					"SELECT";
388 339
 					sel;
389 340
 					"FROM";
390  
-					(gen_sub_tables e lrel col_names head_cols);
  341
+					(gen_sub_tables e lrel (Str.split (Str.regexp ",") col_names) head_cols);
391 342
 				])
392 343
 		) predicates in
393 344
 			"("^(String.concat " UNION " sub_selects)^") AS foo"
@@ -405,49 +356,56 @@ and gen_sub_tables e l sel sel_as =
405 356
 	(*Generate the table expressions for the from*)
406 357
 	let tables = List.filter (fun x -> match x with | Rel r -> true | _ -> false) l in
407 358
 	for ntable = 0 to List.length tables - 1 do
408  
-		let table_name = relation_head (List.nth tables ntable) in
409  
-		let col_names = relation_tail (List.nth tables ntable) in			
  359
+		let table = split_relation(List.nth tables ntable) in
  360
+			let table_name = List.nth table 0 in
  361
+			let col_names = List.nth table 1 in			
410 362
 			from := List.append from.contents [(get_subquery e table_name col_names)^(string_of_int num_table.contents)];
411 363
 			num_table := num_table.contents + 1;
412  
-			vars_from := List.append vars_from.contents (List.filter(fun x -> match x with | ParamS s -> true | ParamI i -> false) col_names);
  364
+			vars_from := List.append vars_from.contents (Str.split (Str.regexp ",") col_names);
413 365
 	done;
414 366
 	(*Process the equalities*)
415 367
 	let comparisons = List.filter (fun x -> match x with 
416 368
 												| Comp(s, c, i) -> true
  369
+												| Comp2(s, c, i) -> true
417 370
 												| BPred (x, vl) -> true
418 371
 												| _ -> false) l in
419  
-	(*Printf.printf "Number of comparisions: %i\n" (List.length comparisons);*)
420 372
 	for nequ = 0 to List.length comparisons - 1 do
421 373
 		let info = prepare_literal(List.nth comparisons nequ) in
422 374
 		let equ = (String.concat " " info) in
423 375
 		if match List.nth comparisons nequ with
424  
-			| Comp(s, c, i) -> List.for_all (fun p -> let p2 = param_to_string p in List.exists(fun x -> (String.compare p2 (param_to_string x)) == 0 || (match p with | ParamS s -> false | ParamI i -> true)) vars_from.contents) [s;i]
425  
-			| BPred (x, vl) -> List.for_all (fun p -> let p2 = param_to_string p in List.exists(fun x -> (String.compare p2 (param_to_string x)) == 0 || (match p with | ParamS s -> false | ParamI i -> true)) vars_from.contents) vl
  376
+			| Comp(s, c, i) -> List.exists (fun x -> (String.compare (List.nth info 0) x) == 0) vars_from.contents
  377
+			| Comp2(s, c, i) -> List.exists (fun x -> (String.compare (List.nth info 0) x) == 0) vars_from.contents &&
  378
+									List.exists(fun x -> (String.compare (List.nth info 2) x) == 0) vars_from.contents
  379
+			| BPred (x, vl) -> List.exists (fun x -> List.exists(fun y -> (String.compare y x) == 0) vl) vars_from.contents
426 380
 			| Rel r -> raise (QueryError ("Relation not expected within comparisons."))
427 381
 			| Not t -> raise (QueryError ("Negation not expected within comparisons."))
428 382
 		then where := List.append where.contents [equ]
429 383
 		else where_not_in := List.append where_not_in.contents [equ]
430 384
 	done;
431  
-	(*Printf.printf "Comparisions where: \"%s\"\n" (String.concat ";" where.contents);*)
432  
-	(*Printf.printf "Comparisions where_not_in: \"%s\"\n" (String.concat ";" where_not_in.contents);*)
433 385
 	(*Process the negations*)
434 386
 	let nots = List.filter (fun x -> match x with | Not t -> true | _ -> false) l in
435 387
 	let sub_nots = List.map (fun x -> extract_term_from_not x) nots in
436 388
 	List.iter(fun x-> match x with 
437  
-			| Rel r			-> not_in := List.append not_in.contents [(get_subquery e (get_predname(Rel r)) (get_varlist(Rel r)))^(string_of_int num_table.contents)];
  389
+			| Rel r			-> not_in := List.append not_in.contents [(get_subquery e (get_predname(Rel r)) (String.concat "," (get_varlist(Rel r))))^(string_of_int num_table.contents)];
438 390
 								num_table := num_table.contents + 1;
439 391
 							   vars_not_in := List.append vars_not_in.contents (get_varlist(Rel r))
440  
-			| Comp (s, c, i)	-> if List.for_all (fun p -> let p2 = param_to_string p in List.exists(fun x -> (String.compare p2 (param_to_string x)) == 0 || (match p with | ParamS s -> false | ParamI i -> true)) vars_from.contents) [s;i]
  392
+			| Comp (s, c, i)	-> let info = prepare_literal x in
  393
+								if List.exists(fun x -> (String.compare (List.hd info) x) == 0) vars_from.contents
441 394
 								then where := List.append where.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
442 395
 								else where_not_in := List.append where_not_in.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
443  
-			| BPred(s, vl)		-> if List.for_all (fun p -> let p2 = param_to_string p in List.exists(fun x -> (String.compare p2 (param_to_string x)) == 0 || (match p with | ParamS s -> false | ParamI i -> true)) vars_from.contents) vl
  396
+			| Comp2(s, c, i)	-> let info = prepare_literal x in
  397
+								if List.exists(fun x -> (String.compare (List.hd info) x) == 0) vars_from.contents &&
  398
+									List.exists(fun x -> (String.compare (List.nth info 2) x) == 0) vars_from.contents
  399
+								then where := List.append where.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
  400
+								else where_not_in := List.append where_not_in.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
  401
+			| BPred(s, vl)		-> if List.exists (fun x -> List.exists(fun y -> (String.compare y x) == 0) vl) vars_from.contents
444 402
 								then where := List.append where.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
445 403
 								else where_not_in := List.append where_not_in.contents ["NOT "^(String.concat " " (prepare_literal(x)))]
446 404
 			| Not t			-> invalid_arg "Error: Not Not Clause!!!") sub_nots;
447 405
 	(*Check query safety*)
448 406
 	(*1st check that all selected variables are in a not negated relation*)
449  
-	List.iter(fun x -> if not (List.exists(fun y -> (String.compare (param_to_string x) (param_to_string y)) == 0  || (match x with | ParamS s -> false | ParamI i -> true)) vars_from.contents) 
450  
-						then raise (QueryError ("Variable '"^(param_to_string x)^"' is not safe."))) sel_as;
  407
+	List.iter(fun x -> if not (List.exists(fun y -> (String.compare x y) == 0) vars_from.contents) 
  408
+						then raise (QueryError ("Variable '"^x^"' is not safe."))) sel_as;
451 409
 	(*Generate the result*)
452 410
 	let str_from = String.concat " NATURAL JOIN " from.contents in
453 411
 	let str_where = 
@@ -468,13 +426,13 @@ and gen_sub_tables e l sel sel_as =
468 426
 (* generate SQL statement from the ast *)
469 427
 let sql_stt e = String.concat "" 
470 428
 	["SELECT DISTINCT ";
471  
-	(String.concat ", " (List.map(fun x -> param_to_string x)(get_varlist(match (get_query e) with 
472  
-		Query p -> Rel p | _ -> invalid_arg "is_prog"))));
  429
+	(String.concat ", " (get_varlist(match (get_query e) with 
  430
+		Query p -> Rel p | _ -> invalid_arg "is_prog")));
473 431
 	" FROM " ;
474 432
 	( get_subquery e (get_predname(match (get_query e) with 
475 433
 		Query p -> Rel p | _ -> invalid_arg "is_prog"))
476  
-		(get_varlist(match (get_query e) with 
477  
-		Query p -> Rel p | _ -> invalid_arg "is_prog")));
  434
+		(String.concat "," (get_varlist(match (get_query e) with 
  435
+		Query p -> Rel p | _ -> invalid_arg "is_prog"))));
478 436
 	]
479 437
 ;;
480 438
 
57  examples.lang
@@ -56,7 +56,7 @@ Q(x,y) :- Test(x,y) and x=1.
56 56
 ?-Q(b,c).
57 57
 /
58 58
 
59  
-Q(x) :- Test(1,x).
  59
+Q(x) :- Test(x,1).
60 60
 ?-Q(b).
61 61
 /
62 62
 
@@ -84,10 +84,6 @@ Q(x,a,b):-Names(x,y,z) and Marks(x,a,b) and b = 75.
84 84
 ?-Q(x,a,b).
85 85
 /
86 86
 
87  
-Q(x,a):-Names(x,y,z) and Marks(x,a,75).
88  
-?-Q(x,a).
89  
-/
90  
-
91 87
 Q(x,a,b):-Marks(x,a,b).
92 88
 ?-Q(x,a,b).
93 89
 /
@@ -111,7 +107,6 @@ Q(y):-Student(x,z,a) and not Enroll(x,y,b) and z=200.
111 107
 R(x):-Enroll(a,x,b) and not Q(x).
112 108
 ?-R(x).
113 109
 /
114  
-Errors ==> Variable 'y' is not safe.
115 110
 
116 111
 Q(id,descr) :- Test(id,descr).
117 112
 R(id,descr) :- Q(id,descr).
@@ -183,18 +178,6 @@ Q(x,y,z):-Marks(x,y,z) and not x = z.
183 178
 ?-Q(x,y,z).
184 179
 /
185 180
 
186  
-Q(x,y,z):-Marks(x,y,z) and not x = x.
187  
-?-Q(x,y,z).
188  
-/
189  
-
190  
-Q(x,y,z):-Marks(x,y,z) and not x = 3.
191  
-?-Q(x,y,z).
192  
-/
193  
-
194  
-Q(x,y,z):-Marks(x,y,z) and not 3 = x.
195  
-?-Q(x,y,z).
196  
-/
197  
-
198 181
 Q(x,y,z):-Names(x,y,z) and not Marks(x,a,b) and x = b.
199 182
 ?-Q(x,a,b).
200 183
 /
@@ -276,44 +259,6 @@ Q(x,y,z):-Marks(x,y,z) and _isOdd(z).
276 259
 ?-Q(x,y,z).
277 260
 /
278 261
 
279  
-Q(x,y):-Marks(x,y,100).
280  
-?-Q(x,y).
281  
-/
282  
-
283  
-Q(x,y):-Marks(3,y,x).
284  
-?-Q(x,y).
285  
-/
286  
-
287  
-Q(y):-Marks(3,y,100).
288  
-?-Q(y).
289  
-/
290  
-
291  
-Q(x,y,z):-Marks(x,y,z) and _isOdd(1).
292  
-?-Q(x,y,z).
293  
-/
294  
-
295  
-Q(x,1,z):-Marks(x,y,z).
296  
-?-Q(x,y,z).
297  
-/
298  
-
299  
-Q(0,1,2):-Marks(x,y,z).
300  
-?-Q(x,y,z).
301  
-/
302  
-
303  
-Q(0,1,2):-Marks(x,y,z).
304  
-Q(2,1,0):-Marks(x,y,z).
305  
-?-Q(x,y,z).
306  
-/
307  
-
308  
-Q(x,y,z):-Marks(x,y,z).
309  
-?-Q(1,y,z).
310  
-/
311  
-
312  
-Q(x,y,z):-Marks(x,y,z).
313  
-R(x,y):-Q(x,y,75).
314  
-?-R(x,y).
315  
-/
316  
-
317 262
 (*command examples*)
318 263
 
319 264
 #help select/
27  expr.ml
@@ -6,14 +6,12 @@ type expr =
6 6
 	| Comm of stt (*later it would be stt list!!!*)
7 7
 and term =
8 8
 	| Rel of rterm
9  
-	| Comp of param * string * param
  9
+	| Comp of string * string * int
  10
+	| Comp2 of string * string * string
10 11
 	| Not of term
11  
-	| BPred of string * param list
  12
+	| BPred of string * string list
12 13
 and rterm =
13  
-	| Pred of string * param list
14  
-and param = 
15  
-	| ParamS of string
16  
-	| ParamI of int
  14
+	| Pred of string * string list
17 15
 and stt =
18 16
 	| TestComm of string
19 17
 	| ReconnComm of string * int * string * string * string
@@ -37,25 +35,20 @@ and helpp =
37 35
 (* to be continued... *)
38 36
 ;;
39 37
 
40  
-let param_to_string p =
41  
-	match p with
42  
-		| ParamS s	-> s
43  
-		| ParamI i	-> string_of_int i
44  
-;;
45  
-
46 38
 (* support function for smart stringify of the AST - see to_string below *)
47 39
 let string_of_rterm r = match r with 	
48  
-	| Pred (x, [])		-> x
49  
-	| Pred (x, h::[]) 	-> x ^ "(" ^ param_to_string h ^ ")"
50  
-	| Pred (x, h::t) 	-> x ^ "(" ^ param_to_string h ^ List.fold_right (fun s acc -> acc ^ "," ^ param_to_string s) t "" ^ ")"
  40
+	| Pred (x, [])		-> x ^ "()"
  41
+	| Pred (x, h::[]) 	-> x ^ "(" ^ h ^ ")"
  42
+	| Pred (x, h::t) 	-> x ^ "(" ^ h ^ List.fold_right (fun s acc -> acc ^ "," ^ s) t "" ^ ")"
51 43
 ;;
52 44
 
53 45
 (* support function for smart stringify of the AST - see to_string below *)
54 46
 let rec string_of_term t = match t with 
55 47
 	| Rel r			-> string_of_rterm r
56  
-	| Comp (s1, c, i)	-> param_to_string s1 ^ c ^ param_to_string i
  48
+	| Comp (s1, c, i)	-> s1 ^ c ^ string_of_int i
  49
+	| Comp2(s1, c, s2)	-> s1 ^ c ^ s2
57 50
 	| Not t			-> "not " ^ string_of_term t
58  
-	| BPred (x, vl) -> x^"("^(String.concat "," (List.map(fun x -> param_to_string x)vl))^")"
  51
+	| BPred (x, vl) -> x^"("^(String.concat "," vl)^")"
59 52
 ;;
60 53
 
61 54
 (* support function for smart stringify of the AST - see to_string below *)
407  lexer.ml
@@ -7,37 +7,40 @@
7 7
 # 8 "lexer.ml"
8 8
 let __ocaml_lex_tables = {
9 9
   Lexing.lex_base = 
10  
-   "\000\000\234\255\003\000\030\000\240\255\241\255\242\255\243\255\
11  
-    \014\000\048\000\246\255\078\000\156\000\182\000\004\001\082\001\
12  
-    \160\001\254\255\255\255\238\001\060\002\138\002\216\002\253\255\
13  
-    \242\002\245\255\244\255\235\255\237\255\236\255";
  10
+   "\000\000\232\255\003\000\030\000\238\255\239\255\240\255\241\255\
  11
+    \014\000\048\000\244\255\078\000\156\000\182\000\004\001\082\001\
  12
+    \160\001\238\001\254\255\255\255\060\002\138\002\216\002\038\003\
  13
+    \253\255\116\003\142\003\243\255\242\255\233\255\235\255\234\255\
  14
+    ";
14 15
   Lexing.lex_backtrk = 
15  
-   "\255\255\255\255\017\000\016\000\255\255\255\255\255\255\255\255\
16  
-    \255\255\255\255\255\255\008\000\006\000\255\255\004\000\003\000\
17  
-    \006\000\255\255\255\255\007\000\006\000\006\000\006\000\255\255\
18  
-    \005\000\255\255\255\255\255\255\255\255\255\255";
  16
+   "\255\255\255\255\019\000\018\000\255\255\255\255\255\255\255\255\
  17
+    \255\255\255\255\255\255\010\000\008\000\255\255\005\000\004\000\
  18
+    \003\000\008\000\255\255\255\255\009\000\008\000\008\000\008\000\
  19
+    \255\255\006\000\007\000\255\255\255\255\255\255\255\255\255\255\
  20
+    ";
19 21
   Lexing.lex_default = 
20 22
    "\255\255\000\000\255\255\255\255\000\000\000\000\000\000\000\000\
21 23
     \255\255\255\255\000\000\255\255\255\255\255\255\255\255\255\255\
22  
-    \255\255\000\000\000\000\255\255\255\255\255\255\255\255\000\000\
23  
-    \255\255\000\000\000\000\000\000\000\000\000\000";
  24
+    \255\255\255\255\000\000\000\000\255\255\255\255\255\255\255\255\
  25
+    \000\000\255\255\255\255\000\000\000\000\000\000\000\000\000\000\
  26
+    ";
24 27
   Lexing.lex_trans = 
25 28
    "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
26  
-    \000\000\018\000\017\000\000\000\000\000\000\000\000\000\000\000\
  29
+    \000\000\019\000\018\000\000\000\000\000\000\000\000\000\000\000\
27 30
     \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
28 31
     \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\
29  
-    \018\000\000\000\000\000\013\000\000\000\000\000\000\000\000\000\
  32
+    \019\000\000\000\000\000\013\000\000\000\000\000\000\000\000\000\
30 33
     \006\000\005\000\000\000\000\000\007\000\011\000\010\000\001\000\
31 34
     \015\000\015\000\015\000\015\000\015\000\015\000\015\000\015\000\
32  
-    \015\000\015\000\009\000\026\000\003\000\004\000\002\000\008\000\
33  
-    \029\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
  35
+    \015\000\015\000\009\000\028\000\003\000\004\000\002\000\008\000\
  36
+    \031\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
34 37
     \014\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
35 38
     \014\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
36  
-    \014\000\014\000\014\000\028\000\027\000\025\000\000\000\011\000\
  39
+    \014\000\014\000\014\000\030\000\029\000\027\000\000\000\016\000\
37 40
     \000\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
38 41
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
39 42
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
40  
-    \012\000\016\000\012\000\011\000\000\000\000\000\011\000\011\000\
  43
+    \012\000\017\000\012\000\011\000\000\000\000\000\011\000\011\000\
41 44
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
42 45
     \000\000\000\000\000\000\000\000\000\000\000\000\000\000\011\000\
43 46
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
@@ -47,26 +50,26 @@ let __ocaml_lex_tables = {
47 50
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
48 51
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
49 52
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
50  
-    \011\000\019\000\000\000\000\000\019\000\019\000\019\000\019\000\
51  
-    \019\000\019\000\019\000\019\000\019\000\019\000\000\000\000\000\
52  
-    \000\000\000\000\000\000\000\000\000\000\019\000\019\000\019\000\
53  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
54  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
55  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\000\000\
56  
-    \000\000\000\000\000\000\019\000\000\000\012\000\012\000\012\000\
  53
+    \011\000\020\000\000\000\000\000\020\000\020\000\020\000\020\000\
  54
+    \020\000\020\000\020\000\020\000\020\000\020\000\000\000\000\000\
  55
+    \000\000\000\000\000\000\000\000\000\000\020\000\020\000\020\000\
  56
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  57
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  58
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\000\000\
  59
+    \000\000\000\000\000\000\020\000\000\000\012\000\012\000\012\000\
57 60
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
58 61
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
59  
-    \012\000\012\000\012\000\012\000\012\000\012\000\012\000\024\000\
60  
-    \024\000\024\000\024\000\024\000\024\000\024\000\024\000\024\000\
61  
-    \024\000\024\000\024\000\024\000\024\000\024\000\024\000\024\000\
62  
-    \024\000\024\000\024\000\024\000\024\000\024\000\024\000\024\000\
63  
-    \024\000\019\000\000\000\000\000\019\000\019\000\019\000\019\000\
64  
-    \019\000\019\000\019\000\019\000\019\000\019\000\000\000\000\000\
65  
-    \000\000\000\000\000\000\000\000\000\000\019\000\019\000\019\000\
66  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
67  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
68  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\000\000\
69  
-    \000\000\000\000\000\000\019\000\000\000\014\000\014\000\014\000\
  62
+    \012\000\012\000\012\000\012\000\012\000\012\000\012\000\026\000\
  63
+    \026\000\026\000\026\000\026\000\026\000\026\000\026\000\026\000\
  64
+    \026\000\026\000\026\000\026\000\026\000\026\000\026\000\026\000\
  65
+    \026\000\026\000\026\000\026\000\026\000\026\000\026\000\026\000\
  66
+    \026\000\020\000\000\000\000\000\020\000\020\000\020\000\020\000\
  67
+    \020\000\020\000\020\000\020\000\020\000\020\000\000\000\000\000\
  68
+    \000\000\000\000\000\000\000\000\000\000\020\000\020\000\020\000\
  69
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  70
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  71
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\000\000\
  72
+    \000\000\000\000\000\000\020\000\000\000\014\000\014\000\014\000\
70 73
     \014\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
71 74
     \014\000\014\000\014\000\014\000\014\000\014\000\014\000\014\000\
72 75
     \014\000\014\000\014\000\014\000\014\000\014\000\014\000\011\000\
@@ -79,60 +82,79 @@ let __ocaml_lex_tables = {
79 82
     \000\000\011\000\000\000\011\000\011\000\011\000\011\000\011\000\
80 83
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
81 84
     \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
82  
-    \011\000\011\000\011\000\011\000\011\000\019\000\000\000\000\000\
83  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
84  
-    \019\000\019\000\000\000\000\000\000\000\000\000\000\000\000\000\
85  
-    \000\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
86  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
87  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
88  
-    \019\000\019\000\019\000\000\000\000\000\000\000\000\000\019\000\
89  
-    \000\000\020\000\012\000\012\000\012\000\012\000\012\000\012\000\
  85
+    \011\000\011\000\011\000\011\000\011\000\011\000\000\000\000\000\
  86
+    \011\000\011\000\011\000\011\000\011\000\011\000\011\000\011\000\
  87
+    \011\000\011\000\000\000\000\000\000\000\000\000\000\000\000\000\
  88
+    \000\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  89
+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  90
+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  91
+    \025\000\025\000\025\000\000\000\000\000\000\000\000\000\011\000\
  92
+    \000\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  93
+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  94
+    \025\000\025\000\025\000\025\000\025\000\025\000\025\000\025\000\
  95
+    \025\000\025\000\025\000\020\000\000\000\000\000\020\000\020\000\
  96
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  97
+    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\
  98
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  99
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  100
+    \020\000\020\000\020\000\020\000\020\000\020\000\020\000\020\000\
  101
+    \020\000\000\000\000\000\000\000\000\000\020\000\000\000\021\000\
  102
+    \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
90 103
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
91 104
     \012\000\012\000\012\000\012\000\012\000\012\000\012\000\012\000\
92  
-    \012\000\012\000\012\000\019\000\000\000\000\000\019\000\019\000\
93  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
94  
-    \000\000\000\000\000\000\000\000\000\000\000\000\000\000\019\000\
95  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
96  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\
97  
-    \019\000\019\000\019\000\019\000\019\000\019\000\019\000\019\000\