197 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			197 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								%  clp(q,r)                                         version 1.3.2 %
							 | 
						||
| 
								 | 
							
								%                                                                 %
							 | 
						||
| 
								 | 
							
								%  (c) Copyright 1992,1993,1994,1995                              %
							 | 
						||
| 
								 | 
							
								%  Austrian Research Institute for Artificial Intelligence (OFAI) %
							 | 
						||
| 
								 | 
							
								%  Schottengasse 3                                                %
							 | 
						||
| 
								 | 
							
								%  A-1010 Vienna, Austria                                         %
							 | 
						||
| 
								 | 
							
								%                                                                 %
							 | 
						||
| 
								 | 
							
								%  File:   expand.pl                                              %
							 | 
						||
| 
								 | 
							
								%  Author: Christian Holzbaur           christian@ai.univie.ac.at %
							 | 
						||
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								% Perform theory-purification in the presence of
							 | 
						||
| 
								 | 
							
								% interpreted terms.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- module( expand, [expand/0, noexpand/0]).
							 | 
						||
| 
								 | 
							
								:- dynamic expanding/0.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- multifile
							 | 
						||
| 
								 | 
							
									user:term_expansion/2,
							 | 
						||
| 
								 | 
							
									user:goal_expansion/3.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- dynamic
							 | 
						||
| 
								 | 
							
									user:term_expansion/2,
							 | 
						||
| 
								 | 
							
									user:goal_expansion/3.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								user:term_expansion(A,B) :-			% expands heads
							 | 
						||
| 
								 | 
							
									expanding,
							 | 
						||
| 
								 | 
							
									purify_head(A,B).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								user:goal_expansion(G,M,E):-			% expands bodies
							 | 
						||
| 
								 | 
							
									     M \== prolog, % quite common due to internal call_cleanups etc.
							 | 
						||
| 
								 | 
							
									     M \== expand,			% this file may get loaded more than once
							 | 
						||
| 
								 | 
							
									     expanding,
							 | 
						||
| 
								 | 
							
									     purify(G,M,E).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								noexpand :-
							 | 
						||
| 
								 | 
							
									retractall(expanding).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand :-
							 | 
						||
| 
								 | 
							
									assert(expanding).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								purify( Goal, Module, _) :- quoted( Goal, Module), !, fail.
							 | 
						||
| 
								 | 
							
								purify( Goal, _,      Expansion) :-
							 | 
						||
| 
								 | 
							
								  interpreted_relation( Goal, _Module),
							 | 
						||
| 
								 | 
							
								  !,
							 | 
						||
| 
								 | 
							
								  Expansion = {Goal}.
							 | 
						||
| 
								 | 
							
								purify( X=Y,  _Module, Expansion) :- !,		% shortcut for =/2
							 | 
						||
