702 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
			
		
		
	
	
			702 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Prolog
		
	
	
	
	
	
| /*
 | |
| 	LPAD and CP-Logic reasoning suite
 | |
| 	File lpadsld.pl
 | |
| 	Goal oriented interpreter for LPADs based on SLDNF
 | |
| 	Copyright (c) 2007, Fabrizio Riguzzi
 | |
| */
 | |
| 
 | |
| :-dynamic rule/4,def_rule/2,setting/2.
 | |
| %:-yap_flag(gc_trace,very_verbose).
 | |
| %:-source.
 | |
| :-use_module(library(lists)).
 | |
| :-use_module(library(ugraphs)).
 | |
| 
 | |
| :-load_foreign_files(['cplint'],[],init_my_predicates).
 | |
| 
 | |
| :- op(1150, xfx, <- ).
 | |
| :- op(950,xfy, &).
 | |
| :- op(900,fy,~).
 | |
| :- op(1170,fx,prob).
 | |
| 
 | |
| /* start of list of parameters that can be set by the user with
 | |
| set(Parameter,Value) */
 | |
| setting(epsilon_parsing,0.00001).
 | |
| setting(save_dot,false).
 | |
| setting(ground_body,false). 
 | |
| /* available values: true, false
 | |
| if true, both the head and the body of each clause will be grounded, otherwise
 | |
| only the head is grounded. In the case in which the body contains variables 
 | |
| not appearing in the head, the body represents an existential event */
 | |
| setting(min_error,0.01).
 | |
| setting(depth_bound,4).
 | |
| setting(prob_threshold,0.00001).
 | |
| setting(prob_bound,0.01).
 | |
| 
 | |
| /* end of list of parameters */
 | |
| 
 | |
| /* s(GoalsLIst,Prob) compute the probability of a list of goals 
 | |
| GoalsLis can have variables, s returns in backtracking all the solutions with their
 | |
| corresponding probability */
 | |
| s(GoalsList,Prob):-
 | |
| 	solve(GoalsList,Prob).
 | |
| 
 | |
| 
 | |
| solve(GoalsList,Prob):-
 | |
| 	findall(Deriv,find_deriv(GoalsList,Deriv),L),
 | |
| 	build_formula(L,Formula,[],Var),
 | |
| 	var2numbers(Var,0,NewVar),
 | |
| 	(setting(save_dot,true)->
 | |
| 		format("Variables: ~p~n",[Var]),
 | |
| 		compute_prob(NewVar,Formula,Prob,1)
 | |
| 	;
 | |
| 		compute_prob(NewVar,Formula,Prob,0)
 | |
| 	).
 | |
| 
 | |
| solve(GoalsList,0.0):-
 | |
| 	\+ find_deriv(GoalsList,_Deriv).
 | |
| 
 | |
| /* s(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2) compute the probability of a list of goals 
 | |
| GoalsLis can have variables, s returns in backtracking all the solutions with 
 | |
| their corresponding probability 
 | |
| CPUTime1 is the cpu time for performing resolution
 | |
| CPUTime2 is the cpu time for elaborating the BDD 
 | |
| WallTime1 is the wall time for performing resolution
 | |
| WallTime2 is the wall time for elaborating the BDD */
 | |
| 
 | |
| 
 | |
| s(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):-
 | |
| 	solve(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2).
 | |
| 
 | |
| 
 | |
| solve(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):-
 | |
| 	statistics(cputime,[_,_]),
 | |
| 	statistics(walltime,[_,_]),
 | |
| 	findall(Deriv,find_deriv(GoalsList,Deriv),L)->
 | |
| 	statistics(cputime,[_,CT1]),
 | |
| 	CPUTime1 is CT1/1000,
 | |
| 	statistics(walltime,[_,WT1]),
 | |
| 	WallTime1 is WT1/1000,
 | |
| 	%print_mem,
 | |
| 	build_formula(L,Formula,[],Var,0,Conj),
 | |
| 	length(L,ND),
 | |
| 	length(Var,NV),
 | |
| 	format(user_error,"Disjunctions :~d~nConjunctions: ~d~nVariables ~d~n",[ND,Conj,NV]),
 | |
