| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | % -*- Mode: Prolog -*- | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % This Prolog to SQL compiler may be distributed free of charge provided that it is | 
					
						
							|  |  |  | % not used in commercial applications without written consent of the author, and | 
					
						
							|  |  |  | % that the copyright notice remains unchanged. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %                    (C) Copyright by Christoph Draxler, Munich | 
					
						
							|  |  |  | %                        Version 1.1 of Dec. 21st 1992 | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % I would like to keep in my hands the further development and distribution of the | 
					
						
							|  |  |  | % compiler. This does not mean that I don't want other people to suggest or even | 
					
						
							|  |  |  | % implement improvements - quite on the contrary: I greatly appreciate contributions  | 
					
						
							|  |  |  | % and if they make sense to me I will incorporate them into the compiler (with due | 
					
						
							|  |  |  | % credits given!).  | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % For further development of the compiler, address your requests, comments and | 
					
						
							|  |  |  | % criticism to the author: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %                    Christoph Draxler | 
					
						
							|  |  |  | %                    CIS Centre for Information and Speech Processing | 
					
						
							|  |  |  | %                    Ludwig-Maximilians-University Munich | 
					
						
							|  |  |  | %                    Wagmuellerstr. 23  | 
					
						
							|  |  |  | %                    D 80538 Munich | 
					
						
							|  |  |  | %                    Tel : ++49 / +89 / 211 06 64 (-60) | 
					
						
							|  |  |  | %                    Fax : ++49 / +89 / 211 06 74 | 
					
						
							|  |  |  | %                    Mail: draxler@cis.uni-muenchen.de | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % A report describing the implementation is available upon request from the | 
					
						
							|  |  |  | % author.  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % RELEASE INFORMATION | 
					
						
							|  |  |  | % =================== | 
					
						
							|  |  |  | % Current version is v. 1.1 of Dec. 21st 1992. | 
					
						
							|  |  |  | % Version 1.0 Sept. 3 1992 | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | :- module(myddas_prolog2sql,[ | 
					
						
							|  |  |  | 			     translate/3, | 
					
						
							|  |  |  | 			     queries_atom/2 | 
					
						
							|  |  |  | 			    ]). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | :- use_module(lists,[ | 
					
						
							|  |  |  | 		     append/3, | 
					
						
							|  |  |  | 		     member/2 | 
					
						
							|  |  |  | 		     ]). | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | :- use_module(myddas_prolog2sql_optimizer,[ | 
					
						
							|  |  |  | 					   optimize_sql/2 | 
					
						
							|  |  |  | 					  ]). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Top level predicate translate/3 organizes the compilation and constructs a | 
					
						
							|  |  |  | % Prolog term representation of the SQL query.  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-03 18:02:29 +00:00
										 |  |  | #ifdef MYDDAS_STATS | 
					
						
							|  |  |  | translate(ProjectionTerm,DatabaseGoal,SQLQueryTermOpt):- | 
					
						
							|  |  |  | 	c_db_stats_walltime(Start), | 
					
						
							|  |  |  | 	translate_(ProjectionTerm,DatabaseGoal,SQLQueryTermOpt), | 
					
						
							|  |  |  | 	c_db_stats_walltime(End), | 
					
						
							|  |  |  | 	c_db_stats_translate(Start,End). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-03 18:02:29 +00:00
										 |  |  | translate_(ProjectionTerm,DatabaseGoal,SQLQueryTermOpt):- | 
					
						
							|  |  |  | #else | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | translate(ProjectionTerm,DatabaseGoal,SQLQueryTermOpt):- | 
					
						
							| 
									
										
										
										
											2006-05-03 18:02:29 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    % --- initialize variable identifiers and range variables for relations ----- | 
					
						
							|  |  |  |    init_gensym(var), | 
					
						
							|  |  |  |    init_gensym(rel), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % --- tokenize projection term and database goal ---------------------------- | 
					
						
							|  |  |  |    tokenize_term(DatabaseGoal,TokenDatabaseGoal), | 
					
						
							|  |  |  |    tokenize_term(ProjectionTerm,TokenProjectionTerm), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % --- lexical analysis: reordering of goals for disjunctive normalized form - | 
					
						
							|  |  |  |    disjunction(TokenDatabaseGoal,Disjunction), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % --- code generation --------------------------------------------------------------- | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    query_generation(Disjunction,TokenProjectionTerm,SQLQueryTerm), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    % --- optimize sql ------------------------------------------------------------------ | 
					
						
							|  |  |  |    optimize_sql(SQLQueryTerm,SQLQueryTermOpt). | 
					
						
							| 
									
										
										
										
											2007-05-20 21:33:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | % --- disjunction(Goal,Disjunction) ---------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % turns original goal into disjunctive normalized form by computing all conjunctions | 
					
						
							|  |  |  | % and collecting them in a list | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | disjunction(Goal,Disjunction):- | 
					
						
							|  |  |  |    findall(Conjunction,linearize(Goal,Conjunction),Disjunction). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- linearize(Goal,ConjunctionList) -------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Returns a conjunction of base goals for a complex disjunctive or conjunctive goal | 
					
						
							|  |  |  | % Yields several solutions upon backtracking for disjunctive goals | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | linearize(((A,B),C),(LinA,(LinB,LinC))):- | 
					
						
							|  |  |  |    % --- transform left-linear to right-linear conjunction (',' is associative) ---- | 
					
						
							|  |  |  |    linearize(A,LinA), | 
					
						
							|  |  |  |    linearize(B,LinB), | 
					
						
							|  |  |  |    linearize(C,LinC). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | linearize((A,B),(LinA,LinB)):- | 
					
						
							|  |  |  |    A \= (_,_), | 
					
						
							|  |  |  |    % --- make sure A is not a conjunction ------------------------------------------ | 
					
						
							|  |  |  |    linearize(A,LinA), | 
					
						
							|  |  |  |    linearize(B,LinB). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | %linearize((A;B),LinA):- | 
					
						
							|  |  |  | linearize((A;_),LinA):- | 
					
						
							|  |  |  |    linearize(A,LinA). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | %linearize((A;B),LinB):- | 
					
						
							|  |  |  | linearize((_;B),LinB):- | 
					
						
							|  |  |  |    linearize(B,LinB). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | linearize(not A, not LinA):- | 
					
						
							|  |  |  |    linearize(A,LinA). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | linearize(Var^A, Var^LinA):- | 
					
						
							|  |  |  |    linearize(A,LinA). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | linearize(A,A):- | 
					
						
							|  |  |  |    A \= (_,_), | 
					
						
							|  |  |  |    A \= (_;_), | 
					
						
							|  |  |  |    A \= _^_, | 
					
						
							|  |  |  |    A \= not(_). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- tokenize_term(Term,TokenizedTerm) ------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % If Term is a  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - variable, then this variable is instantiated with a unique identifier  | 
					
						
							|  |  |  | %    of the form '$var$'(VarId), and TokenizedTerm is bound to the same  | 
					
						
							|  |  |  | %    term '$var$'(VarId).  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - constant, then TokenizedTerm is bound to '$const$'(Term). | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - complex term, then the term is decomposed, its arguments are tokenized, | 
					
						
							|  |  |  | %    and TokenizedTerm is bound to the result of the composition of the original | 
					
						
							|  |  |  | %    functor and the tokenized arguments. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_term('$var$'(VarId),'$var$'(VarId)):- | 
					
						
							|  |  |  |    var(VarId), | 
					
						
							|  |  |  |    % --- uninstantiated variable: instantiate it with unique identifier. | 
					
						
							|  |  |  |    gensym(var,VarId). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_term('$var$'(VarId),'$var$'(VarId)):- | 
					
						
							|  |  |  |    nonvar(VarId). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_term(Constant,'$const$'(Constant)):- | 
					
						
							|  |  |  |    nonvar(Constant), | 
					
						
							|  |  |  |    functor(Constant,_,0). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_term(Term,TokenizedTerm):- | 
					
						
							|  |  |  |    nonvar(Term), | 
					
						
							|  |  |  |    Term \= '$var$'(_), | 
					
						
							|  |  |  |    Term \= '$const$'(_), | 
					
						
							|  |  |  |    Term =.. [Functor|Arguments], | 
					
						
							|  |  |  |    Arguments \= [], | 
					
						
							|  |  |  |    tokenize_arguments(Arguments,TokenArguments), | 
					
						
							|  |  |  |    TokenizedTerm =.. [Functor|TokenArguments]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- tokenize_arguments(Arguments,TokenizedArguments) --------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % organizes tokenization of arguments by traversing list and calling tokenize_term | 
					
						
							|  |  |  | % for each element of the list. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_arguments([],[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | tokenize_arguments([FirstArg|RestArgs],[TokFirstArg|TokRestArgs]):- | 
					
						
							|  |  |  |    tokenize_term(FirstArg,TokFirstArg), | 
					
						
							|  |  |  |    tokenize_arguments(RestArgs,TokRestArgs). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- query_generation(ListOfConjunctions, ProjectionTerm, ListOfQueries) --------------  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % For each Conjunction translate the pair (ProjectionTerm,Conjunction) to an SQL query | 
					
						
							|  |  |  | % and connect each such query through a UNION-operator to result in the ListOfQueries. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % A Conjunction consists of positive or negative subgoals. Each subgoal is translated  | 
					
						
							|  |  |  | % as follows: | 
					
						
							|  |  |  | %  - the functor of a goal that is not a comparison operation is translated to | 
					
						
							|  |  |  | %    a relation name with a range variable | 
					
						
							|  |  |  | %  - negated goals are translated to NOT EXISTS-subqueries with * projection | 
					
						
							|  |  |  | %  - comparison operations are translated to comparison operations in the WHERE-clause | 
					
						
							|  |  |  | %  - aggregate function terms are translated to aggregate function (sub)queries | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % The arguments of a goal are translated as follows: | 
					
						
							|  |  |  | %  - variables of a goal are translated to qualified attributes | 
					
						
							|  |  |  | %  - variables occurring in several goals are translated to equality comparisons | 
					
						
							|  |  |  | %    (equi join) in the WHERE-clause | 
					
						
							|  |  |  | %  - constant arguments are translated to equality comparisons in the WHERE-clause | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % Special treatment of arithmetic functions: | 
					
						
							|  |  |  | %  - arithmetic functions are identified through the Prolog is/2 operator | 
					
						
							|  |  |  | %  - an arithmetic function may contain an unbound variable only on its left side | 
					
						
							|  |  |  | %  - the right side of the is/2 operator may consist of  | 
					
						
							|  |  |  | %    * bound variables (bound through occurrence within a positive database goal, or  | 
					
						
							|  |  |  | %      bound through preceeding arithmetic function), or of  | 
					
						
							|  |  |  | %    * constants (numbers, i.e. integers, reals) | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % The following RESTRICTION holds: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - the binding of variables follows Prolog: variables are bound by positive base goals | 
					
						
							|  |  |  | %    and on the left side of the is/2 predicate - comparison operations, negated goals | 
					
						
							|  |  |  | %    and right sides of the is/2 predicate do not return variable bindings and may even  | 
					
						
							|  |  |  | %    require all arguments to be bound for a safe evaluation. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | query_generation([],_,[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | query_generation([Conjunction|Conjunctions],ProjectionTerm,[Query|Queries]):- | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | 	projection_term_variables(ProjectionTerm,InitDict), | 
					
						
							|  |  |  | 	( Conjunction =.. [once|Arguments] -> | 
					
						
							|  |  |  | 	    [Args] = Arguments,  | 
					
						
							|  |  |  | 	    translate_conjunction(Args,SQLFrom,SQLWhereTemp,InitDict,Dict), | 
					
						
							|  |  |  | 	    append(SQLWhereTemp,[once],SQLWhere) | 
					
						
							|  |  |  | 	; | 
					
						
							|  |  |  | 	    translate_conjunction(Conjunction,SQLFrom,SQLWhere,InitDict,Dict) | 
					
						
							|  |  |  | 	), | 
					
						
							|  |  |  | 	translate_projection(ProjectionTerm,Dict,SQLSelect), | 
					
						
							|  |  |  | 	Query = query(SQLSelect,SQLFrom,SQLWhere), | 
					
						
							|  |  |  | 	query_generation(Conjunctions,ProjectionTerm,Queries). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_goal(Goal,SQLFrom,SQLWhere,Dict,NewDict) ------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % translates a | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %   - positive database goal to the associated FROM- and WHERE clause of an SQL query | 
					
						
							|  |  |  | %   - a negated goal to a negated existential subquery | 
					
						
							|  |  |  | %   - an arithmetic goal to an arithmetic expression or an aggregate function query | 
					
						
							|  |  |  | %   - a comparison goal to a comparison expression | 
					
						
							|  |  |  | %   - a negated comparison goal to a comparison expression with the opposite comparison | 
					
						
							|  |  |  | %     operator | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | translate_goal(SimpleGoal,[SQLFrom],SQLWhere,Dict,NewDict):- | 
					
						
							|  |  |  |    % --- positive goal binds variables - these bindings are held in the dictionary ----- | 
					
						
							|  |  |  |    functor(SimpleGoal,Functor,Arity), | 
					
						
							|  |  |  |    translate_functor(Functor,Arity,SQLFrom), | 
					
						
							|  |  |  |    SimpleGoal =.. [Functor|Arguments], | 
					
						
							|  |  |  |    translate_arguments(Arguments,SQLFrom,1,SQLWhere,Dict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_goal(Result is Expression,[],SQLWhere,Dict,NewDict):- | 
					
						
							|  |  |  |    translate_arithmetic_function(Result,Expression,SQLWhere,Dict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_goal(not NegatedGoals,[],SQLNegatedSubquery,Dict,Dict):- | 
					
						
							|  |  |  |    % --- negated goals do not bind variables - hence Dict is returned unchanged -------- | 
					
						
							|  |  |  |    functor(NegatedGoals,Functor,_), | 
					
						
							|  |  |  |    not comparison(Functor,_), | 
					
						
							|  |  |  |    translate_conjunction(NegatedGoals,SQLFrom,SQLWhere,Dict,_), | 
					
						
							|  |  |  |    SQLNegatedSubquery = [negated_existential_subquery([*],SQLFrom,SQLWhere)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_goal(not ComparisonGoal,[],SQLCompOp,Dict,Dict):- | 
					
						
							|  |  |  |    % --- comparison operations do not bind variables - Dict is returned unchanged ------ | 
					
						
							|  |  |  |    ComparisonGoal =.. [ComparisonOperator,LeftArg,RightArg], | 
					
						
							|  |  |  |    comparison(ComparisonOperator,SQLOperator), | 
					
						
							|  |  |  |    negated_comparison(SQLOperator,SQLNegOperator), | 
					
						
							|  |  |  |    translate_comparison(LeftArg,RightArg,SQLNegOperator,Dict,SQLCompOp). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | %% EXAMPLE: db_prolog_select([Gene1],(once((eval(Gene1,_,_),exists(eval(Gene1),eval(Gene1,_,_)))))). | 
					
						
							|  |  |  | translate_goal(exists(ProjectionTerm,ExistsGoals),SQLFrom,SQLExistsSubquery,Dict,Dict):- | 
					
						
							|  |  |  |    % --- exists goals do not bind variables - hence Dict is returned unchanged -------- | 
					
						
							|  |  |  |    functor(ExistsGoals,Functor,_), | 
					
						
							|  |  |  |    not comparison(Functor,_), | 
					
						
							|  |  |  |    translate_projection(ProjectionTerm,Dict,SQLSelect), | 
					
						
							|  |  |  |    translate_conjunction(ExistsGoals,SQLFrom,SQLWhere,Dict,_), | 
					
						
							|  |  |  |    SQLExistsSubquery = [existential_subquery(SQLSelect,SQLFrom,SQLWhere)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_goal(exists(ExistsGoals),SQLFrom,SQLExistsSubquery,Dict,Dict):- | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  |    % --- exists goals do not bind variables - hence Dict is returned unchanged -------- | 
					
						
							|  |  |  |    functor(ExistsGoals,Functor,_), | 
					
						
							|  |  |  |    not comparison(Functor,_), | 
					
						
							|  |  |  |    translate_conjunction(ExistsGoals,SQLFrom,SQLWhere,Dict,_), | 
					
						
							|  |  |  |    SQLExistsSubquery = [existential_subquery([*],SQLFrom,SQLWhere)]. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | translate_goal(ComparisonGoal,[],SQLCompOp,Dict,Dict):- | 
					
						
							|  |  |  |    % --- comparison operations do not bind variables - Dict is returned unchanged ------ | 
					
						
							|  |  |  |    ComparisonGoal =.. [ComparisonOperator,LeftArg,RightArg], | 
					
						
							|  |  |  |    comparison(ComparisonOperator,SQLOperator), | 
					
						
							|  |  |  |    translate_comparison(LeftArg,RightArg,SQLOperator,Dict,SQLCompOp). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %DISTINCT | 
					
						
							|  |  |  | translate_goal(distinct(Goal),List,SQL,Dict,DistinctDict):-!, | 
					
						
							|  |  |  | 	translate_goal(Goal,List,SQL,Dict,NewDict), | 
					
						
							|  |  |  | 	add_distinct_statement(NewDict,DistinctDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %DEBUG | 
					
						
							|  |  |  | add_distinct_statement(Dict,Dict):- | 
					
						
							| 
									
										
										
										
											2005-12-19 13:41:15 +00:00
										 |  |  | 	append([_],[1,2],_). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_conjunction(Conjunction,SQLFrom,SQLWhere,Dict,NewDict) ----------------- | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % translates a conjunction of goals (represented as a list of goals preceeded by  | 
					
						
							|  |  |  | % existentially quantified variables) to FROM- and WHERE-clause of an SQL query.   | 
					
						
							|  |  |  | % A dictionary containing the associated SQL table and attribute names is built up | 
					
						
							|  |  |  | % as an accumulator pair (arguments Dict and NewDict) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_conjunction('$var$'(VarId)^Goal,SQLFrom,SQLWhere,Dict,NewDict):- | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | #ifdef DEBUG_TRANSLATE | 
					
						
							|  |  |  |    write('translate_conjuntion clause 1'),nl, | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | % --- add info on existentially quantified variables to dictionary here ------------- | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    add_to_dictionary(VarId,_,_,_,existential,Dict,TmpDict), | 
					
						
							|  |  |  |    translate_conjunction(Goal,SQLFrom,SQLWhere,TmpDict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_conjunction(Goal,SQLFrom,SQLWhere,Dict,NewDict):- | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | #ifdef DEBUG_TRANSLATE | 
					
						
							|  |  |  |    write('translate_conjuntion clause 2'),nl, | 
					
						
							|  |  |  | #endif | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    Goal \= (_,_), | 
					
						
							|  |  |  |    translate_goal(Goal,SQLFrom,SQLWhere,Dict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_conjunction((Goal,Conjunction),SQLFrom,SQLWhere,Dict,NewDict):- | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | #ifdef DEBUG_TRANSLATE | 
					
						
							|  |  |  | 	write('translate_conjuntion clause 3'),nl, | 
					
						
							|  |  |  | #endif | 
					
						
							|  |  |  | 	translate_goal(Goal,FromBegin,WhereBegin,Dict,TmpDict), | 
					
						
							|  |  |  | 	translate_conjunction(Conjunction,FromRest,WhereRest,TmpDict,NewDict), | 
					
						
							|  |  |  | 	append(FromBegin,FromRest,SQLFrom), | 
					
						
							|  |  |  | 	append(WhereBegin,WhereRest,SQLWhere). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_arithmetic_function(Result,Expression,SQLWhere,Dict,NewDict) ----------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Arithmetic functions (left side of is/2 operator is bound to value of expression on | 
					
						
							|  |  |  | % right side) may be called with either | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % - Result unbound: then Result is bound to the value of the evaluation of Expression | 
					
						
							|  |  |  | % - Result bound: then an equality condition is returned between the value of Result | 
					
						
							|  |  |  | %   and the value of the evaluation of Expression. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Only the equality test shows up in the WHERE clause of an SQLquery. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arithmetic_function('$var$'(VarId),Expression,[],Dict,NewDict):- | 
					
						
							|  |  |  |    % assigment of value of arithmetic expression to variable - does not | 
					
						
							|  |  |  |    % show up in WHERE-part, but expression corresponding to | 
					
						
							|  |  |  |    % variable must be stored in Dict for projection translation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    evaluable_expression(Expression,Dict,ArithExpression,Type), | 
					
						
							|  |  |  |    add_to_dictionary(VarId,is,ArithExpression,Type,all,Dict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arithmetic_function('$var$'(VarId),Expression,ArithComparison,Dict,Dict):- | 
					
						
							|  |  |  |    % --- test whether left side evaluates to right side: return equality comparison ---- | 
					
						
							|  |  |  |    % Left side consists of qualified attribute, i.e. range variable must not be | 
					
						
							|  |  |  |    % arithmetic operator is/2  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    lookup(VarId,Dict,PrevRangeVar,PrevAtt,_), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    not (PrevRangeVar = is), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % test whether type of attribute is numeric - if not, there's no sense in  | 
					
						
							|  |  |  |    % continuing the translation | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(PrevType,number), | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    evaluable_expression(Expression,Dict,ArithExpression,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(ExprType,number), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    ArithComparison = [comp(att(PrevRangeVar,PrevAtt),'=',ArithExpression)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arithmetic_function('$var$'(VarId),Expression,ArithComparison,Dict,Dict):- | 
					
						
							|  |  |  |    % --- test whether left side evaluates to right side: return equality comparison ---- | 
					
						
							|  |  |  |    % Left side consists of arithmetic expression, i.e. VarId is stored in Dict as  | 
					
						
							|  |  |  |    % belonging to arithmetic expression which is expressed as RangeVar-argument  | 
					
						
							|  |  |  |    % of lookup returning is/2. Type information is implicit through the is/2 functor | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    lookup(VarId,Dict,is,LeftExpr,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(Type,number), | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    evaluable_expression(Expression,Dict,RightExpr,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(ExprType,number), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    ArithComparison = [comp(LeftExpr,'=',RightExpr)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arithmetic_function('$const$'(Constant),Expression,ArithComparison,Dict,Dict):- | 
					
						
							|  |  |  |    % --- is/2 used to test whether left side evaluates to right side ------------------- | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    get_type('$const$'(Constant),_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(ConstantType,number), | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    evaluable_expression(Expression,Dict,ArithExpression,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(ExprType,number), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    ArithComparison = [comp('$const$'(Constant),'=',ArithExpression)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_comparison(LeftArg,RightArg,CompOp,Dict,SQLComparison) --------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % translates the left and right arguments of a comparison term into the | 
					
						
							|  |  |  | % appropriate comparison operation in SQL. The result type of each  | 
					
						
							|  |  |  | % argument expression is checked for type compatibility | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_comparison(LeftArg,RightArg,CompOp,Dict,Comparison):- | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    evaluable_expression(LeftArg,Dict,LeftTerm,_), | 
					
						
							|  |  |  |    evaluable_expression(RightArg,Dict,RightTerm,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %type_compatible(LeftArgType,RightArgType), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    Comparison = [comp(LeftTerm,CompOp,RightTerm)]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_functor(Functor,QualifiedTableName) ------------------------------------ | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % translate_functor searches for the matching relation table name for | 
					
						
							|  |  |  | % a given functor and creates a unique range variable to result in | 
					
						
							|  |  |  | % a unique qualified relation table name. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_functor(Functor,Arity,rel(TableName,RangeVariable)):- | 
					
						
							|  |  |  |    relation(Functor,Arity,TableName), | 
					
						
							|  |  |  |    gensym(rel,RangeVariable). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_arguments(Arguments,RelTable,ArgPos,Conditions,Dict) ------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % translate_arguments organizes the translation of term arguments. One | 
					
						
							|  |  |  | % term argument after the other is taken from the list of term arguments | 
					
						
							|  |  |  | % until the list is exhausted.  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arguments([],_,_,[],Dict,Dict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_arguments([Arg|Args],SQLTable,Position,SQLWhere,Dict,NewDict):- | 
					
						
							|  |  |  |    translate_argument(Arg,SQLTable,Position,Where,Dict,TmpDict), | 
					
						
							|  |  |  |    NewPosition is Position + 1, | 
					
						
							|  |  |  |    translate_arguments(Args,SQLTable,NewPosition,RestWhere,TmpDict,NewDict), | 
					
						
							|  |  |  |    append(Where,RestWhere,SQLWhere). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_argument(Argument,RelTable,Position,Condition,Dict) -------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % The first occurrence of a variable leads to its associated SQL attribute information | 
					
						
							|  |  |  | % to be recorded in the Dict. Any further occurrence creates an equi-join condition  | 
					
						
							|  |  |  | % between the current attribute and the previously recorded attribute. | 
					
						
							|  |  |  | % Constant arguments always translate to equality comparisons between an attribute and  | 
					
						
							|  |  |  | % the constant value. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_argument('$var$'(VarId),rel(SQLTable,RangeVar),Position,[],Dict,NewDict):- | 
					
						
							|  |  |  |    attribute(Position,SQLTable,Attribute,Type), | 
					
						
							|  |  |  |    add_to_dictionary(VarId,RangeVar,Attribute,Type,all,Dict,NewDict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_argument('$var$'(VarId),rel(SQLTable,RangeVar),Position,AttComparison,Dict,Dict):- | 
					
						
							|  |  |  |    % --- Variable occurred previously - retrieve first occurrence data from dictionary - | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    lookup(VarId,Dict,PrevRangeVar,PrevAtt,_), | 
					
						
							|  |  |  |    attribute(Position,SQLTable,Attribute,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    % type_compatible(PrevType,Type), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    AttComparison = [comp(att(RangeVar,Attribute),=,att(PrevRangeVar,PrevAtt))]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_argument('$const$'(Constant),rel(SQLTable,RangeVar),Position,ConstComparison,Dict,Dict):- | 
					
						
							|  |  |  |    % --- Equality comparison of constant value and attribute in table ------------------ | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  |    attribute(Position,SQLTable,Attribute,_), | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  |    %get_type('$const$'(Constant),ConstType), | 
					
						
							|  |  |  |    %type_compatible(ConstType,Type), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    ConstComparison = [comp(att(RangeVar,Attribute),=,'$const$'(Constant))]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- projection_term_variables(ProjectionTerm,Dict) ----------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % extracts all variables from the ProjectionTerm and places them into the | 
					
						
							|  |  |  | % Dict as a dict/4 term with their Identifier, a non instantiated RangeVar and  | 
					
						
							|  |  |  | % Attribute argument, and the keyword existential for the type of quantification | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %% ERRO?? | 
					
						
							|  |  |  | %projection_term_variables('$const(_)$',[]). | 
					
						
							|  |  |  | projection_term_variables('$const$'(_),[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | projection_term_variables('$var$'(VarId),[dict(VarId,_,_,_,existential)]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | projection_term_variables(ProjectionTerm,ProjectionTermVariables):- | 
					
						
							|  |  |  |    ProjectionTerm =.. [Functor|ProjectionTermList], | 
					
						
							|  |  |  |    not (Functor = '$var$'), | 
					
						
							|  |  |  |    not (ProjectionTermList = []), | 
					
						
							|  |  |  |    projection_list_vars(ProjectionTermList,ProjectionTermVariables). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | projection_list_vars([],[]). | 
					
						
							|  |  |  | projection_list_vars(['$var$'(VarId)|RestArgs],[dict(VarId,_,_,_,existential)|RestVars]):- | 
					
						
							|  |  |  |    projection_list_vars(RestArgs,RestVars). | 
					
						
							|  |  |  | projection_list_vars(['$const$'(_)|RestArgs],Vars):- | 
					
						
							|  |  |  |    projection_list_vars(RestArgs,Vars). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | % RESTRICTION! ProjectionTerm underlies the following restrictions: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - ProjectionTerm must have a functor other than the built-in | 
					
						
							|  |  |  | %    operators, i.e. ',',';', etc. are not allowed | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - only variables and constants are allowed as arguments, | 
					
						
							|  |  |  | %    i.e. no structured terms | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_projection('$var$'(VarId),Dict,SelectList):- | 
					
						
							|  |  |  |    projection_arguments(['$var$'(VarId)],SelectList,Dict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_projection('$const$'(Const),_,['$const$'(Const)]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_projection(ProjectionTerm,Dict,SelectList):- | 
					
						
							|  |  |  |    ProjectionTerm =.. [Functor|Arguments], | 
					
						
							|  |  |  |    not (Functor = '$var$'), | 
					
						
							|  |  |  |    not (Functor = '$const$'), | 
					
						
							|  |  |  |    not (Arguments = []), | 
					
						
							|  |  |  |    projection_arguments(Arguments,SelectList,Dict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | projection_arguments([],[],_). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | projection_arguments([Arg|RestArgs],[Att|RestAtts],Dict):- | 
					
						
							|  |  |  |    retrieve_argument(Arg,Att,Dict), | 
					
						
							|  |  |  |    projection_arguments(RestArgs,RestAtts,Dict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % - retrieve_argument(Argument,SQLAttribute,Dictionary) -------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % retrieves the mapping of an argument to the appropriate SQL construct, i.e. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  - qualified attribute names for variables in base goals | 
					
						
							|  |  |  | %  - arithmetic expressions for variables in arithmetic goals | 
					
						
							|  |  |  | %  - constant values for constants | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | retrieve_argument('$var$'(VarId),Attribute,Dict):- | 
					
						
							|  |  |  |    lookup(VarId,Dict,TableName,AttName,_), | 
					
						
							|  |  |  |    ( | 
					
						
							|  |  |  |     TableName = is -> | 
					
						
							|  |  |  |       Attribute = AttName | 
					
						
							|  |  |  |    ; | 
					
						
							|  |  |  |       Attribute = att(TableName,AttName) | 
					
						
							|  |  |  |    ). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | retrieve_argument('$const$'(Constant),'$const$'(Constant),_). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- lookup(Key,Dict,Value) ----------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | lookup(VarId,Dict,RangeVar,Attribute,Type):- | 
					
						
							|  |  |  |    member(dict(VarId,RangeVar,Attribute,Type,Quant),Dict), | 
					
						
							|  |  |  |    ( | 
					
						
							|  |  |  |     Quant = all -> | 
					
						
							|  |  |  |       true | 
					
						
							|  |  |  |    ; | 
					
						
							|  |  |  |       nonvar(RangeVar), | 
					
						
							|  |  |  |       nonvar(Attribute) | 
					
						
							|  |  |  |    ). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- add_to_dictionary(Key,RangeVar,Attribute,Quantifier,Dict,NewDict) ---------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | add_to_dictionary(Key,RangeVar,Attribute,Type,_,Dict,Dict):- | 
					
						
							|  |  |  |    member(dict(Key,RangeVar,Attribute,Type,existential),Dict). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | add_to_dictionary(Key,RangeVar,Attribute,Type,Quantifier,Dict,NewDict):- | 
					
						
							|  |  |  |    not member(dict(Key,_,_,_,_),Dict), | 
					
						
							|  |  |  |    NewDict = [dict(Key,RangeVar,Attribute,Type,Quantifier)|Dict]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- aggregate_function(AggregateFunctionTerm,Dict,AggregateFunctionQuery) ------------ | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % aggregate_function discerns five Prolog aggregate function terms: count, avg, min, | 
					
						
							|  |  |  | % max, and sum. Each such term is has two arguments: a variable indicating the attribute | 
					
						
							|  |  |  | % over which the function is to be computed, and a goal argument which must contain in  | 
					
						
							|  |  |  | % at least one argument position the variable: | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %    e.g.  avg(Seats,plane(Type,Seats)) | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % These aggregate function terms correspond to the SQL built-in aggregate functions. | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % RESTRICTION: AggregateGoal may only be conjunction of (positive or negative) base  | 
					
						
							|  |  |  | % goals | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | aggregate_function(AggregateFunctionTerm,Dict,AggregateFunctionExpression):- | 
					
						
							|  |  |  |    AggregateFunctionTerm =..[AggFunctor,AggVar,AggGoal], | 
					
						
							|  |  |  |    aggregate_functor(AggFunctor,SQLFunction), | 
					
						
							|  |  |  |    conjunction(AggGoal,AggConjunction), | 
					
						
							|  |  |  |    aggregate_query_generation(SQLFunction,AggVar,AggConjunction,Dict,AggregateFunctionExpression). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | conjunction(Goal,Conjunction):- | 
					
						
							|  |  |  |    disjunction(Goal,[Conjunction]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- aggregate_query_generation(Function,FunctionVariable,AggGoal,Dict,AggregateQuery)  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % compiles the function variable (representing the attribute over which the aggregate  | 
					
						
							|  |  |  | % function is to be computed) and the aggregate goal (representing the selection and  | 
					
						
							|  |  |  | % join conditions for the computation of the aggregate function) to an SQL aggregate  | 
					
						
							|  |  |  | % function subquery. | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | % aggregate_query_generation(count,'$const$'('*'),AggGoal,Dict,AggregateQuery):- | 
					
						
							|  |  |  | %    translate_conjunction(AggGoal,SQLFrom,SQLWhere,Dict,TmpDict), | 
					
						
							|  |  |  | %   AggregateQuery = agg_query(Function,(count,['$const$'(*)]),SQLFrom,SQLWhere,[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | aggregate_query_generation(count,'$const$'('*'),AggGoal,Dict,AggregateQuery):- | 
					
						
							|  |  |  |    translate_conjunction(AggGoal,SQLFrom,SQLWhere,Dict,_), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % ATTENTION! It is assumed that in count(*) aggregate query terms there cannot be | 
					
						
							|  |  |  |    % free variables because '*' stands for "all arguments" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    AggregateQuery = agg_query(_,(count,['$const$'(*)]),SQLFrom,SQLWhere,[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | %DISTINCT | 
					
						
							|  |  |  | aggregate_query_generation(countdistinct,'$const$'('*'),AggGoal,Dict,AggregateQuery):- | 
					
						
							|  |  |  |    translate_conjunction(AggGoal,SQLFrom,SQLWhere,Dict,_), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % ATTENTION! It is assumed that in count(*) aggregate query terms there cannot be | 
					
						
							|  |  |  |    % free variables because '*' stands for "all arguments" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    AggregateQuery = agg_query(_,(countdistinct,['$const$'(*)]),SQLFrom,SQLWhere,[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | aggregate_query_generation(Function,FunctionVariable,AggGoal,Dict,AggregateQuery):- | 
					
						
							|  |  |  |    translate_conjunction(AggGoal,SQLFrom,SQLWhere,Dict,TmpDict), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    % --- only variables occurring in the aggregate goal are relevant to the translation | 
					
						
							|  |  |  |    % of the function variable and the free variables in the goal. | 
					
						
							|  |  |  |    % Thus subtract from TmpDict all entries of Dict | 
					
						
							|  |  |  |    set_difference(TmpDict,Dict,AggDict), | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |    translate_projection(FunctionVariable,AggDict,SQLSelect), | 
					
						
							|  |  |  |    translate_grouping(FunctionVariable,AggDict,SQLGroup), | 
					
						
							|  |  |  |    AggregateQuery = agg_query(Function,SQLSelect,SQLFrom,SQLWhere,SQLGroup). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_grouping(FunctionVariable,Dict,SQLGroup) ------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % finds the free variables in the aggregate function term and collects their | 
					
						
							|  |  |  | % corresponding SQL qualified attributes in the SQLGroup list. | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_grouping(FunctionVariable,Dict,SQLGroup):- | 
					
						
							|  |  |  |    free_vars(FunctionVariable,Dict,FreeVariables), | 
					
						
							|  |  |  |    translate_free_vars(FreeVariables,SQLGroup). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- free_vars(FunctionVariable,Dict,FreeVarList) ------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % A Variable is free if it neither occurs as the FunctionVariable, nor is stored as | 
					
						
							|  |  |  | % existentially quantified (through ^/2 in the original goal) in the dictionary | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % FreeVars contains for each variable the relevant attribute and relation information  | 
					
						
							|  |  |  | % contained in the dictionary | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | % free_vars(FunctionVariable,Dict,FreeVarList):- | 
					
						
							|  |  |  | %   projection_term_variables(FunctionVariable,FunctionVariableList), | 
					
						
							|  |  |  | %   findall((Var,Table,Attribute), | 
					
						
							|  |  |  | %       (member(dict(Var,Table,Attribute,Type,all),Dict), | 
					
						
							|  |  |  | %        not member(dict(Var,_,_,_,_),FunctionVariableList) | 
					
						
							|  |  |  | %       ), | 
					
						
							|  |  |  | %       FreeVarList). | 
					
						
							|  |  |  | free_vars(FunctionVariable,Dict,FreeVarList):- | 
					
						
							|  |  |  |   projection_term_variables(FunctionVariable,FunctionVariableList), | 
					
						
							|  |  |  |   findall((Var,Table,Attribute), | 
					
						
							|  |  |  |       (member(dict(Var,Table,Attribute,_,all),Dict), | 
					
						
							|  |  |  |        not member(dict(Var,_,_,_,_),FunctionVariableList) | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |       FreeVarList). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- function_variable_list(FunctionVariable,FunctionVariableList) -------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % extracts the list of variables which occur in the function variable term | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % RESTRICTION: FunctionVariable may only contain one single variable. | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function_variable_list('$var$'(VarId),[VarId]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- translate_free_vars(FreeVars,SQLGroup) ------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % translates dictionary information on free variables to SQLGroup of aggregate | 
					
						
							|  |  |  | % function query | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | translate_free_vars([],[]). | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | %translate_free_vars([(VarId,Table,Attribute)|FreeVars],[att(Table,Attribute)|SQLGroups]):- | 
					
						
							|  |  |  | translate_free_vars([(_,Table,Attribute)|FreeVars],[att(Table,Attribute)|SQLGroups]):- | 
					
						
							|  |  |  |    translate_free_vars(FreeVars,SQLGroups). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- evaluable_expression(ExpressionTerm,Dictionary,Expression,Type) -------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % evaluable_expression constructs SQL arithmetic expressions with qualified attribute names | 
					
						
							|  |  |  | % from the Prolog arithmetic expression term and the information stored in the dictionary. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % The type of an evaluable function is returned in the argument Type. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % The dictionary is not changed because it is used for lookup only.  | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression(AggregateFunctionTerm,Dictionary,AggregateFunctionExpression,number):- | 
					
						
							|  |  |  |    aggregate_function(AggregateFunctionTerm,Dictionary,AggregateFunctionExpression). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression(LeftExp + RightExp,Dictionary,LeftAr + RightAr,number):- | 
					
						
							|  |  |  |    evaluable_expression(LeftExp,Dictionary,LeftAr,number), | 
					
						
							|  |  |  |    evaluable_expression(RightExp,Dictionary,RightAr,number). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression(LeftExp - RightExp,Dictionary,LeftAr - RightAr,number):- | 
					
						
							|  |  |  |    evaluable_expression(LeftExp,Dictionary,LeftAr,number), | 
					
						
							|  |  |  |    evaluable_expression(RightExp,Dictionary,RightAr,number). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression(LeftExp * RightExp,Dictionary,LeftAr * RightAr,number):- | 
					
						
							|  |  |  |    evaluable_expression(LeftExp,Dictionary,LeftAr,number), | 
					
						
							|  |  |  |    evaluable_expression(RightExp,Dictionary,RightAr,number). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression(LeftExp / RightExp,Dictionary, LeftAr / RightAr,number):- | 
					
						
							|  |  |  |    evaluable_expression(LeftExp,Dictionary,LeftAr,number), | 
					
						
							|  |  |  |    evaluable_expression(RightExp,Dictionary,RightAr,number). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression('$var$'(VarId),Dictionary,att(RangeVar,Attribute),Type):- | 
					
						
							|  |  |  |    lookup(VarId,Dictionary,RangeVar,Attribute,Type), | 
					
						
							|  |  |  |    RangeVar \= is. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression('$var$'(VarId),Dictionary,ArithmeticExpression,Type):- | 
					
						
							|  |  |  |    lookup(VarId,Dictionary,is,ArithmeticExpression,Type). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | evaluable_expression('$const$'(Const),_,'$const$'(Const),ConstType):- | 
					
						
							|  |  |  |    get_type('$const$'(Const),ConstType). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Output to screen predicates - rather crude at the moment | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- printqueries(Code) --------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | printqueries([Query]):- | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_query(Query), | 
					
						
							|  |  |  |    write(';'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    nl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | printqueries([Query|Queries]):- | 
					
						
							|  |  |  |    not (Queries = []), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_query(Query), | 
					
						
							|  |  |  |    nl, | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  |    write('UNION '), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    nl, | 
					
						
							|  |  |  |    printqueries(Queries). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- print_query(QueryCode) ----------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_query(query([agg_query(Function,Select,From,Where,Group)],_,_)):- | 
					
						
							|  |  |  |    % --- ugly rule here: aggregate function only in SELECT Part of query ---- | 
					
						
							|  |  |  |    !, | 
					
						
							|  |  |  |    print_query(agg_query(Function,Select,From,Where,Group)). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_query(query(Select,From,Where)):- | 
					
						
							|  |  |  |    print_clause('SELECT',Select,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('FROM',From,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('WHERE',Where,'AND'), | 
					
						
							|  |  |  |    nl. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_query(agg_query(Function,Select,From,Where,Group)):- | 
					
						
							|  |  |  |    print_clause('SELECT',Function,Select,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('FROM',From,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('WHERE',Where,'AND'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('GROUP BY',Group,','). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_query(negated_existential_subquery(Select,From,Where)):- | 
					
						
							|  |  |  |    write('NOT EXISTS'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    write('('), | 
					
						
							|  |  |  |    print_clause('SELECT',Select,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('FROM',From,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('WHERE',Where,'AND'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    write(')'). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | print_query(existential_subquery(Select,From,Where)):- | 
					
						
							|  |  |  |    write('EXISTS'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    write('('), | 
					
						
							|  |  |  |    print_clause('SELECT',Select,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('FROM',From,','), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    print_clause('WHERE',Where,'AND'), | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    write(')'). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- print_clause(Keyword,ClauseCode,Separator) --------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % with  | 
					
						
							|  |  |  | % Keyword    one of SELECT, FROM, WHERE, or GROUP BY,  | 
					
						
							|  |  |  | % ClauseCode the code corresponding to the appropriate clause of an SQL query, and  | 
					
						
							|  |  |  | % Separator  indicating the character(s) through which the items of a clause | 
					
						
							|  |  |  | %            are separated from each other (',' or 'AND'). | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | % -------------------------------------------------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | % print_clause(Keyword,[],_). | 
					
						
							|  |  |  | print_clause(_,[],_). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_clause(Keyword,[Column|RestColumns],Separator):- | 
					
						
							|  |  |  |    write(Keyword), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    print_clause([Column|RestColumns],Separator). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_clause(Keyword,Function,[Column],Separator):- | 
					
						
							|  |  |  |    write(Keyword), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    write(Function), | 
					
						
							|  |  |  |    write('('), | 
					
						
							|  |  |  |    print_clause([Column],Separator), | 
					
						
							|  |  |  |    write(')'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- print_clause(ClauseCode,Separator) ----------------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_clause([Item],_):- | 
					
						
							|  |  |  |    print_column(Item). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_clause([Item,NextItem|RestItems],Separator):- | 
					
						
							|  |  |  |    print_column(Item), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    write(Separator), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    print_clause([NextItem|RestItems],Separator). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- print_column(ColumnCode) -------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column('*'):- | 
					
						
							|  |  |  |    write('*'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(att(RangeVar,Attribute)):- | 
					
						
							|  |  |  |    write(RangeVar), | 
					
						
							|  |  |  |    write('.'), | 
					
						
							|  |  |  |    write(Attribute). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(rel(Relation,RangeVar)):- | 
					
						
							|  |  |  |    write(Relation), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    write(RangeVar). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column('$const$'(String)):- | 
					
						
							|  |  |  |    get_type('$const$'(String),string), | 
					
						
							|  |  |  |    write('"'), | 
					
						
							|  |  |  |    write(String), | 
					
						
							|  |  |  |    write('"'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column('$const$'(Number)):- | 
					
						
							|  |  |  |    get_type('$const$'(Number),NumType), | 
					
						
							|  |  |  |    type_compatible(NumType,number), | 
					
						
							|  |  |  |    write(Number). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(comp(LeftArg,Operator,RightArg)):- | 
					
						
							|  |  |  |    print_column(LeftArg), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    write(Operator), | 
					
						
							|  |  |  |    write(' '), | 
					
						
							|  |  |  |    print_column(RightArg). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(LeftExpr * RightExpr):- | 
					
						
							|  |  |  |    print_column(LeftExpr), | 
					
						
							|  |  |  |    write('*'), | 
					
						
							|  |  |  |    print_column(RightExpr). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(LeftExpr / RightExpr):- | 
					
						
							|  |  |  |    print_column(LeftExpr), | 
					
						
							|  |  |  |    write('/'), | 
					
						
							|  |  |  |    print_column(RightExpr). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(LeftExpr + RightExpr):- | 
					
						
							|  |  |  |    print_column(LeftExpr), | 
					
						
							|  |  |  |    write('+'), | 
					
						
							|  |  |  |    print_column(RightExpr). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(LeftExpr - RightExpr):- | 
					
						
							|  |  |  |    print_column(LeftExpr), | 
					
						
							|  |  |  |    write('-'), | 
					
						
							|  |  |  |    print_column(RightExpr). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(agg_query(Function,Select,From,Where,Group)):- | 
					
						
							|  |  |  |    nl, | 
					
						
							|  |  |  |    write('('), | 
					
						
							|  |  |  |    print_query(agg_query(Function,Select,From,Where,Group)), | 
					
						
							|  |  |  |    write(')'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | print_column(negated_existential_subquery(Select,From,Where)):- | 
					
						
							|  |  |  |    print_query(negated_existential_subquery(Select,From,Where)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | print_column(existential_subquery(Select,From,Where)):- | 
					
						
							|  |  |  |    print_query(existential_subquery(Select,From,Where)). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- queries_atom(Queries,QueryAtom) ----------------------------  | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % queries_atom(Queries,QueryAtom) returns in its second argument | 
					
						
							|  |  |  | % the SQL query as a Prolog atom. For efficiency reasons, a list | 
					
						
							|  |  |  | % of ASCII codes is ceated as a difference list, and it is then  | 
					
						
							|  |  |  | % transformed to an atom by name/2 | 
					
						
							|  |  |  | % ----------------------------------------------------------------  | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  | #ifdef MYDDAS_STATS | 
					
						
							|  |  |  | queries_atom(Queries,QueryAtom):- | 
					
						
							|  |  |  | 	c_db_stats_walltime(Start), | 
					
						
							|  |  |  | 	queries_atom_(Queries,QueryAtom), | 
					
						
							|  |  |  | 	c_db_stats_walltime(End), | 
					
						
							|  |  |  | 	c_db_stats_translate(Start,End). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  | queries_atom_(Queries,QueryAtom):- | 
					
						
							|  |  |  | #else | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | queries_atom(Queries,QueryAtom):- | 
					
						
							| 
									
										
										
										
											2006-06-09 18:32:01 +00:00
										 |  |  | #endif | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    queries_atom(Queries,QueryList,[]), | 
					
						
							|  |  |  |    name(QueryAtom,QueryList). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | queries_atom([Query],QueryList,Diff):- | 
					
						
							|  |  |  |    query_atom(Query,QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | queries_atom([Query|Queries],QueryList,Diff):- | 
					
						
							|  |  |  |    Queries \= [], | 
					
						
							|  |  |  |    query_atom(Query,QueryList,X1), | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  |    column_atom('UNION ',X1,X2), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    queries_atom(Queries,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- query_atom(QueryCode) -------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | query_atom(query([agg_query(Function,Select,From,Where,Group)],_,_),QueryList,Diff):- | 
					
						
							|  |  |  |    % --- ugly rule here: aggregate function only in SELECT Part of query ---- | 
					
						
							|  |  |  |    !, | 
					
						
							|  |  |  |    query_atom(agg_query(Function,Select,From,Where,Group),QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | query_atom(query(Select,From,Where),QueryList,Diff):- | 
					
						
							|  |  |  |    clause_atom('SELECT',Select,',',QueryList,X1), | 
					
						
							|  |  |  |    clause_atom('FROM',From,',',X1,X2), | 
					
						
							|  |  |  |    clause_atom('WHERE',Where,'AND',X2,Diff). | 
					
						
							| 
									
										
										
										
											2006-01-26 18:52:49 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | query_atom(agg_query(Function,Select,From,Where,Group),QueryList,Diff):- | 
					
						
							|  |  |  |    clause_atom('SELECT',Function,Select,',',QueryList,X1), | 
					
						
							|  |  |  |    clause_atom('FROM',From,',',X1,X2), | 
					
						
							| 
									
										
										
										
											2006-02-05 02:19:15 +00:00
										 |  |  |    clause_atom('WHERE',Where,'AND',X2,X3), | 
					
						
							| 
									
										
										
										
											2006-01-17 18:07:06 +00:00
										 |  |  | %ILP : PARA NAO POR OS GROUP BYS. FAZER FLAG PARA ISTO | 
					
						
							| 
									
										
										
										
											2006-02-05 02:19:15 +00:00
										 |  |  |    clause_atom('GROUP BY',Group,',',X3,Diff). | 
					
						
							| 
									
										
										
										
											2006-01-25 20:40:21 +00:00
										 |  |  |     | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | query_atom(negated_existential_subquery(Select,From,Where),QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom('NOT EXISTS(',QueryList,X1),    | 
					
						
							|  |  |  |    clause_atom('SELECT',Select,',',X1,X2), | 
					
						
							|  |  |  |    clause_atom('FROM',From,',',X2,X3), | 
					
						
							|  |  |  |    clause_atom('WHERE',Where,'AND',X3,X4), | 
					
						
							|  |  |  |    column_atom(')',X4,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | query_atom(existential_subquery(Select,From,Where),QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom('EXISTS(',QueryList,X1),    | 
					
						
							|  |  |  |    clause_atom('SELECT',Select,',',X1,X2), | 
					
						
							|  |  |  |    clause_atom('FROM',From,',',X2,X3), | 
					
						
							|  |  |  |    clause_atom('WHERE',Where,'AND',X3,X4), | 
					
						
							| 
									
										
										
										
											2006-01-16 21:00:12 +00:00
										 |  |  |    column_atom('LIMIT 1)',X4,Diff). | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- clause_atom(Keyword,ClauseCode,Junctor,CurrAtom,QueryAtom) ------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % with  | 
					
						
							|  |  |  | % Keyword    one of SELECT, FROM, WHERE, or GROUP BY,  | 
					
						
							|  |  |  | % ClauseCode the code corresponding to the appropriate clause of an SQL query, and  | 
					
						
							|  |  |  | % Junctor    indicating the character(s) through which the items of a clause | 
					
						
							|  |  |  | %            are separated from each other (',' or 'AND'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % ILP | 
					
						
							|  |  |  | % clause_atom(Keyword,[],_,QueryList,QueryList). | 
					
						
							|  |  |  | clause_atom(_,[],_,QueryList,QueryList). | 
					
						
							| 
									
										
										
										
											2006-01-26 18:52:49 +00:00
										 |  |  | % case there is no WHERE condition | 
					
						
							|  |  |  | clause_atom(_,[once],_,QueryList,Diff):-!, | 
					
						
							|  |  |  | 	column_atom(' ',QueryList,X1), | 
					
						
							|  |  |  | 	column_atom('LIMIT 1',X1,X2), | 
					
						
							|  |  |  | 	column_atom(' ',X2,Diff). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | clause_atom(Keyword,[Column|RestColumns],Junctor,QueryList,Diff):- | 
					
						
							| 
									
										
										
										
											2006-02-10 23:39:18 +00:00
										 |  |  | 	column_atom(Keyword,QueryList,X1), | 
					
						
							|  |  |  | 	column_atom(' ',X1,X2), | 
					
						
							|  |  |  | 	clause_atom([Column|RestColumns],Junctor,X2,X3), | 
					
						
							|  |  |  | 	column_atom(' ',X3,Diff). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | %DISTINCT | 
					
						
							|  |  |  | clause_atom(Keyword,'COUNTDISTINCT',[Column],Junctor,QueryList,Diff):-!, | 
					
						
							| 
									
										
										
										
											2006-01-17 18:07:06 +00:00
										 |  |  | 	column_atom(Keyword,QueryList,X1), | 
					
						
							|  |  |  | 	column_atom(' ',X1,X2), | 
					
						
							|  |  |  | 	column_atom('COUNT',X2,X3), | 
					
						
							|  |  |  | 	column_atom('(DISTINCT ',X3,X4), | 
					
						
							|  |  |  | 	clause_atom([Column],Junctor,X4,X5), | 
					
						
							|  |  |  | 	column_atom(') ',X5,Diff). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | clause_atom(Keyword,Function,[Column],Junctor,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(Keyword,QueryList,X1), | 
					
						
							|  |  |  |    column_atom(' ',X1,X2), | 
					
						
							|  |  |  |    column_atom(Function,X2,X3), | 
					
						
							|  |  |  |    column_atom('(',X3,X4), | 
					
						
							|  |  |  |    clause_atom([Column],Junctor,X4,X5), | 
					
						
							|  |  |  |    column_atom(') ',X5,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- clause_atom(ClauseCode,Junctor) -------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-26 18:52:49 +00:00
										 |  |  | clause_atom([once],_,QueryList,Diff):-!, | 
					
						
							|  |  |  | 	column_atom(' LIMIT 1 ',QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | clause_atom([Item],_,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(Item,QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | clause_atom([Item,NextItem|RestItems],Junctor,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(Item,QueryList,X1), | 
					
						
							|  |  |  |    column_atom(' ',X1,X2), | 
					
						
							| 
									
										
										
										
											2006-01-26 18:52:49 +00:00
										 |  |  |    ( NextItem = once -> | 
					
						
							|  |  |  |        X4 = X2 | 
					
						
							|  |  |  |    ; | 
					
						
							|  |  |  |        column_atom(Junctor,X2,X3), | 
					
						
							|  |  |  |        column_atom(' ',X3,X4) | 
					
						
							|  |  |  |    ), | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  |    clause_atom([NextItem|RestItems],Junctor,X4,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(att(RangeVar,Attribute),QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(RangeVar,QueryList,X1), | 
					
						
							|  |  |  |    column_atom('.',X1,X2), | 
					
						
							|  |  |  |    column_atom(Attribute,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(rel(Relation,RangeVar),QueryList,Diff):- | 
					
						
							| 
									
										
										
										
											2006-02-10 23:39:18 +00:00
										 |  |  | 	column_atom('`',QueryList,X0), | 
					
						
							|  |  |  | 	column_atom(Relation,X0,X1), | 
					
						
							|  |  |  | 	column_atom('` ',X1,X2), | 
					
						
							|  |  |  | 	column_atom(RangeVar,X2,Diff). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | column_atom('$const$'(String),QueryList,Diff):- | 
					
						
							|  |  |  |    get_type('$const$'(String),string), | 
					
						
							|  |  |  |    column_atom('"',QueryList,X1), | 
					
						
							|  |  |  |    column_atom(String,X1,X2), | 
					
						
							|  |  |  |    column_atom('"',X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom('$const$'(Number),QueryList,Diff):- | 
					
						
							|  |  |  |    get_type('$const$'(Number),NumType), | 
					
						
							|  |  |  |    type_compatible(NumType,number), | 
					
						
							|  |  |  |    column_atom(Number,QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(comp(LeftArg,Operator,RightArg),QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(LeftArg,QueryList,X1), | 
					
						
							|  |  |  |    column_atom(' ',X1,X2), | 
					
						
							|  |  |  |    column_atom(Operator,X2,X3), | 
					
						
							|  |  |  |    column_atom(' ',X3,X4), | 
					
						
							|  |  |  |    column_atom(RightArg,X4,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(LeftExpr * RightExpr,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(LeftExpr,QueryList,X1), | 
					
						
							|  |  |  |    column_atom('*',X1,X2), | 
					
						
							|  |  |  |    column_atom(RightExpr,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(LeftExpr + RightExpr,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(LeftExpr,QueryList,X1), | 
					
						
							|  |  |  |    column_atom('+',X1,X2), | 
					
						
							|  |  |  |    column_atom(RightExpr,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(LeftExpr - RightExpr,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(LeftExpr,QueryList,X1), | 
					
						
							|  |  |  |    column_atom('-',X1,X2), | 
					
						
							|  |  |  |    column_atom(RightExpr,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(LeftExpr / RightExpr,QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom(LeftExpr,QueryList,X1), | 
					
						
							|  |  |  |    column_atom('/',X1,X2), | 
					
						
							|  |  |  |    column_atom(RightExpr,X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(agg_query(Function,Select,From,Where,Group),QueryList,Diff):- | 
					
						
							|  |  |  |    column_atom('(',QueryList,X1), | 
					
						
							|  |  |  |    query_atom(agg_query(Function,Select,From,Where,Group),X1,X2), | 
					
						
							|  |  |  |    column_atom(')',X2,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(negated_existential_subquery(Select,From,Where),QueryList,Diff):- | 
					
						
							|  |  |  |    query_atom(negated_existential_subquery(Select,From,Where),QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-08 16:36:17 +00:00
										 |  |  | column_atom(existential_subquery(Select,From,Where),QueryList,Diff):- | 
					
						
							|  |  |  |    query_atom(existential_subquery(Select,From,Where),QueryList,Diff). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | column_atom(Atom,List,Diff):- | 
					
						
							|  |  |  |    atom(Atom), | 
					
						
							|  |  |  |    name(Atom,X1), | 
					
						
							|  |  |  |    append(X1,Diff,List). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | column_atom(Number,List,Diff) :- | 
					
						
							|  |  |  | 	number(Number), | 
					
						
							|  |  |  | 	name(Number,X1), | 
					
						
							|  |  |  | 	append(X1,Diff,List).	 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- gensym(Root,Symbol) ---------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % SEPIA 3.2. version - other Prolog implementations provide gensym/2 | 
					
						
							|  |  |  | % and init_gensym/1 as built-ins. */ | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % (C) Christoph Draxler, Aug. 1992 | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | %  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | init_gensym(Atom) :-  | 
					
						
							|  |  |  | 	set_value(Atom,'@'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | gensym(Atom,Var) :- | 
					
						
							|  |  |  |         var(Var), | 
					
						
							|  |  |  | 	get_value(Atom,Value), | 
					
						
							|  |  |  | 	char_code(Value,Code), | 
					
						
							|  |  |  |         NewCode is Code + 1, | 
					
						
							|  |  |  | 	char_code(Var,NewCode), | 
					
						
							|  |  |  |         set_value(Atom,Var). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- auxiliary predicates (some of them may be built-in... -------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | repeat_n(N):- | 
					
						
							|  |  |  |    integer(N), | 
					
						
							|  |  |  |    N > 0, | 
					
						
							|  |  |  |    repeat_1(N). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | repeat_1(1):-!. | 
					
						
							|  |  |  | repeat_1(_). | 
					
						
							|  |  |  | repeat_1(N):- | 
					
						
							|  |  |  |    N1 is N-1, | 
					
						
							|  |  |  |    repeat_1(N1). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- set_difference(SetA,SetB,Difference) -------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % SetA - SetB = Difference | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | set_difference([],_,[]). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | set_difference([Element|RestSet],Set,[Element|RestDifference]):- | 
					
						
							|  |  |  |    not member(Element,Set), | 
					
						
							|  |  |  |    set_difference(RestSet,Set,RestDifference). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | set_difference([Element|RestSet],Set,RestDifference):- | 
					
						
							|  |  |  |    member(Element,Set), | 
					
						
							|  |  |  |    set_difference(RestSet,Set,RestDifference). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- Mapping of Prolog operators to SQL operators ------------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | comparison(=,=). | 
					
						
							|  |  |  | comparison(<,<). | 
					
						
							| 
									
										
										
										
											2006-01-10 15:16:15 +00:00
										 |  |  | comparison(=<,'<='). | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | comparison(>=,'>='). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | comparison(>,>). | 
					
						
							|  |  |  | comparison(@<,<). | 
					
						
							|  |  |  | comparison(@>,>). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | negated_comparison(=,'<>'). | 
					
						
							|  |  |  | negated_comparison(\=,=). | 
					
						
							| 
									
										
										
										
											2006-01-10 15:16:15 +00:00
										 |  |  | negated_comparison(>,'<='). | 
					
						
							| 
									
										
										
										
											2005-11-22 11:25:59 +00:00
										 |  |  | negated_comparison(=<,>). | 
					
						
							|  |  |  | negated_comparison(<,>=). | 
					
						
							|  |  |  | negated_comparison(>=,<). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- aggregate_function(PrologFunctor,SQLFunction) ----------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | aggregate_functor(avg,'AVG'). | 
					
						
							|  |  |  | aggregate_functor(min,'MIN'). | 
					
						
							|  |  |  | aggregate_functor(max,'MAX'). | 
					
						
							|  |  |  | aggregate_functor(sum,'SUM'). | 
					
						
							|  |  |  | aggregate_functor(count,'COUNT'). | 
					
						
							|  |  |  | aggregate_functor(countdistinct,'COUNTDISTINCT'). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- type system -------------------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % A rudimentary type system is provided for consistency checking during the | 
					
						
							|  |  |  | % translation and for output formatting | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % The basic types are string and number. number has the subtypes integer and | 
					
						
							|  |  |  | % real. | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type_compatible(Type,Type):- | 
					
						
							|  |  |  |    is_type(Type). | 
					
						
							|  |  |  | type_compatible(SubType,Type):- | 
					
						
							|  |  |  |    subtype(SubType,Type). | 
					
						
							|  |  |  | type_compatible(Type,SubType):- | 
					
						
							|  |  |  |    subtype(SubType,Type). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- subtype(SubType,SuperType) ----------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Simple type hierarchy checking | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | subtype(SubType,SuperType):- | 
					
						
							|  |  |  |    is_subtype(SubType,SuperType). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | subtype(SubType,SuperType):- | 
					
						
							|  |  |  |    is_subtype(SubType,InterType), | 
					
						
							|  |  |  |    subtype(InterType,SuperType). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- is_type(Type) ------------------------------------------------------------ | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Type names | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | is_type(number). | 
					
						
							|  |  |  | is_type(integer). | 
					
						
							|  |  |  | is_type(real). | 
					
						
							|  |  |  | is_type(string). | 
					
						
							|  |  |  | is_type(natural). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- is_subtype(SubType,SuperType) -------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Simple type hierarchy for numeric types | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | is_subtype(integer,number). | 
					
						
							|  |  |  | is_subtype(real,number). | 
					
						
							|  |  |  | is_subtype(natural,integer). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | % --- get_type(Constant,Type) -------------------------------------------------- | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % Prolog implementation specific definition of type retrieval | 
					
						
							|  |  |  | % sepia Prolog version given here | 
					
						
							|  |  |  | % | 
					
						
							|  |  |  | % ------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_type('$const$'(Constant),integer):- | 
					
						
							|  |  |  |    integer(Constant),!. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_type('$const$'(Constant),real):- | 
					
						
							|  |  |  |    number(Constant),!. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | get_type('$const$'(Constant),string):- | 
					
						
							|  |  |  |    atom(Constant). | 
					
						
							| 
									
										
										
										
											2006-04-30 10:11:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 |