| 
								 | 
							
								  ( ( var(X) ; interpreted_term( X, Th) ),
							 | 
						||
| 
								 | 
							
								    ( var(Y) ; interpreted_term( Y, Th) ),
							 | 
						||
| 
								 | 
							
								    nonvar( Th) ->
							 | 
						||
| 
								 | 
							
								       Expansion = {X=Y}
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								       ra( X=Y, user, Pure, ThL, ThLTail),
							 | 
						||
| 
								 | 
							
								       ThL \== ThLTail,
							 | 
						||
| 
								 | 
							
								       ThLTail = [Pure],
							 | 
						||
| 
								 | 
							
								       l2conj( ThL, Expansion)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								purify( Goal, _Module, Expansion) :-
							 | 
						||
| 
								 | 
							
								  nobuiltin( Goal),
							 | 
						||
| 
								 | 
							
								  ra( Goal, user, Pure, ThL, ThLTail),
							 | 
						||
| 
								 | 
							
								  ThL \== ThLTail,				% ifunctors present ?
							 | 
						||
| 
								 | 
							
								  ThLTail = [Pure],
							 | 
						||
| 
								 | 
							
								  l2conj( ThL, Expansion).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								nobuiltin( Goal) :-
							 | 
						||
| 
								 | 
							
								  predicate_property( Goal, built_in),
							 | 
						||
| 
								 | 
							
								  !,
							 | 
						||
| 
								 | 
							
								  fail.
							 | 
						||
| 
								 | 
							
								nobuiltin( _).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								quoted( {_},			  _).
							 | 
						||
| 
								 | 
							
								quoted( run(_,_),		  geler).	% late goal of verify_attributes/3
							 | 
						||
| 
								 | 
							
								quoted( resubmit_eq(_), 	  nf).		%   some (all?) of its clients
							 | 
						||
| 
								 | 
							
								quoted( resubmit_lt(_), 	  nf).
							 | 
						||
| 
								 | 
							
								quoted( resubmit_le(_), 	  nf).
							 | 
						||
| 
								 | 
							
								quoted( resubmit_ne(_), 	  nf).
							 | 
						||
| 
								 | 
							
								quoted( wait_linear_retry(_,_,_), nf).
							 | 
						||
| 
								 | 
							
								quoted( fm_cp_filter(_,_,_),	  linear).	% generator in findall/3
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								quoted( printf(_),	     _).
							 | 
						||
| 
								 | 
							
								quoted( printf(_,_),	     _).
							 | 
						||
| 
								 | 
							
								quoted( user_tout(_,_,_,_),  _).		% undef pred
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								% Identify the theory (module) involved.
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								interpreted_term( X,		_) :- var(X), !, fail.
							 | 
						||
| 
								 | 
							
								interpreted_term( X,		linear) :- number(X).
							 | 
						||
| 
								 | 
							
								interpreted_term( rat(_,_),	linear).	% rational constant
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								interpreted_term( #(_), 	linear).	% Monash
							 | 
						||
| 
								 | 
							
								interpreted_term( -(_), 	linear).	% unary minus
							 | 
						||
| 
								 | 
							
								interpreted_term( +(_), 	linear).	%	plus
							 | 
						||
| 
								 | 
							
								interpreted_term( +(_,_),	linear).	% binary
							 | 
						||
| 
								 | 
							
								interpreted_term( -(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( *(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( /(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( pow(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( exp(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( ^(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( sin(_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( cos(_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( tan(_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( min(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( max(_,_),	linear).
							 | 
						||
| 
								 | 
							
								interpreted_term( abs(_),	linear).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								interpreted_relation( G,		_) :- var(G), !, fail.
							 | 
						||
| 
								 | 
							
								interpreted_relation( <(_,_),		linear).
							 | 
						||
| 
								 | 
							
								interpreted_relation( =<(_,_),		linear).
							 | 
						||
| 
								 | 
							
								interpreted_relation( <=(_,_),		linear). % Monash
							 | 
						||
| 
								 | 
							
								interpreted_relation( >(_,_),		linear).
							 | 
						||
| 
								 | 
							
								interpreted_relation( >=(_,_),		linear).
							 | 
						||
| 
								 | 
							
								interpreted_relation( =\=(_,_), 	linear).
							 | 
						||
| 
								 | 
							
								interpreted_relation( =:=(_,_), 	linear).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% ----------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								% replace alien subterms by variables
							 | 
						||
| 
								 | 
							
								% Special treatment for quote/1
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								ra( Term, _,  Pure) --> {var(Term), !, Term = Pure}.
							 | 
						||
| 
								 | 
							
								ra( Term, Th, Pure) -->
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    functor( Term, N, A),
							 | 
						||
| 
								 | 
							
								    functor( Pure, N, A)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  ra( A, Term, Th, Pure).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ra( 0, _,    _,  _) --> !.
							 | 
						||
| 
								 | 
							
								ra( N, Term, Th, Pure) -->
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    N1 is N-1,
							 | 
						||
| 
								 | 
							
								    arg( N, Term, Ta),
							 | 
						||
| 
								 | 
							
								    arg( N, Pure, Pa)
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  ra_one( Ta, Th, Pa),
							 | 
						||
| 
								 | 
							
								  ra( N1, Term, Th, Pure).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ra_one( Term,		 _,	       Pure) --> {var( Term), !, Pure=Term}.
							 | 
						||
| 
								 | 
							
								ra_one( quote(Term),	 _,	       Pure) --> {!, Pure=Term}.
							 | 
						||
| 
								 | 
							
								ra_one( Term,		 ParentTheory, Pure) -->
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    ( interpreted_term( Term, Theory) ->
							 | 
						||
| 
								 | 
							
									true
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
									Theory=user
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  ( { ParentTheory=Theory } ->
							 | 
						||
| 
								 | 
							
								      ra( Term, Theory, Pure)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								      ra_equate( Theory, Pure, ThPure),
							 | 
						||
| 
								 | 
							
								      ra( Term, Theory, ThPure)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ra_equate( user,    A, B) --> !, { A=B }.	% now
							 | 
						||
| 
								 | 
							
								ra_equate( _Theory, A, B) --> [ {A=B} ].		% later
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% ---------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								purify_head( Term, NewTerm) :-
							 | 
						||
| 
								 | 
							
								  ( prolog:dcg_expansion( Term, []/*undef layout*/, Exp, _) ->
							 | 
						||
| 
								 | 
							
								      true
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								      Term = Exp
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  ( Exp = ?-(_) ->				% don't touch these
							 | 
						||
| 
								 | 
							
								      fail
							 | 
						||
| 
								 | 
							
								  ; Exp = :-(_) ->				% expanded via goal_expansion
							 | 
						||
| 
								 | 
							
								      fail
							 | 
						||
| 
								 | 
							
								  ; Exp = (H:-B) ->
							 | 
						||
| 
								 | 
							
								      ra( H, user, NewHead, Cl, []),
							 | 
						||
| 
								 | 
							
								      Cl = [_|_],				% ifunctors in head ?
							 | 
						||
| 
								 | 
							
								      l2conj( Cl, Thc),
							 | 
						||
| 
								 | 
							
								      NewTerm = (NewHead:-Thc,B)
							 | 
						||
| 
								 | 
							
								  ;						% facts
							 | 
						||
| 
								 | 
							
								      ra( Exp, user, H, Cl, []),
							 | 
						||
| 
								 | 
							
								      Cl = [_|_],				% ifunctors in head ?
							 | 
						||
| 
								 | 
							
								      l2conj( Cl, B),
							 | 
						||
| 
								 | 
							
								      NewTerm = (H:-B)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								l2conj( [],	true).
							 | 
						||
| 
								 | 
							
								l2conj( [X|Xs], Conj) :-
							 | 
						||
| 
								 | 
							
								  ( Xs = [], Conj = X
							 | 
						||
| 
								 | 
							
								  ; Xs = [_|_], Conj = (X,Xc), l2conj( Xs, Xc)
							 | 
						||
| 
								 | 
							
								  ).
							 |