| 	var2numbers(Var,0,NewVar),
 | |
| 	(setting(save_dot,true)->
 | |
| 		format("Variables: ~p~n",[Var]),
 | |
| 		compute_prob(NewVar,Formula,Prob,1)
 | |
| 	;
 | |
| 		compute_prob(NewVar,Formula,Prob,0)
 | |
| 	),
 | |
| 	statistics(cputime,[_,CT2]),
 | |
| 	CPUTime2 is CT2/1000,
 | |
| 	statistics(walltime,[_,WT2]),
 | |
| 	WallTime2 is WT2/1000,
 | |
| 	format(user_error,"~nMemory after inference~n",[]).
 | |
| 	%print_mem.
 | |
| 
 | |
| print_mem:-
 | |
| 	statistics(global_stack,[GS,GSF]),
 | |
| 	statistics(local_stack,[LS,LSF]),
 | |
| 	statistics(heap,[HP,HPF]),
 | |
| 	statistics(trail,[TU,TF]),
 | |
| 	format(user_error,"~nGloabal stack used ~d execution stack free: ~d~n",[GS,GSF]),
 | |
| 	format(user_error,"Local stack used ~d execution stack free: ~d~n",[LS,LSF]),
 | |
| 	format(user_error,"Heap used ~d heap free: ~d~n",[HP,HPF]),
 | |
| 	format(user_error,"Trail used ~d Trail free: ~d~n",[TU,TF]).
 | |
| 
 | |
| find_deriv(GoalsList,Deriv):-
 | |
| 	solve(GoalsList,[],Deriv).
 | |
| %	remove_duplicates(DerivDup,Deriv). 
 | |
| 
 | |
| 
 | |
| /* duplicate can appear in the C set because two different unistantiated clauses may become the 
 | |
| same clause when instantiated */
 | |
| 
 | |
| /* sc(Goals,Evidence,Prob) compute the conditional probability of the list of goals
 | |
| Goals given the list of goals Evidence 
 | |
| Goals and Evidence can have variables, sc returns in backtracking all the solutions with their
 | |
| corresponding probability 
 | |
| */
 | |
| sc(Goals,Evidence,Prob):-
 | |
| 	solve_cond(Goals,Evidence,Prob).
 | |
| 
 | |
| solve_cond(Goals,Evidence,Prob):-
 | |
| 	findall(DerivE,find_deriv(Evidence,DerivE),LE),
 | |
| 	findall(DerivGE,find_deriv_GE(LE,Goals,DerivGE),LGE),
 | |
| 	%print_mem,
 | |
| 	build_formula(LE,FormulaE,[],VarE),
 | |
| 	var2numbers(VarE,0,NewVarE),
 | |
| 	build_formula(LGE,FormulaGE,[],VarGE),
 | |
| 	var2numbers(VarGE,0,NewVarGE),
 | |
| 	compute_prob(NewVarE,FormulaE,ProbE,0),
 | |
| 	call_compute_prob(NewVarGE,FormulaGE,ProbGE),
 | |
| 	(ProbE>0.0->
 | |
| 		Prob is ProbGE/ProbE
 | |
| 	;
 | |
| 		%print_mem,
 | |
| 		Prob=undefined
 | |
| 	),
 | |
| 	format(user_error,"~nMemory after inference~n",[]).
 | |
| 	%print_mem.
 | |
| 
 | |
| /* sc(Goals,Evidence,Prob,Time1,Time2) compute the conditional probability of the list of goals
 | |
| Goals given the list of goals Evidence 
 | |
| Goals and Evidence can have variables, sc returns in backtracking all the solutions with their
 | |
| corresponding probability 
 | |
| Time1 is the time for performing resolution
 | |
| Time2 is the time for elaborating the two BDDs
 | |
| */
 | |
| sc(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):-
 | |
| 	solve_cond(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2).
 | |
| 
 | |
| solve_cond(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):-
 | |
| 	statistics(cputime,[_,_]),
 | |
| 	statistics(walltime,[_,_]),
 | |
| 	findall(DerivE,find_deriv(Evidence,DerivE),LE),
 | |
| 	findall(DerivGE,find_deriv_GE(LE,Goals,DerivGE),LGE),
 | |
| 	statistics(cputime,[_,CT1]),
 | |
| 	CPUTime1 is CT1/1000,
 | |
| 	statistics(walltime,[_,WT1]),
 | |
| 	WallTime1 is WT1/1000,
 | |
| 	build_formula(LE,FormulaE,[],VarE),
 | |
| 	var2numbers(VarE,0,NewVarE),
 | |
| 	build_formula(LGE,FormulaGE,[],VarGE),
 | |
| 	var2numbers(VarGE,0,NewVarGE),
 | |
| 	compute_prob(NewVarE,FormulaE,ProbE,0),
 | |
| 	call_compute_prob(NewVarGE,FormulaGE,ProbGE),
 | |
| 	(ProbE>0.0->
 | |
| 		Prob is ProbGE/ProbE,
 | |
| 		statistics(cputime,[_,CT2]),
 | |
| 		CPUTime2 is CT2/1000,
 | |
| 		statistics(walltime,[_,WT2]),
 | |
| 		WallTime2 is WT2/1000
 | |
| 	;
 | |
| 		Prob=undefined,
 | |
| 		statistics(cputime,[_,CT2]),
 | |
| 		CPUTime2 is CT2/1000,
 | |
| 		statistics(walltime,[_,WT2]),
 | |
| 		WallTime2 is WT2/1000
 | |
| 	).
 | |
| 
 | |
| solve_cond_goals(Goals,LE,0,Time1,0):-
 | |
| 	statistics(runtime,[_,_]),
 | |
| 	\+ find_deriv_GE(LE,Goals,_DerivGE),
 | |
| 	statistics(runtime,[_,T1]),
 | |
| 	Time1 is T1/1000.
 | |
| 
 | |
| call_compute_prob(NewVarGE,FormulaGE,ProbGE):-
 | |
| 	(setting(save_dot,true)->
 | |
| 		format("Variables: ~p~n",[NewVarGE]),
 | |
| 		compute_prob(NewVarGE,FormulaGE,ProbGE,1)
 | |
| 	;
 | |
| 		compute_prob(NewVarGE,FormulaGE,ProbGE,0)
 | |
| 	).
 | |
| 
 | |
| find_deriv_GE(LD,GoalsList,Deriv):-
 | |
| 	member(D,LD),
 | |
| 	solve(GoalsList,D,DerivDup),
 | |
| 	remove_duplicates(DerivDup,Deriv).
 | |
| 
 | |
| 
 | |
| /* solve(GoalsList,CIn,COut) takes a list of goals and an input C set
 | |
| and returns an output C set
 | |
| The C set is a list of triple (N,R,S) where
 | |
| - N is the index of the head atom used, starting from 0
 | |
| - R is the index of the non ground rule used, starting from 1
 | |
| - S is the substitution of rule R, in the form of a list whose elements
 | |
| 	are of the form 'VarName'=value
 | |
| */
 | |
| solve([],C,C):-!.
 | |
| 
 | |
| solve([\+ H|T],CIn,COut):-
 | |
| 	builtin(H),!,
 | |
| 	call((\+ H)),
 | |
| 	solve(T,CIn,COut).
 | |
| 
 | |
| solve([\+ H |T],CIn,COut):-!,
 | |
| 	list2and(HL,H),
 | |
| 	findall(D,solve(HL,CIn,D),L),
 | |
| 		choose_clauses(CIn,L,C1),	
 | |
| 		solve(T,C1,COut)
 | |
| 	.	
 | |
| solve([H|T],CIn,COut):-
 | |
| 	builtin(H),!,
 | |
| 	call(H),
 | |
| 	solve(T,CIn,COut).
 | |
| 
 | |
| solve([H|T],CIn,COut):-
 | |
| 	def_rule(H,B),
 | |
| 	append(B,T,NG),
 | |
| 	solve(NG,CIn,COut).
 | |
| 	
 | |
| solve([H|T],CIn,COut):-
 | |
| 	find_rule(H,(R,S,N),CIn),
 | |
| 	solve_pres(R,S,N,T,CIn,COut).
 | |
| 
 | |
| solve_pres(R,S,N,T,CIn,COut):-
 | |
| 	member_eq((N,R,S),CIn),!,
 | |
| 	solve(T,CIn,COut).
 | |
| 
 | |
| solve_pres(R,S,N,T,CIn,COut):-
 | |
| %	format("a",[]),
 | |
| 	solve(T,[(N,R,S)|CIn],COut).
 | |
| 
 | |
| /*
 | |
| solve_pres(R,S,N,T,CIn,COut):-
 | |
| 	append(CIn,[(N,R,S)],C1),
 | |
| 	solve(T,C1,COut).
 | |
| */
 | |
| 
 | |
| 	
 | |
| 	
 | |
| /* find_rule(G,(R,S,N),Body,C) takes a goal G and the current C set and
 | |
| returns the index R of a disjunctive rule resolving with G together with
 | |
| the index N of the resolving head, the substitution S and the Body of the 
 | |
| rule */
 | |
| find_rule(H,(R,S,N),C):-
 | |
| 	rule(H,_P,N,R,S,_NH,_Head),
 | |
| 	not_already_present_with_a_different_head(N,R,S,C).
 | |
| 
 | |
| not_already_present_with_a_different_head(_N,_R,_S,[]).
 | |
| 
 | |
| not_already_present_with_a_different_head(N,R,S,[(N1,R,S1)|T]):-
 | |
| 	not_different(N,N1,S,S1),!,
 | |
| 	not_already_present_with_a_different_head(N,R,S,T).
 | |
| 		
 | |
| not_already_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):-
 | |
| 	R\==R1,
 | |
| 	not_already_present_with_a_different_head(N,R,S,T).
 | |
| 
 | |
| 
 | |
| not_different(_N,_N1,S,S1):-
 | |
| 	S\=S1,!.	
 | |
| 
 | |
| not_different(N,N,S,S).
 | |
| 
 | |
| 
 | |
| 
 | |
| /* choose_clauses(CIn,LC,COut) takes as input the current C set and 
 | |
| the set of C sets for a negative goal and returns a new C set that 
 | |
| excludes all the derivations for the negative goals */
 | |
| choose_clauses(C,[],C).
 | |
| 
 | |
| choose_clauses(CIn,[D|T],COut):-
 | |
| 	set_diff(D,Cin,D1),
 | |
| 	member((N,R,S),D1),
 | |
| 	add_inc(N,R,S,CIn,T,COut).
 | |
| 
 | |
| 
 | |
| add_inc(N,R,S,CIn,T,COut):-
 | |
| 	already_present_with_a_different_head(N,R,S,CIn),!,
 | |
| 	choose_clauses(CIn,T,COut).
 | |
| 
 | |
| add_inc(N,R,S,CIn,T,COut):-
 | |
| 	\+ member((N,R,S),CIn),
 | |
|         new_head(N,R,S,N1),
 | |
| 	choose_clauses([(N1,R,S)|CIn],T,COut).
 | |
| 
 | |
| set_diff([H|_T],[H|_S],[]):-!.
 | |
| 
 | |
| set_diff([H|T],S,[H|R]):-
 | |
| 	set_diff(T,S,R).
 | |
| 
 | |
| set_diff(T,_S,T).
 | |
| 
 | |
| /*
 | |
| set_diff([H|T],[H|S],R):-!,
 | |
| 	set_diff(T,S,R).
 | |
| 
 | |
| set_diff(T,_S,T).
 | |
| */
 | |
| /*
 | |
| set_diff([],_S,[]).
 | |
| 
 | |
| set_diff([H|T],S,R):-
 | |
| 	member(H,S),!,
 | |
| 	set_diff(T,S,R).
 | |
| 
 | |
| set_diff([H|T],S,[H|R]):-
 | |
| 	set_diff(T,S,R).
 | |
| */
 | |
| /* select a head different from N for rule R with
 | |
| substitution S, return it in N1 */
 | |
| new_head(N,R,S,N1):-
 | |
| 	rule_by_num(R,S,Numbers,Head,_Body),
 | |
| 	Head\=uniform(_,_,_),!,
 | |
| 	nth0(N, Numbers, _Elem, Rest),
 | |
| 	member(N1,Rest).
 | |
| 
 | |
| already_present_with_a_different_head(N,R,S,[(NH,R,SH)|_T]):-
 | |
| 	S=SH,NH \= N,!.
 | |
| 
 | |
| already_present_with_a_different_head(N,R,S,[_H|T]):-
 | |
| 	already_present_with_a_different_head(N,R,S,T).
 | |
| 
 | |
| 
 | |
| 
 | |
| /* checks that a rule R with head N and selection S is already
 | |
| present in C (or a generalization of it is in C) */ 
 | |
| already_present(N,R,S,[(N,R,SH)|_T]):-
 | |
| 	S=SH.
 | |
| 
 | |
| already_present(N,R,S,[_H|T]):-
 | |
| 	already_present(N,R,S,T).
 | |
| 
 | |
| /* rem_dup_lists removes the C sets that are a superset of 
 | |
| another C sets further on in the list of C sets */
 | |
| /* rem_dup_lists removes the C sets that are a superset of 
 | |
| another C sets further on in the list of C sets */
 | |
| rem_dup_lists([],L,L).
 | |
| 
 | |
| rem_dup_lists([H|T],L0,L):-
 | |
| 	(member_subset(H,T);member_subset(H,L0)),!,
 | |
| 	rem_dup_lists(T,L0,L).
 | |
| 
 | |
| rem_dup_lists([H|T],L0,L):-
 | |
| 	rem_dup_lists(T,[H|L0],L).
 | |
| 
 | |
| member_subset(E,[H|_T]):-
 | |
| 	subset_my(H,E),!.
 | |
| 
 | |
| member_subset(E,[_H|T]):-
 | |
| 	member_subset(E,T).
 | |
| 
 | |
| 
 | |
| 
 | |
| /* predicates for building the formula to be converted into a BDD */
 | |
| 
 | |
| /* build_formula(LC,Formula,VarIn,VarOut) takes as input a set of C sets
 | |
| LC and a list of Variables VarIn and returns the formula and a new list
 | |
| of variables VarOut 
 | |
| Formula is of the form [Term1,...,Termn]
 | |
| Termi is of the form [Factor1,...,Factorm]
 | |
| Factorj is of the form (Var,Value) where Var is the index of
 | |
| the multivalued variable Var and Value is the index of the value
 | |
| */
 | |
| build_formula([],[],Var,Var,C,C).
 | |
| 
 | |
| build_formula([D|TD],[F|TF],VarIn,VarOut,C0,C1):-
 | |
| 	length(D,NC),
 | |
| 	C2 is C0+NC,
 | |
| 	%reverse(D,D1),
 | |
| 	D1=D,
 | |
| 	build_term(D1,F,VarIn,Var1),
 | |
| 	build_formula(TD,TF,Var1,VarOut,C2,C1).
 | |
| 
 | |
| build_formula([],[],Var,Var).
 | |
| 
 | |
| build_formula([D|TD],[F|TF],VarIn,VarOut):-
 | |
| 	build_term(D,F,VarIn,Var1),
 | |
| 	build_formula(TD,TF,Var1,VarOut).
 | |
| 
 | |
| 
 | |
| build_term([],[],Var,Var).
 | |
| 
 | |
| build_term([(_,pruned,_)|TC],TF,VarIn,VarOut):-!,
 | |
| 	build_term(TC,TF,VarIn,VarOut).
 | |
| 
 | |
| build_term([(N,R,S)|TC],[[NVar,N]|TF],VarIn,VarOut):-
 | |
| 	(nth0_eq(0,NVar,VarIn,(R,S))->
 | |
| 		Var1=VarIn
 | |
| 	;
 | |
| 		append(VarIn,[(R,S)],Var1),
 | |
| 		length(VarIn,NVar)
 | |
| 	),
 | |
| 	build_term(TC,TF,Var1,VarOut).
 | |
| 
 | |
| /* nth0_eq(PosIn,PosOut,List,El) takes as input a List,
 | |
| an element El and an initial position PosIn and returns in PosOut
 | |
| the position in the List that contains an element exactly equal to El
 | |
| */
 | |
| nth0_eq(N,N,[H|_T],El):-
 | |
| 	H==El,!.
 | |
| 
 | |
| nth0_eq(NIn,NOut,[_H|T],El):-
 | |
| 	N1 is NIn+1,
 | |
| 	nth0_eq(N1,NOut,T,El).
 | |
| 
 | |
| /* var2numbers converts a list of couples (Rule,Substitution) into a list
 | |
| of triples (N,NumberOfHeadsAtoms,ListOfProbabilities), where N is an integer 
 | |
| starting from 0 */
 | |
| var2numbers([],_N,[]).
 | |
| 
 | |
| var2numbers([(R,S)|T],N,[[N,ValNumber,Probs]|TNV]):-
 | |
| 	find_probs(R,S,Probs),
 | |
| 	length(Probs,ValNumber),
 | |
| 	N1 is N+1,
 | |
| 	var2numbers(T,N1,TNV).
 | |
| 
 | |
| find_probs(R,S,Probs):-
 | |
| 	rule_by_num(R,S,_N,Head,_Body),
 | |
| 	get_probs(Head,Probs).
 | |
| 	
 | |
| get_probs(uniform(_A:1/Num,_P,_Number),ListP):-
 | |
| 	Prob is 1/Num,
 | |
| 	list_el(Num,Prob,ListP).
 | |
| 
 | |
| get_probs([],[]).
 | |
| 
 | |
| get_probs([_H:P|T],[P1|T1]):-
 | |
| 	P1 is P,
 | |
| 	get_probs(T,T1).
 | |
| 
 | |
| list_el(0,_P,[]):-!.
 | |
| 
 | |
| list_el(N,P,[P|T]):-
 | |
| 	N1 is N-1,
 | |
| 	list_el(N1,P,T).
 | |
| 
 | |
| /* end of predicates for building the formula to be converted into a BDD */list_el(0,_P,[]):-!.
 | |
| 
 | |
| 
 | |
| /* start of predicates for parsing an input file containing a program */
 | |
| 
 | |
| /* p(File) parses the file File.cpl. It can be called more than once without 
 | |
| exiting yap */
 | |
| p(File):-
 | |
| 	parse(File).
 | |
| 
 | |
| parse(File):-
 | |
| 	atom_concat(File,'.cil',FilePl),
 | |
| 	open(FilePl,read,S),
 | |
| 	read_clauses(S,C),
 | |
| 	close(S),
 | |
| 	retractall(rule_by_num(_,_,_,_,_)),
 | |
| 	retractall(rule(_,_,_,_,_,_,_)),
 | |
| 	retractall(def_rule(_,_)),
 | |
| 	process_clauses(C,1).
 | |
| 
 | |
| process_clauses([(end_of_file,[])],_N).
 | |
| 	
 | |
| process_clauses([((H <- B),_V)|T],N):-!,
 | |
| 	convert_body(B,BL),
 | |
| 	assert(def_rule(H,BL)),
 | |
| 	process_clauses(T,N).
 | |
| 
 | |
| 
 | |
| process_clauses([((prob H),V)|T],N):-!,
 | |
| 	list2and(HL1,H),
 | |
| 	process_head(HL1,HL),
 | |
| 	length(HL,LH),
 | |
| 	listN(0,LH,NH),
 | |
| 	assert_rules(HL,0,HL,[],NH,N,V),
 | |
| 	assertz(rule_by_num(N,V,NH,HL,[])),
 | |
| 	N1 is N+1,
 | |
| 	process_clauses(T,N1).
 | |
| 
 | |
| process_clauses([(H,_V)|T],N):-
 | |
| 	assert(def_rule(H,[])),
 | |
| 	process_clauses(T,N).
 | |
| 	
 | |
| 
 | |
| assert_rules([],_Pos,_HL,_BL,_Nh,_N,_V1):-!.
 | |
| 
 | |
| assert_rules(['':_P],_Pos,_HL,_BL,_Nh,_N,_V1):-!.
 | |
| 
 | |
| assert_rules([H:P|T],Pos,HL,BL,NH,N,V1):-
 | |
| 	assertz(rule(H,P,Pos,N,V1,NH,HL)),
 | |
| 	Pos1 is Pos+1,
 | |
| 	assert_rules(T,Pos1,HL,BL,NH,N,V1).
 | |
| 
 | |
| 
 | |
| /* if the annotation in the head are not ground, the null atom is not added
 | |
| and the eventual formulas are not evaluated */
 | |
| 	
 | |
| process_head(HL,NHL):-
 | |
| 	(ground_prob(HL)->
 | |
| 		process_head_ground(HL,0,NHL)
 | |
| 	;
 | |
| 		NHL=HL
 | |
| 	).
 | |
| 
 | |
| ground_prob([]).
 | |
| 
 | |
| ground_prob([_H:PH|T]):-
 | |
| 	ground(PH),
 | |
| 	ground_prob(T).
 | |
| 
 | |
| process_head_ground([H:PH],P,[H:PH1|Null]):-
 | |
| 	PH1 is PH,
 | |
| 	PNull is 1-P-PH1,
 | |
| 	setting(epsilon_parsing,Eps),
 | |
| 	EpsNeg is - Eps,
 | |
| 	PNull > EpsNeg,
 | |
| 	(PNull>Eps->
 | |
| 		Null=['':PNull]
 | |
| 	;
 | |
| 		Null=[]
 | |
| 	).
 | |
| 
 | |
| process_head_ground([H:PH|T],P,[H:PH1|NT]):-
 | |
| 	PH1 is PH,
 | |
| 	P1 is P+PH1,
 | |
| 	process_head_ground(T,P1,NT).
 | |
| 
 | |
| /* predicates for reading in the program clauses */
 | |
| read_clauses(S,Clauses):-
 | |
| 	(setting(ground_body,true)->
 | |
| 		read_clauses_ground_body(S,Clauses)
 | |
| 	;
 | |
| 		read_clauses_exist_body(S,Clauses)
 | |
| 	).
 | |
| 
 | |
| 
 | |
| read_clauses_ground_body(S,[(Cl,V)|Out]):-
 | |
| 	read_term(S,Cl,[variable_names(V)]),
 | |
| 	(Cl=end_of_file->
 | |
| 		Out=[]
 | |
| 	;
 | |
| 		read_clauses_ground_body(S,Out)
 | |
| 	).
 | |
| 
 | |
| 
 | |
| read_clauses_exist_body(S,[(Cl,V)|Out]):-
 | |
| 	read_term(S,Cl,[variable_names(VN)]),
 | |
| 	extract_vars_cl(Cl,VN,V),
 | |
| 	(Cl=end_of_file->
 | |
| 		Out=[]
 | |
| 	;
 | |
| 		read_clauses_exist_body(S,Out)
 | |
| 	).
 | |
| 
 | |
| 
 | |
| extract_vars_cl(end_of_file,[]).
 | |
| 
 | |
| extract_vars_cl(Cl,VN,Couples):-
 | |
| 	(Cl=(H:-_B)->
 | |
| 		true
 | |
| 	;
 | |
| 		H=Cl
 | |
| 	),
 | |
| 	extract_vars(H,[],V),
 | |
| 	pair(VN,V,Couples).
 | |
| 	
 | |
| 
 | |
| pair(_VN,[],[]).
 | |
| 
 | |
| pair([VN= _V|TVN],[V|TV],[VN=V|T]):-
 | |
| 	pair(TVN,TV,T).	
 | |
| 	
 | |
| 
 | |
| extract_vars(Var,V0,V):-
 | |
| 	var(Var),!,
 | |
| 	(member_eq(Var,V0)->
 | |
| 		V=V0
 | |
| 	;
 | |
| 		append(V0,[Var],V)
 | |
| 	).
 | |
| 	
 | |
| extract_vars(Term,V0,V):-
 | |
| 	Term=..[_F|Args],
 | |
| 	extract_vars_list(Args,V0,V).
 | |
| 
 | |
| 
 | |
| extract_vars_list([],V,V).
 | |
| 
 | |
| extract_vars_list([Term|T],V0,V):-
 | |
| 	extract_vars(Term,V0,V1),
 | |
| 	extract_vars_list(T,V1,V).
 | |
| 
 | |
| 	
 | |
| listN(N,N,[]):-!.
 | |
| 
 | |
| listN(NIn,N,[NIn|T]):-
 | |
| 	N1 is NIn+1,
 | |
| 	listN(N1,N,T).
 | |
| /* end of predicates for parsing an input file containing a program */
 | |
| 
 | |
| /* start of utility predicates */
 | |
| list2or([X],X):-
 | |
| 	X\=;(_,_),!.
 | |
| 
 | |
| list2or([H|T],(H ; Ta)):-!,
 | |
| 	list2or(T,Ta).
 | |
| 
 | |
| list2and([X],X):-
 | |
| 	X\=(_,_),!.
 | |
| 
 | |
| list2and([H|T],(H,Ta)):-!,
 | |
| 	list2and(T,Ta).
 | |
| 
 | |
| member_eq(A,[H|_T]):-
 | |
| 	A==H,!.
 | |
| 	
 | |
| member_eq(A,[_H|T]):-
 | |
| 	member_eq(A,T).
 | |
| 
 | |
| subset_my([],_).
 | |
| 
 | |
| subset_my([H|T],L):-
 | |
| 	member_eq(H,L),
 | |
| 	subset_my(T,L).
 | |
| 
 | |
| remove_duplicates_eq([],[]).
 | |
| 
 | |
| remove_duplicates_eq([H|T],T1):-
 | |
| 	member_eq(H,T),!,
 | |
| 	remove_duplicates_eq(T,T1).
 | |
| 
 | |
| remove_duplicates_eq([H|T],[H|T1]):-
 | |
| 	remove_duplicates_eq(T,T1).
 | |
| 
 | |
| builtin(_A is _B).
 | |
| builtin(_A > _B).
 | |
| builtin(_A < _B).
 | |
| builtin(_A >= _B).
 | |
| builtin(_A =< _B).
 | |
| builtin(_A =:= _B).
 | |
| builtin(_A =\= _B).
 | |
| builtin(true).
 | |
| builtin(false).
 | |
| builtin(_A = _B).
 | |
| builtin(_A==_B).
 | |
| builtin(_A\=_B).
 | |
| builtin(_A\==_B).
 | |
| builtin(length(_L,_N)).
 | |
| builtin(member(_El,_L)).
 | |
| builtin(average(_L,_Av)).
 | |
| builtin(max_list(_L,_Max)).
 | |
| builtin(min_list(_L,_Max)).
 | |
| builtin(nth0(_,_,_)).
 | |
| builtin(nth(_,_,_)).
 | |
| average(L,Av):-
 | |
| 	sum_list(L,Sum),
 | |
| 	length(L,N),
 | |
| 	Av is Sum/N.
 | |
| 
 | |
| clique(Graph,Clique):-
 | |
| 	vertices(Graph,Candidates),
 | |
| 	extend_cycle(Graph,Candidates,[],[],Clique).
 | |
| 	
 | |
| extend_cycle(G,[H|T],Not,CS,CSOut):-
 | |
| 	neighbours(H, G, Neigh),
 | |
| 	intersection(Neigh,T,NewCand),
 | |
| 	intersection(Neigh,Not,NewNot),
 | |
| 	extend(G,NewCand,NewNot,[H|CS],CSOut).
 | |
| 
 | |
| extend_cycle(G,[H|T],Not,CS,CSOut):-
 | |
| 	extend_cycle(G,T,[H|Not],CS,CSOut).
 | |
| 
 | |
| extend(_G,[],[],CompSub,CompSub):-!.
 | |
| 
 | |
| extend(G,Cand,Not,CS,CSOut):-
 | |
| 	extend_cycle(G,Cand,Not,CS,CSOut).
 | |
| 	
 | |
| convert_body((~ A & B),[\+ A|B1]):-!,
 | |
| 	convert_body(B,B1).
 | |
| 
 | |
| convert_body((A & B),[A|B1]):-!,
 | |
| 	convert_body(B,B1).
 | |
| 
 | |
| convert_body(~ A,[\+ A]):-!.
 | |
| 
 | |
| convert_body(A,[A]).
 | |
| 
 | |
| /* set(Par,Value) can be used to set the value of a parameter */
 | |
| set(Parameter,Value):-
 | |
| 	retract(setting(Parameter,_)),
 | |
| 	assert(setting(Parameter,Value)).
 | |
| 
 | |
| /* end of utility predicates */
 |