2608 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			2608 lines
		
	
	
		
			62 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								RIB
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Copyright (c) 2011, Fabrizio Riguzzi and Nicola di Mauro
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								:-multifile setting/2,mode/2,modeh/2,modeb/2,neg/1.
							 | 
						||
| 
								 | 
							
								%:- set_prolog_flag(profiling,on).
							 | 
						||
| 
								 | 
							
								%:- set_prolog_flag(debug,on).
							 | 
						||
| 
								 | 
							
								:- set_prolog_flag(discontiguous_warnings,on).
							 | 
						||
| 
								 | 
							
								:- set_prolog_flag(single_var_warnings,on).
							 | 
						||
| 
								 | 
							
								%:-yap_flag(gc_trace,very_verbose).
							 | 
						||
| 
								 | 
							
								%:- source.
							 | 
						||
| 
								 | 
							
								:- use_module(inference_ib,
							 | 
						||
| 
								 | 
							
								  [build_network/5,
							 | 
						||
| 
								 | 
							
								  get_prob/3,
							 | 
						||
| 
								 | 
							
								  get_CL/3,
							 | 
						||
| 
								 | 
							
								  remove_head/2,
							 | 
						||
| 
								 | 
							
								  get_atoms/2,
							 | 
						||
| 
								 | 
							
								  find_deriv_inf1/2,
							 | 
						||
| 
								 | 
							
								  find_atoms_head/3]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:-use_module(library(lists)).
							 | 
						||
| 
								 | 
							
								:-use_module(library(rbtrees)).
							 | 
						||
| 
								 | 
							
								:-use_module(library(random)).
							 | 
						||
| 
								 | 
							
								:-set_prolog_flag(unknown,fail).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%:-use_module(library(lpadsld)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:-dynamic setting/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Total number of examples in case in which the models in the kb file contain
							 | 
						||
| 
								 | 
							
								a prob(P). fact. In that case, one model corresponds to sample_size*P examples
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								setting(sample_size,1000). 
							 | 
						||
| 
								 | 
							
								setting(setrand,rand(1230,45,123)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								setting(verbosity,1).
							 | 
						||
| 
								 | 
							
								setting(minimal_step,0.005).
							 | 
						||
| 
								 | 
							
								setting(maximal_step,0.1).
							 | 
						||
| 
								 | 
							
								setting(depth_bound,3).
							 | 
						||
| 
								 | 
							
								setting(logsize_fraction,0.9).
							 | 
						||
| 
								 | 
							
								/* value assigned to log 0
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								setting(delta,-10).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								setting(epsilon_fraction,100).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* maximum number of non-ground rules 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								setting(max_rules,6000).
							 | 
						||
| 
								 | 
							
								/* maximum number of variables in an output rule
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Data structures:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								array qy: Q(y)
							 | 
						||
| 
								 | 
							
								array q: Q(ch|y), for each y q store a red black tree with ch(N,S) as key
							 | 
						||
| 
								 | 
							
								array p: P(N), for each rule N store d(Probs,Atoms)
							 | 
						||
| 
								 | 
							
								PAX: rb tree with atoms as key and list of parents (ch(N,S)) as values
							 | 
						||
| 
								 | 
							
								CH: list of choice variables, each of the form ch(N,S) where N is the rule
							 | 
						||
| 
								 | 
							
								number and S is a substitution that ground rule N
							 | 
						||
| 
								 | 
							
								R: list of elemtns N-Inst where N is a rule number and Inst is a list of
							 | 
						||
| 
								 | 
							
								instantiations
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Storage of examples:
							 | 
						||
| 
								 | 
							
								an extra argument is added to each ground atom to store the example id (integer)
							 | 
						||
| 
								 | 
							
								atom a(b,c,d) that is true in interpretation 10 is asserted as
							 | 
						||
| 
								 | 
							
								a(10,a,b,c,d)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ib_par(File):-
							 | 
						||
| 
								 | 
							
								  setting(setrand,K),
							 | 
						||
| 
								 | 
							
								  setrand(K),
							 | 
						||
| 
								 | 
							
								  generate_file_names(File,FileKB,FileOut,FileL,FileLPAD,FileBG),
							 | 
						||
| 
								 | 
							
								  reconsult(FileL),
							 | 
						||
| 
								 | 
							
								        (file_exists(FileBG)->
							 | 
						||
| 
								 | 
							
								                reconsult(FileBG)
							 | 
						||
| 
								 | 
							
								        ;
							 | 
						||
| 
								 | 
							
								                true
							 | 
						||
| 
								 | 
							
								        ),
							 | 
						||
| 
								 | 
							
								  load_models(FileKB),
							 | 
						||
| 
								 | 
							
								  retractall(hb(_,_,_)),
							 | 
						||
| 
								 | 
							
								  ex(NS),
							 | 
						||
| 
								 | 
							
								  set(sample_size,NS),
							 | 
						||
| 
								 | 
							
								  load_initial_model(FileLPAD,Model),!,
							 | 
						||
| 
								 | 
							
								  randomize(Model,Model0),
							 | 
						||
| 
								 | 
							
								  set(verbosity,3),
							 | 
						||
| 
								 | 
							
								  statistics(runtime,[_,_]),  
							 | 
						||
| 
								 | 
							
								  assert_model(Model0),  
							 | 
						||
| 
								 | 
							
								  write_model(Model0,user_output),
							 | 
						||
| 
								 | 
							
								  compute_parameters_IB(Model0,Model1,I,LogSize),
							 | 
						||
| 
								 | 
							
								  statistics(runtime,[_,CT]),
							 | 
						||
| 
								 | 
							
								  CTS is CT/1000,
							 | 
						||
| 
								 | 
							
								  format("Execution time ~f LogSize ~f Final I ~f~n",[CTS,LogSize,I]),
							 | 
						||
| 
								 | 
							
								  listing(setting/2),
							 | 
						||
| 
								 | 
							
								  format("Model:~n",[]),
							 | 
						||
| 
								 | 
							
								  write_model(Model1,user_output),
							 | 
						||
| 
								 | 
							
								  open(FileOut,write,Stream),
							 | 
						||
| 
								 | 
							
								  format(Stream,"/* Execution time ~f LogSize ~f Final I ~f~n",[CTS,LogSize,I]),
							 | 
						||
| 
								 | 
							
								  tell(Stream),
							 | 
						||
| 
								 | 
							
								  listing(setting/2),
							 | 
						||
| 
								 | 
							
								  format(Stream,"*/~n",[]),
							 | 
						||
| 
								 | 
							
								  write_model(Model1,Stream),
							 | 
						||
| 
								 | 
							
								  told.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* checks whether two variable substitutions are the same,
							 | 
						||
| 
								 | 
							
								independently of the variable names */
							 | 
						||
| 
								 | 
							
								match_subs([],_S1):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								match_subs([_V1=S|TS],[_V2=S|TS1]):-
							 | 
						||
| 
								 | 
							
								  match_subs(TS,TS1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* computes the parameters of a model by using the information bottleneck
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_parameters_IB(Model0,Model1,I2,LogSize):-
							 | 
						||
| 
								 | 
							
								  build_network_IB(CH,PAX,T,TCh,R,LogSize),
							 | 
						||
| 
								 | 
							
								  my_set_value(ch,CH),
							 | 
						||
| 
								 | 
							
								  my_set_value(pax,PAX),
							 | 
						||
| 
								 | 
							
								  my_set_value(t,T),  
							 | 
						||
| 
								 | 
							
								  my_set_value(tch,TCh),
							 | 
						||
| 
								 | 
							
								  (CH=[]->
							 | 
						||
| 
								 | 
							
								    Model1=Model0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    length(CH,LCH),
							 | 
						||
| 
								 | 
							
								    format("Logsize ~f ground clauses ~d~n",[LogSize,LCH]),
							 | 
						||
| 
								 | 
							
								    ex(NEx),
							 | 
						||
| 
								 | 
							
								    array(q,NEx),
							 | 
						||
| 
								 | 
							
								    array(qt,NEx),
							 | 
						||
| 
								 | 
							
								    build_q_table(CH),
							 | 
						||
| 
								 | 
							
								    build_qt_table(T),
							 | 
						||
| 
								 | 
							
								    static_array(qy,NEx,float),
							 | 
						||
| 
								 | 
							
								    build_q_Y_table(0,NEx),
							 | 
						||
| 
								 | 
							
								    build_p_table(Model0),
							 | 
						||
| 
								 | 
							
								    rb_new(Q_ch0),
							 | 
						||
| 
								 | 
							
								    compute_Q_ch(CH,Q_ch0,Q_ch1),
							 | 
						||
| 
								 | 
							
								    rb_new(Q_t0),
							 | 
						||
| 
								 | 
							
								    compute_Q_t(T,Q_t0,Q_t1),
							 | 
						||
| 
								 | 
							
								    compute_I(NEx,CH,Q_ch1,T,Q_t1,I1),
							 | 
						||
| 
								 | 
							
								    compute_Nr(R,NR),
							 | 
						||
| 
								 | 
							
								    iterate_IB_par(0.0,I1,I2,1,Q_ch1,Q_t1,R,NR,LogSize,Model0),
							 | 
						||
| 
								 | 
							
								    build_new_model(Model0,Model1),
							 | 
						||
| 
								 | 
							
								    flush_output
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* updates the model with the distribution stored in the array p (P 
							 | 
						||
| 
								 | 
							
								distribution after the optimization)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								build_new_model([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_new_model([rule(N,V,NH,HL,BL,LogF)|T],[rule(N,V,NH,HL1,BL,LogF)|T1]):-
							 | 
						||
| 
								 | 
							
								  my_get_value(ch,CH),
							 | 
						||
| 
								 | 
							
								  member(ch(N,_S),CH),!,
							 | 
						||
| 
								 | 
							
								  array_element(p,N,d(Distr,_Val)),
							 | 
						||
| 
								 | 
							
								  new_dist(HL,Distr,HL1),
							 | 
						||
| 
								 | 
							
								  build_new_model(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_new_model([H|T],[H|T1]):-
							 | 
						||
| 
								 | 
							
								  build_new_model(T,T1).
							 | 
						||
| 
								 | 
							
								/* given a head as a list of annotated atoms and a list of probabilities,
							 | 
						||
| 
								 | 
							
								returns the head with the annotations taken from the list of probabilities
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								new_dist([],[],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								new_dist([H:_P|HL],[P1|TP],[H:P1|HL1]):-
							 | 
						||
| 
								 | 
							
								  new_dist(HL,TP,HL1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* builds the initial Q(Y) table:
							 | 
						||
| 
								 | 
							
								it assigns to each example either
							 | 
						||
| 
								 | 
							
								1) the probability indicated for the example in the .kb file
							 | 
						||
| 
								 | 
							
								2) or 1/n if n is the number of examples
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								build_q_Y_table(N,N):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_q_Y_table(N,NEx):-
							 | 
						||
| 
								 | 
							
								  (prob(N,P)->
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    P is 1/NEx
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  update_array(qy,N,P),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								  build_q_Y_table(N1,NEx).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* main cycle of parameter learning with ib
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								iterate_IB_par(Gamma,I,I,N,_Q_ch,_Q_t,_R,_NR,LogSize,_Model):-
							 | 
						||
| 
								 | 
							
								  setting(logsize_fraction,LF),
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  (
							 | 
						||
| 
								 | 
							
								  Gamma>0.9999
							 | 
						||
| 
								 | 
							
								  ;I>LogSize*LF
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  format("Iteration ~d~nGamma ~f~n I ~f~n",[N,Gamma,I]),
							 | 
						||
| 
								 | 
							
								  !.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								iterate_IB_par(Gamma,I,I2,N,Q_ch,Q_t,R,NR,LogSize,Model):-
							 | 
						||
| 
								 | 
							
								  format("Iteration ~d~nGamma ~f~n I ~f~n",[N,Gamma,I]),
							 | 
						||
| 
								 | 
							
								  maximize_Q(Gamma,Q_ch,Q_t,R,LogSize,NR,Gamma1),
							 | 
						||
| 
								 | 
							
								  compute_Nr(R,NR1),
							 | 
						||
| 
								 | 
							
								  maximize_P(R,NR1),
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  rb_new(Q_ch0),
							 | 
						||
| 
								 | 
							
								  my_get_value(ch,CH),
							 | 
						||
| 
								 | 
							
								  compute_Q_ch(CH,Q_ch0,Q_ch1),
							 | 
						||
| 
								 | 
							
								  rb_new(Q_t0),
							 | 
						||
| 
								 | 
							
								  my_get_value(t,T),
							 | 
						||
| 
								 | 
							
								  compute_Q_t(T,Q_t0,Q_t1),
							 | 
						||
| 
								 | 
							
								  compute_I(NEx,CH,Q_ch1,T,Q_t1,I1),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								  build_new_model(Model,Model1),
							 | 
						||
| 
								 | 
							
								  retract_model,
							 | 
						||
| 
								 | 
							
								  assert_model(Model1),
							 | 
						||
| 
								 | 
							
								  flush_output,
							 | 
						||
| 
								 | 
							
								  iterate_IB_par(Gamma1,I1,I2,N1,Q_ch1,Q_t1,R,NR1,LogSize,Model).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes the P distribution that maximizes the Lagrangian
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								maximize_P([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								maximize_P([_N-_Inst|TR],[0.0|TNR]):-!,
							 | 
						||
| 
								 | 
							
								  maximize_P(TR,TNR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								maximize_P([N-_Inst|TR],[_NR|TNR]):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  maximize_P(TR,TNR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								maximize_P([N-Inst|TR],[NR|TNR]):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,_V,_NH,HL,_BL),
							 | 
						||
| 
								 | 
							
								  length(HL,LH),
							 | 
						||
| 
								 | 
							
								  list0(0,LH,Num0),  
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  compute_theta_num(0,NEx,Inst,N,Num0,Num),
							 | 
						||
| 
								 | 
							
								  divide(NR,Num,Theta),
							 | 
						||
| 
								 | 
							
								%  normalize(Theta,Theta1),
							 | 
						||
| 
								 | 
							
								  array_element(p,N,d(_,Val)),
							 | 
						||
| 
								 | 
							
								  update_array(p,N,d(Theta,Val)),
							 | 
						||
| 
								 | 
							
								  maximize_P(TR,TNR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes the numerator of \theta_{hd_r|true}, i.e.
							 | 
						||
| 
								 | 
							
								\sum_{s\in i(r)}\sum_{y}Q(y)Q(Ch_s=hd_r|y)bt(pa_{ch_s}[y])+\alpha(r,hd_r,true)=
							 | 
						||
| 
								 | 
							
								\sum_{s,ch_s\in i(r)}\mathcal{N}(s,hd_r)+\alpha(r,hd_r,true)=
							 | 
						||
| 
								 | 
							
								\mathcal{N}(r,hd_r)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_theta_num(N,N,_Inst,_N,Num,Num):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_theta_num(Y,NEx,Inst,N,Num0,Num1):-
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,Q_Y),
							 | 
						||
| 
								 | 
							
								  array_element(q,Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  find_true_inst_unseen(Inst,N,Y,TInst),
							 | 
						||
| 
								 | 
							
								  compute_theta_term(TInst,Y,N,Q_Y,Q_ch_Y_par,Num0,Num2),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_theta_num(Y1,NEx,Inst,N,Num2,Num1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*   computes 
							 | 
						||
| 
								 | 
							
								\sum_{y}Q(y)Q(Ch_s=hd_r|y)bt(pa_{ch_s}[y])+\alpha(r,hd_r,true)=
							 | 
						||
| 
								 | 
							
								\mathcal{N}(s,hd_r)+\alpha(r,hd_r,true)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_theta_term([],_Y,_N,_Q_Y,_Q_ch_Y_par,Term,Term):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_theta_term([S|TS],Y,N,Q_Y,Q_ch_Y_par,Term0,Term1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch_Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTB,_B),
							 | 
						||
| 
								 | 
							
								  times(Q_Y,Q_ch_Y,TermS0),
							 | 
						||
| 
								 | 
							
								  times(PTB,TermS0,TermS),  
							 | 
						||
| 
								 | 
							
								  sum(Term0,TermS,Term2),
							 | 
						||
| 
								 | 
							
								  compute_theta_term(TS,Y,N,Q_Y,Q_ch_Y_par,Term2,Term1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* computes the Q distribution that maximizes the Lagrangian 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								maximize_Q(Gamma,Q_ch,Q_t,R,LogSize,NR,Gamma1):-
							 | 
						||
| 
								 | 
							
								  my_get_value(ch,CH),
							 | 
						||
| 
								 | 
							
								  my_get_value(pax,PAX),
							 | 
						||
| 
								 | 
							
								  my_get_value(t,T),
							 | 
						||
| 
								 | 
							
								  setting(delta,Delta),
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  compute_D(0,NEx,R,NR,D),
							 | 
						||
| 
								 | 
							
								  compute_Q_gradient(0,NEx,Gamma,Delta,Q_ch,Q_t,R,NR,CH,PAX,T,D,[],QGrad,[],IGrad,
							 | 
						||
| 
								 | 
							
								    [],QTGrad,[],ITGrad),
							 | 
						||
| 
								 | 
							
								  compute_step(QGrad,IGrad,QTGrad,ITGrad,LogSize,S),
							 | 
						||
| 
								 | 
							
								  setting(minimal_step,MinS),
							 | 
						||
| 
								 | 
							
								  setting(maximal_step,MaxS),
							 | 
						||
| 
								 | 
							
								  ((S<MinS;\+ S< +inf)->
							 | 
						||
| 
								 | 
							
								    S1=MinS
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    (S>MaxS->
							 | 
						||
| 
								 | 
							
								      S1=MaxS
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      S1=S
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  format("Step: original ~f, adjusted ~f~n",[S,S1]),
							 | 
						||
| 
								 | 
							
								  Gamma1 is Gamma +S1,
							 | 
						||
| 
								 | 
							
								  update_Q(0,NEx,CH,QGrad,S1),
							 | 
						||
| 
								 | 
							
								  update_QT(0,NEx,T,QTGrad,S1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes I_Q(CH;Y)=
							 | 
						||
| 
								 | 
							
								\sum_y\sum_i\sum_{ch_i}Q(y)Q(ch_i|y)(\log Q(ch_i|y)-\log Q(ch_i))=
							 | 
						||
| 
								 | 
							
								(\sum_y\sum_i\sum_{ch_i}Q(y)Q(ch_i|y)\log Q(ch_i|y))-E_Q[\log Q(ch_i)]
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_I(NEx,CH,Q_ch,T,Q_t,I):-
							 | 
						||
| 
								 | 
							
								  compute_I(0,NEx,CH,Q_ch,T,Q_t,0,I0),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_ch(CH,Q_ch,0,I1),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_t(T,Q_t,0,I2),
							 | 
						||
| 
								 | 
							
								%  format("I0 ~f I1 ~f I2 ~f~n",[I0,I1,I2]),
							 | 
						||
| 
								 | 
							
								  I is I0+I1+I2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I(N,N,_CH,_Q_ch_par,_T,_Q_t,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I(Y,NEx,CH,Q_ch_par,T,Q_t_par,I0,I1):-
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,Q_Y),
							 | 
						||
| 
								 | 
							
								  array_element(q,Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  array_element(qt,Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								  compute_I_ch(CH,Q_ch_Y_par,Q_Y,0,ICH),
							 | 
						||
| 
								 | 
							
								  compute_I_t(T,Q_t_Y_par,Q_Y,0,IT),
							 | 
						||
| 
								 | 
							
								  I2 is I0+ICH+IT,
							 | 
						||
| 
								 | 
							
								  %format("Y ~d ICH ~f IT ~f~n",[Y,ICH,IT]),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_I(Y1,NEx,CH,Q_ch_par,T,Q_t_par,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* computes -\sum_i E_Q[\log Q(Ch_i)]=-\sum_{ch_i}Q(ch_i)\log Q(ch_i)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_ch([],_Q_ch_par,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_ch([ch(N,_S)|T],Q_ch_par,I0,I1):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_ch(T,Q_ch_par,I0,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_ch([CH|T],Q_ch_par,I0,I1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(CH,Q_ch,Q_ch_par),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_ch_val(Q_ch,I0,I2),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_ch(T,Q_ch_par,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_t([],_Q_t_par,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_t([H|T],Q_t_par,I0,I1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(H,Q_t,Q_t_par),
							 | 
						||
| 
								 | 
							
								  I2 is I0-Q_t*log(Q_t)-(1-Q_t)*log(1-Q_t),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_t(T,Q_t_par,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes -E_Q[\log Q(Ch_i)]=-\sum_{ch_i}Q(ch_i)\log Q(ch_i)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_ch_val([],I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Exp_Q_ch_val([Q_ch|T],I0,I1):-
							 | 
						||
| 
								 | 
							
								  I2 is I0-Q_ch*log(Q_ch),
							 | 
						||
| 
								 | 
							
								  compute_Exp_Q_ch_val(T,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \sum_i\sum_{ch_i}Q(y)Q(ch_i|y)\log Q(ch_i|y)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_I_ch([],_Q_ch_Y_par,_Q_Y,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I_ch([ch(N,_S)|T],Q_ch_Y_par,Q_Y,I0,I1):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  compute_I_ch(T,Q_ch_Y_par,Q_Y,I0,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I_ch([CH|T],Q_ch_Y_par,Q_Y,I0,I1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(CH,Q_ch_Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  compute_exp_I(Q_ch_Y,Q_Y,I0,I2),
							 | 
						||
| 
								 | 
							
								  compute_I_ch(T,Q_ch_Y_par,Q_Y,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I_t([],_Q_t_Y_par,_Q_Y,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_I_t([H|T],Q_t_Y_par,Q_Y,I0,I1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(H,Q_t_Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								  ((Q_t_Y=<0;Q_t_Y>1)->format("I ~p ~f~n",[H,Q_t_Y]);true),
							 | 
						||
| 
								 | 
							
								  I2 is I0+Q_Y*(Q_t_Y*log(Q_t_Y)+(1-Q_t_Y)*log(1-Q_t_Y)),
							 | 
						||
| 
								 | 
							
								  compute_I_t(T,Q_t_Y_par,Q_Y,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \sum_{ch_i}Q(y)Q(ch_i|y)\log Q(ch_i|y)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_exp_I([],_Q_Y,I,I):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_exp_I([Q_ch_Y|T0],Q_Y,I0,I1):-
							 | 
						||
| 
								 | 
							
								  I2 is I0+Q_ch_Y*Q_Y*log(Q_ch_Y),
							 | 
						||
| 
								 | 
							
								  compute_exp_I(T0,Q_Y,I2,I1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes the new values for the distribution Q(Ch|Y) given the gradient
							 | 
						||
| 
								 | 
							
								vector
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								update_Q(NEx,NEx,_CH,[],_S):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_Q(Y,NEx,CH,[QG|TQG],S):-
							 | 
						||
| 
								 | 
							
								  array_element(q,Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  update_Q_Y(CH,Q_ch_Y_par,QG,S,Q_ch_Y_par1),
							 | 
						||
| 
								 | 
							
								  update_array(q,Y,Q_ch_Y_par1),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  update_Q(Y1,NEx,CH,TQG,S).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes the new values for the distribution Q(Ch|Y) given the gradient
							 | 
						||
| 
								 | 
							
								vector and an example Y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								update_Q_Y([],Q_ch_Y_par,[],_S,Q_ch_Y_par):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_Q_Y([ch(N,_S)|TCH],Q_ch_Y_par,TQG,S,Q_ch_Y_par1):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  update_Q_Y(TCH,Q_ch_Y_par,TQG,S,Q_ch_Y_par1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_Q_Y([CH|TCH],Q_ch_Y_par,[HQG|TQG],S,Q_ch_Y_par1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(CH,Dist,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  times(S,HQG,Delta),
							 | 
						||
| 
								 | 
							
								  %fomat("Delta ~p~n",[Delta]),
							 | 
						||
| 
								 | 
							
								  sum_lower(Dist,Delta,Dist1),
							 | 
						||
| 
								 | 
							
								  normalize(Dist1,Dist2),
							 | 
						||
| 
								 | 
							
								  rb_update(Q_ch_Y_par,CH,Dist2,Q_ch_Y_par2),
							 | 
						||
| 
								 | 
							
								  update_Q_Y(TCH,Q_ch_Y_par2,TQG,S,Q_ch_Y_par1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_QT(NEx,NEx,_T,[],_S):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_QT(Y,NEx,T,[QG|TQG],S):-
							 | 
						||
| 
								 | 
							
								  array_element(qt,Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								%  format("Y ~d~n",[Y]),
							 | 
						||
| 
								 | 
							
								  update_QT_Y(T,Q_t_Y_par,QG,S,Q_t_Y_par1),
							 | 
						||
| 
								 | 
							
								  update_array(qt,Y,Q_t_Y_par1),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  update_QT(Y1,NEx,T,TQG,S).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_QT_Y([],Q_t_Y_par,[],_S,Q_t_Y_par):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_QT_Y([HT|TT],Q_t_Y_par,[HQG|TQG],S,Q_t_Y_par1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(HT,Pr,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								  times(S,HQG,Delta),
							 | 
						||
| 
								 | 
							
								    sum_lower([1-Pr,Pr],Delta,Dist1),
							 | 
						||
| 
								 | 
							
								  normalize(Dist1,[_,Pr1]),
							 | 
						||
| 
								 | 
							
								%  format("t=~p Dist ~p ~f~n",[HT,Dist1,Pr1]),
							 | 
						||
| 
								 | 
							
								  rb_update(Q_t_Y_par,HT,Pr1,Q_t_Y_par2),
							 | 
						||
| 
								 | 
							
								  update_QT_Y(TT,Q_t_Y_par2,TQG,S,Q_t_Y_par1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* sum the values of Q(ch|y) with the values of the step vector \delta
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								sum_lower([],[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								sum_lower([H0|T0],[H1|T1],[H3|T2]):-
							 | 
						||
| 
								 | 
							
								  (H1 < +inf->
							 | 
						||
| 
								 | 
							
								    H2 is H0+H1,
							 | 
						||
| 
								 | 
							
								    (H2<0.0001->
							 | 
						||
| 
								 | 
							
								      H3=0.0001
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      H3=H2
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    format("overflow",[]),
							 | 
						||
| 
								 | 
							
								    H3=H0+100
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  sum_lower(T0,T1,T2).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* normalizes a distribution
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								normalize(Dist1,Dist2):-
							 | 
						||
| 
								 | 
							
								  sum_list(Dist1,Sum),
							 | 
						||
| 
								 | 
							
								  (Sum=:=0.0->format("0 Sum",[])
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  divide(Sum,Dist1,Dist2).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* compute the step size 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_step(QGrad,IGrad,QTGrad,ITGrad,LogSize,S):-
							 | 
						||
| 
								 | 
							
								  %format("CH grad~n",[]),
							 | 
						||
| 
								 | 
							
								  compute_step(QGrad,IGrad,0,0,Sum0),
							 | 
						||
| 
								 | 
							
								  %format("T grad~n",[]),
							 | 
						||
| 
								 | 
							
								  compute_step(QTGrad,ITGrad,0,Sum0,Sum),
							 | 
						||
| 
								 | 
							
								  setting(epsilon_fraction,EF),
							 | 
						||
| 
								 | 
							
								  %format("Sum ~f~n",[Sum]),
							 | 
						||
| 
								 | 
							
								  S is LogSize/EF/Sum.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_step([],[],_Y,S,S).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_step([HQ|TQ],[HI|TI],Y,Sum,S):-
							 | 
						||
| 
								 | 
							
								  append(HQ,DQ),
							 | 
						||
| 
								 | 
							
								  append(HI,DI),
							 | 
						||
| 
								 | 
							
								  vec_times(DQ,DI,D),
							 | 
						||
| 
								 | 
							
								  %format("~p~n",[D]),
							 | 
						||
| 
								 | 
							
								  sum_list(D,SumY),
							 | 
						||
| 
								 | 
							
								  %format("Y ~d SumY ~f~n",[Y,SumY]),
							 | 
						||
| 
								 | 
							
								  Sum1 is Sum + SumY,
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_step(TQ,TI,Y1,Sum1,S).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes Q(Ch)
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								compute_Q_ch([],Q_ch,Q_ch):-!.
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								compute_Q_ch([ch(N,S)|T],Q_ch0,Q_ch1):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,_V,_NH,HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  length(HL,L),
							 | 
						||
| 
								 | 
							
								  list0(0,L,P0),
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  compute_Q_ch_DB(0,NEx,ch(N,S),P0,P1),
							 | 
						||
| 
								 | 
							
								  rb_insert(Q_ch0,ch(N,S),P1,Q_ch2),
							 | 
						||
| 
								 | 
							
								  compute_Q_ch(T,Q_ch2,Q_ch1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Q_ch([ch(N,S)|T],Q_ch0,Q_ch1):-
							 | 
						||
| 
								 | 
							
								  rb_insert(Q_ch0,ch(N,S),1.0,Q_ch2),
							 | 
						||
| 
								 | 
							
								  compute_Q_ch(T,Q_ch2,Q_ch1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \sum_y Q(ch|y)Q(y) for all values ch of a single choice variable
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Q_ch_DB(N,N,_CH,P,P):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Q_ch_DB(Y,NEx,CH,P0,P1):-
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,PY),
							 | 
						||
| 
								 | 
							
								  array_element(q,Y,Q_ch_par),
							 | 
						||
| 
								 | 
							
								  rb_lookup(CH,Par,Q_ch_par),
							 | 
						||
| 
								 | 
							
								  update_dist(P0,Par,PY,P2),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_Q_ch_DB(Y1,NEx,CH,P2,P1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes Q(ch|y)Q(y) for all values ch of a single choice variable and sums
							 | 
						||
| 
								 | 
							
								the result to an accumulator
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								update_dist([],[],_PY,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								update_dist([HP0|P0],[HPar|Par],PY,[HP1|P1]):-
							 | 
						||
| 
								 | 
							
								  HP1 is HP0+HPar*PY,
							 | 
						||
| 
								 | 
							
								  update_dist(P0,Par,PY,P1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* computes Q(T)
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								compute_Q_t([],Q_t,Q_t):-!.
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								compute_Q_t([H|T],Q_t0,Q_t1):-
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  compute_Q_t_DB(0,NEx,H,0,P1),
							 | 
						||
| 
								 | 
							
								  rb_insert(Q_t0,H,P1,Q_t2),
							 | 
						||
| 
								 | 
							
								  compute_Q_t(T,Q_t2,Q_t1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \sum_y Q(t|y)Q(y) for all values t of a single t variable
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Q_t_DB(N,N,_T,P,P):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Q_t_DB(Y,NEx,T,P0,P1):-
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,PY),
							 | 
						||
| 
								 | 
							
								  array_element(qt,Y,Q_t_par),
							 | 
						||
| 
								 | 
							
								  rb_lookup(T,Par,Q_t_par),
							 | 
						||
| 
								 | 
							
								  P2 is P0+Par*PY,
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_Q_t_DB(Y1,NEx,T,P2,P1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes the components of the gradient of Q, i.e. the direction that 
							 | 
						||
| 
								 | 
							
								maximizes the Lagrangian, i.e.
							 | 
						||
| 
								 | 
							
								\frac{\partial G_{ch_i,y}(Q,\gamma)}{\partial Q(ch_{i}|y)}&=&
							 | 
						||
| 
								 | 
							
								-\frac{1}{Q(ch_{i}|y)}+\\
							 | 
						||
| 
								 | 
							
								&&Q(y)(1-Q(ch_{i}|y))(\frac{1-\gamma}{Q(ch_i)}+\\
							 | 
						||
| 
								 | 
							
								&&\gamma E_{Q(CH|ch_{i},y_0)}[\mathcal{D}(y,ch_{t(i,y)},ch_i)]
							 | 
						||
| 
								 | 
							
								for all Ch_i, all values ch_i and all y
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Moreover, it computes the gradient of I
							 | 
						||
| 
								 | 
							
								\frac{\partial I_Q(CH;Y)}{\partial Q(ch_{i0}|y_0)}&=&-\frac{\partial E_Q[\log Q(CH_i)}{\partial Q(ch_{i0}|y_0)}+\frac{\partial E_Q[\log Q(CH_i|y_0)}{\partial Q(ch_{i0}|y_0)}=\\
							 | 
						||
| 
								 | 
							
								&&-Q(y_0)(\log Q(ch_{i0})+1)+Q(y_0)(\log Q(ch_{i0}|y_0)+1)=\\
							 | 
						||
| 
								 | 
							
								&&Q(y_0)(-\log Q(ch_{i0})-1+\log Q(ch_{i0}|y_0)+1)=\\
							 | 
						||
| 
								 | 
							
								&&Q(y_0)(\log Q(ch_{i0}|y_0)-\log Q(ch_{i0}))
							 | 
						||
| 
								 | 
							
								for all Ch_i, all values ch_i and all y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Q_gradient(NEx,NEx,_Gamma,_Delta,_Q_ch,_Q_t,_R,_NR,_CH,_PAX,_T,[],QGrad,QGrad,IGrad,IGrad,QTGrad,QTGrad,ITGrad,ITGrad):-!.
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								  QTGrad=[H|_],
							 | 
						||
| 
								 | 
							
								  format("~p~n",[H]).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Q_gradient(Y,NEx,Gamma,Delta,Q_ch,Q_t,R,NR,CH,PAX,T,[D|DT],QGrad0,QGrad1,IGrad0,IGrad1,QTGrad0,QTGrad1,ITGrad0,ITGrad1):-
							 | 
						||
| 
								 | 
							
								  array_element(q,Y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  array_element(qt,Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,Q_Y),
							 | 
						||
| 
								 | 
							
								  cycle_CH(CH,Y,Gamma,Delta,Q_ch_Y_par,Q_Y,Q_ch,Q_t_Y_par,PAX,D,[],QGradY,[],IGradY),
							 | 
						||
| 
								 | 
							
								  append(QGrad0,[QGradY],QGrad2),
							 | 
						||
| 
								 | 
							
								  append(IGrad0,[IGradY],IGrad2),
							 | 
						||
| 
								 | 
							
								  rb_new(U0),
							 | 
						||
| 
								 | 
							
								  compute_U(R,NR,Y,Q_ch_Y_par,U0,U),
							 | 
						||
| 
								 | 
							
								  cycle_T(T,Y,Gamma,Delta,U,Q_ch_Y_par,Q_Y,Q_t,Q_t_Y_par,PAX,D,[],QTGradY,[],ITGradY),
							 | 
						||
| 
								 | 
							
								  append(QTGrad0,[QTGradY],QTGrad2),
							 | 
						||
| 
								 | 
							
								  append(ITGrad0,[ITGradY],ITGrad2),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_Q_gradient(Y1,NEx,Gamma,Delta,Q_ch,Q_t,R,NR,CH,PAX,T,DT,QGrad2,QGrad1,IGrad2,IGrad1,QTGrad2,QTGrad1,ITGrad2,ITGrad1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_U([],[],_Y,_Q_ch_Y_par,U,U).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_U([HR-Inst|TR],[NR|TNR],Y,Q_ch_Y_par,U0,U):-
							 | 
						||
| 
								 | 
							
								  compute_U_inst(Inst,HR,NR,Y,Q_ch_Y_par,[],UR),
							 | 
						||
| 
								 | 
							
								  rb_insert(U0,HR,UR,U1),
							 | 
						||
| 
								 | 
							
								  compute_U(TR,TNR,Y,Q_ch_Y_par,U1,U).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								compute_U_inst([],_N,_NR,_Y,_Q_ch_Y_par,U,U).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_U_inst([S|TS],N,NR,Y,Q_ch_Y_par,U0,U):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,Sub,_HL,BL),!,
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  (body_true_unseen(BL,_BL,Y,1)->
							 | 
						||
| 
								 | 
							
								    prob_body(BL,Y,1,PTB,_B),
							 | 
						||
| 
								 | 
							
								    rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),  
							 | 
						||
| 
								 | 
							
								    scan_ch(Q_ch_y,[1.0],NR,PTB,UCH),
							 | 
						||
| 
								 | 
							
								    append(U0,[ch(N,S)-UCH],U1)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    U1 = U0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  compute_U_inst(TS,N,NR,Y,Q_ch_Y_par,U1,U).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_U_inst([S|TS],N,NR,Y,Q_ch_Y_par,U0,U):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  (body_true_unseen(BL,_BL,Y,1)->
							 | 
						||
| 
								 | 
							
								    prob_body(BL,Y,1,PTB,_B),
							 | 
						||
| 
								 | 
							
								    rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),  
							 | 
						||
| 
								 | 
							
								    array_element(p,N,d(Theta,_Val)),
							 | 
						||
| 
								 | 
							
								    scan_ch(Q_ch_y,Theta,NR,PTB,UCH),
							 | 
						||
| 
								 | 
							
								    append(U0,[ch(N,S)-UCH],U1)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    U1 = U0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  compute_U_inst(TS,N,NR,Y,Q_ch_Y_par,U1,U).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_ch([],[],_NR,_PTB,[]).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								scan_ch([Q_ch_yH|Q_ch_yT],[ThetaH|ThetaT],NR,PTB,[UCHH|UCHT]):-
							 | 
						||
| 
								 | 
							
								  UCHH is Q_ch_yH*PTB/NR*(1/ThetaH+1),
							 | 
						||
| 
								 | 
							
								  scan_ch(Q_ch_yT,ThetaT,NR,PTB,UCHT).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Computes \mathcal{N}(r), the denominator of \theta_{ch_r|true} for all rules
							 | 
						||
| 
								 | 
							
								r
							 | 
						||
| 
								 | 
							
								i.e
							 | 
						||
| 
								 | 
							
								\sum_{s\in i(r)}\sum_y Q(y)bt(pa_{ch_s}[y]+\alpha(r,true)
							 | 
						||
| 
								 | 
							
								for all r
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Nr([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Nr([N-_Inst|TR],[1.0|TNR]):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_S,_H,_B),!,
							 | 
						||
| 
								 | 
							
								  compute_Nr(TR,TNR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Nr([N-Inst|TR],[NR|TNR]):-
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  compute_Nr_R(0,NEx,N,Inst,0,NR),
							 | 
						||
| 
								 | 
							
								  compute_Nr(TR,TNR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Computes \mathcal{N}(r), for a single rule r
							 | 
						||
| 
								 | 
							
								i.e
							 | 
						||
| 
								 | 
							
								\sum_{s\in i(r)}\sum_y Q(y)bt(pa_{ch_s}[y]+\alpha(r,true)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_Nr_R(NEx,NEx,_N,_Inst,NR,NR):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_Nr_R(Y,NEx,N,Inst,NR0,NR1):-
							 | 
						||
| 
								 | 
							
								  array_element(qy,Y,Q_Y),
							 | 
						||
| 
								 | 
							
								  find_true_inst_unseen(Inst,N,Y,TInst),
							 | 
						||
| 
								 | 
							
								  scan_inst(TInst,N,Y,0,PTB),
							 | 
						||
| 
								 | 
							
								  NR2 is NR0+PTB*Q_Y,
							 | 
						||
| 
								 | 
							
								  Y1 is Y + 1,
							 | 
						||
| 
								 | 
							
								  compute_Nr_R(Y1,NEx,N,Inst,NR2,NR1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_inst([],_N,_Y,PTB,PTB).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_inst([S|TS],N,Y,PTB0,PTB):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTSB,_B),
							 | 
						||
| 
								 | 
							
								  PTB1 is PTB0+PTSB,
							 | 
						||
| 
								 | 
							
								  scan_inst(TS,N,Y,PTB1,PTB).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								prob_body([],_Y,PTSB,PTSB,[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								prob_body([\+ H|T],Y,PTSB0,PTSB,B1):-!,
							 | 
						||
| 
								 | 
							
								  functor(H,P,A0),
							 | 
						||
| 
								 | 
							
								  A is A0-1,
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    H=..[P,_|Args],
							 | 
						||
| 
								 | 
							
								    H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								    array_element(qt,Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								    rb_lookup(H1,Q_t_y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								    PTSB1 is PTSB0*(1-Q_t_y),
							 | 
						||
| 
								 | 
							
								    B1=[\+ H1|B0]
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PTSB1=PTSB0,
							 | 
						||
| 
								 | 
							
								    B1=B0
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  prob_body(T,Y,PTSB1,PTSB,B0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								prob_body([H|T],Y,PTSB0,PTSB,B1):-
							 | 
						||
| 
								 | 
							
								  functor(H,P,A0),
							 | 
						||
| 
								 | 
							
								  A is A0-1,
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    H=..[P,_|Args],
							 | 
						||
| 
								 | 
							
								    H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								    array_element(qt,Y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								    rb_lookup(H1,Q_t_y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								    PTSB1 is PTSB0*Q_t_y,
							 | 
						||
| 
								 | 
							
								    B1=[H1|B0]
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PTSB1=PTSB0,
							 | 
						||
| 
								 | 
							
								    B1=B0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  prob_body(T,Y,PTSB1,PTSB,B0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \mathcal{D}(y_0,ch_{t(i,y_0)},ch_{i0}
							 | 
						||
| 
								 | 
							
								\frac{1}{\mathcal{N}(r(i))}\left (\sum_{k,k\in  t(i,y_0)}\frac{1}{\theta_{Hd_{r(i)}=ch_k|true}}\right )\left (\sum_{s\in t(i,y_0),ch_{i0}=ch_s}
							 | 
						||
| 
								 | 
							
								1\right )=\\
							 | 
						||
| 
								 | 
							
								\frac{1}{\mathcal{N}(r(i))}T(i,ch_{t(i,y_0)})N(i,ch_{t(i,y_0)},ch_{i0})
							 | 
						||
| 
								 | 
							
								for all values of y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_D(NEx,NEx,_Rules,_NR,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_D(Y,NEx,Rules,NR,[DY|TDY]):-
							 | 
						||
| 
								 | 
							
								  compute_D_y(Rules,NR,Y,DY),
							 | 
						||
| 
								 | 
							
								  Y1 is Y+1,
							 | 
						||
| 
								 | 
							
								  compute_D(Y1,NEx,Rules,NR,TDY).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \mathcal{D}(y_0,ch_{t(i,y_0)},ch_{i0}
							 | 
						||
| 
								 | 
							
								for a single value of y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_D_y([],[],_Y,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_D_y([N-_Inst|TR],[1.0|TNR],Y,[N-0|DY]):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  compute_D_y(TR,TNR,Y,DY).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_D_y([N-Inst|TR],[NR|TNR],Y,[N-DYN|DY]):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,_V,_NH,HL,_BL),
							 | 
						||
| 
								 | 
							
								  length(HL,L),
							 | 
						||
| 
								 | 
							
								  find_true_inst_unseen(Inst,N,Y,TInst),
							 | 
						||
| 
								 | 
							
								%  length(TInst,LI),
							 | 
						||
| 
								 | 
							
								%  format("N inst ~d~n",[LI]),
							 | 
						||
| 
								 | 
							
								  generate_combinations(TInst,Y,N,L,NR,[],[],DYN),!,
							 | 
						||
| 
								 | 
							
								  compute_D_y(TR,TNR,Y,DY).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes \mathcal{D}(y_0,ch_{t(i,y_0)},ch_{i0}
							 | 
						||
| 
								 | 
							
								for a single combination of values for ch_{t(i,y_0)}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_D_comb(L,L,_Y,_Values,_PD,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_D_comb(L0,L,Y,Values,PD,[DVec|TD]):-
							 | 
						||
| 
								 | 
							
								  L1 is L0+1,
							 | 
						||
| 
								 | 
							
								  findall(ch(N,S),member((ch(N,S)=L1),Values),List),
							 | 
						||
| 
								 | 
							
								  scan_subs_list(List,Y,PD,DVec),
							 | 
						||
| 
								 | 
							
								  compute_D_comb(L1,L,Y,Values,PD,TD).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_subs_list([],_Y,_PD,[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_subs_list([ch(N,S)|T],Y,PD,[(B,QT,D)|DVec0]):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,QT,B),
							 | 
						||
| 
								 | 
							
								  D is PD*QT,
							 | 
						||
| 
								 | 
							
								  scan_subs_list(T,Y,PD,DVec0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes T(i,ch_{t(i,y_0)}=
							 | 
						||
| 
								 | 
							
								\sum_{k,k\in  t(i,y_0)}\frac{1}{\theta_{Hd_{r(i)}=ch_k|true}}
							 | 
						||
| 
								 | 
							
								for a single combination of values for ch_{t(i,y_0)}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_T([],_Theta,T,T):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_T([_=Val|TVal],ThetaR,T0,T1):-
							 | 
						||
| 
								 | 
							
								  nth(Val,ThetaR,Theta),
							 | 
						||
| 
								 | 
							
								  T2 is T0+1/Theta,
							 | 
						||
| 
								 | 
							
								  compute_T(TVal,ThetaR,T2,T1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* generates all combinations of values for ch_{t(i,y_0)}
							 | 
						||
| 
								 | 
							
								and computes \mathcal{D}(y_0,ch_{t(i,y_0)},ch_{i0}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								generate_combinations([],Y,N,L,NR,Values,DYN,[f(Values,D)|DYN]):-!,
							 | 
						||
| 
								 | 
							
								  array_element(p,N,d(ThetaR,_Val)),
							 | 
						||
| 
								 | 
							
								  compute_T(Values,ThetaR,0,T),
							 | 
						||
| 
								 | 
							
								  PD is 1/NR*T,
							 | 
						||
| 
								 | 
							
								  compute_D_comb(0,L,Y,Values,PD,D).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								generate_combinations([S|TS],Y,N,L,NR,Values,DYN0,DYN1):-
							 | 
						||
| 
								 | 
							
								  cycle_values(0,L,Y,N,S,TS,NR,Values,DYN0,DYN1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* auxiliary predicate for generating all combinations of values for 
							 | 
						||
| 
								 | 
							
								ch_{t(i,y_0)}
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								cycle_values(L,L,_Y,_N,_S,_TS,_NR,_Values,DYN,DYN):-!.
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								cycle_values(V,L,Y,N,S,TS,NR,Values,DYN0,DYN1):-
							 | 
						||
| 
								 | 
							
								  V1 is V+1,
							 | 
						||
| 
								 | 
							
								  generate_combinations(TS,Y,N,L,NR,[ch(N,S)=V1|Values],DYN0,DYN2),
							 | 
						||
| 
								 | 
							
								  cycle_values(V1,L,Y,N,S,TS,NR,Values,DYN2,DYN1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* finds the rule instances that have the body true */
							 | 
						||
| 
								 | 
							
								find_true_inst([],_N,_Ex,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_true_inst([S|TS],N,Ex,[S|TInst]):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  body_true(BL,Ex,1),!,
							 | 
						||
| 
								 | 
							
								  find_true_inst(TS,N,Ex,TInst).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_true_inst([_S|TS],N,Ex,TInst):-
							 | 
						||
| 
								 | 
							
								  find_true_inst(TS,N,Ex,TInst).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_true_inst_unseen([],_N,_Ex,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_true_inst_unseen([S|TS],N,Ex,[S|TInst]):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  body_true_unseen(BL,_BL,Ex,1),!,
							 | 
						||
| 
								 | 
							
								  find_true_inst_unseen(TS,N,Ex,TInst).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_true_inst_unseen([_S|TS],N,Ex,TInst):-
							 | 
						||
| 
								 | 
							
								  find_true_inst_unseen(TS,N,Ex,TInst).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over all the choice variables for computing the gradient
							 | 
						||
| 
								 | 
							
								\frac{\partial G_{ch_i,y}(Q,\gamma)}{\partial Q(ch_{i}|y)}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								cycle_CH([],_Y,_Gamma,_Delta,_Q_ch_Y_par,_Q_Y,_Q_ch_par,_Q_t_Y_par,_PAX,_D,QGrad,QGrad,IGrad,IGrad):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_CH([ch(N,_S)|T],Y,Gamma,Delta,Q_ch_Y_par,Q_Y,Q_ch_par,Q_t_Y_par,PAX,D,QGrad0,QGrad1,IGrad0,IGrad1):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  cycle_CH(T,Y,Gamma,Delta,Q_ch_Y_par,Q_Y,Q_ch_par,Q_t_Y_par,PAX,D,QGrad0,QGrad1,IGrad0,IGrad1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_CH([ch(N,S)|T],Y,Gamma,Delta,Q_ch_Y_par,Q_Y,Q_ch_par,Q_t_Y_par,PAX,D,QGrad0,QGrad1,IGrad0,IGrad1):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S,_NH,HL,BL),
							 | 
						||
| 
								 | 
							
								  get_atoms_head(HL,Val),
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch,Q_ch_par),
							 | 
						||
| 
								 | 
							
								  compute_E_log_Q_ch(Q_ch_y,Q_ch,0,E_log_Q_ch), %ok
							 | 
						||
| 
								 | 
							
								  body_true_unseen(BL,_B,Y,BodyTrue),!,
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTB,_B1),
							 | 
						||
| 
								 | 
							
								  array_element(p,N,d(Theta,_Val)),
							 | 
						||
| 
								 | 
							
								  compute_R(Val,ch(N,S),1,Y,PAX,Q_ch_Y_par,Q_t_Y_par,0,[],R), % ok
							 | 
						||
| 
								 | 
							
								  compute_EP(Val,Q_ch_y,Theta,BodyTrue,PTB,Q_t_Y_par,Y,EP,R,Delta,0,EEP),
							 | 
						||
| 
								 | 
							
								  member((N-DN),D),!,
							 | 
						||
| 
								 | 
							
								  length(HL,NVal),
							 | 
						||
| 
								 | 
							
								  list0(0,NVal,ED0),
							 | 
						||
| 
								 | 
							
								  compute_ED(DN,S,Q_ch_Y_par,ED0,ED),
							 | 
						||
| 
								 | 
							
								  cycle_CH_values(Q_ch_y,Q_ch,Q_Y,E_log_Q_ch,Gamma,EP,EEP,ED,D_ch_y,DI_ch_y),
							 | 
						||
| 
								 | 
							
								  append(QGrad0,[D_ch_y],QGrad2),
							 | 
						||
| 
								 | 
							
								  append(IGrad0,[DI_ch_y],IGrad2),
							 | 
						||
| 
								 | 
							
								  cycle_CH(T,Y,Gamma,Delta,Q_ch_Y_par,Q_Y,Q_ch_par,Q_t_Y_par,PAX,D,QGrad2,QGrad1,IGrad2,IGrad1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over all the values of a choice variable for computing the gradient
							 | 
						||
| 
								 | 
							
								\frac{\partial G_{ch_i,y}(Q,\gamma)}{\partial Q(ch_{i}|y)}
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								cycle_CH_values([],[],_Q_y,_E_log_Q_ch,_Gamma,[],_EEP,[],[],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_CH_values([Q_ch_y|TQ_ch_y],[Q_ch|TQ_ch],Q_y,E_log_Q_ch,Gamma,[EP|TEP],EEP,[ED|TED],
							 | 
						||
| 
								 | 
							
								  [Dir|D],[D_I|I]):-
							 | 
						||
| 
								 | 
							
								  D_Q is -1/Q_ch_y+Q_y*(1-Q_ch_y)*((1-Gamma)/Q_ch+Gamma*ED),
							 | 
						||
| 
								 | 
							
								  D_G is -log(Q_ch)+EP-EEP+E_log_Q_ch,
							 | 
						||
| 
								 | 
							
								  Dir is -D_G/D_Q,
							 | 
						||
| 
								 | 
							
								  ((Q_ch_y<1e-20;Q_ch<1e-20;abs(D_Q)<1e-10;abs(Dir)> 1e10)->
							 | 
						||
| 
								 | 
							
								    format("~f ~f ~f~n",[Q_ch_y,Q_ch,Dir])
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  D_I is Q_y*(log(Q_ch_y)-log(Q_ch)),
							 | 
						||
| 
								 | 
							
								  cycle_CH_values(TQ_ch_y,TQ_ch,Q_y,E_log_Q_ch,Gamma,TEP,EEP,TED,D,I).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_T([],_Y,_Gamma,_Delta,_U,_Q_ch_Y_par,_Q_Y,_Q_t_par,_Q_t_Y_par,_PAX,_D,QGrad,QGrad,IGrad,IGrad):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_T([TH|T],Y,Gamma,Delta,U,Q_ch_Y_par,Q_Y,Q_t_par,Q_t_Y_par,PAX,D,QGrad0,QGrad1,IGrad0,IGrad1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(TH,Q_t_y,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								  rb_lookup(TH,Q_t,Q_t_par),
							 | 
						||
| 
								 | 
							
								  ((Q_t=<0;Q_t>1)->format("Q_t ~d ~p ~f~n",[Y,TH,Q_t]);true),
							 | 
						||
| 
								 | 
							
								  ((Q_t_y=<0;Q_t_y>1)->format("Q_t_y ~d ~p ~f~n",[Y,TH,Q_t_y]);true),
							 | 
						||
| 
								 | 
							
								  Exp_log_Q_T is (1-Q_t_y)*log(1-Q_t)+Q_t_y*log(Q_t),
							 | 
						||
| 
								 | 
							
								  TH=..[F|Args],
							 | 
						||
| 
								 | 
							
								  TH1=..[F,_|Args],
							 | 
						||
| 
								 | 
							
								  find_rules_with_T_in_the_body(TH,RT),
							 | 
						||
| 
								 | 
							
								  rb_lookup(TH,Pa_Th,PAX),
							 | 
						||
| 
								 | 
							
								  compute_EPT(RT,TH1,Pa_Th,Q_ch_Y_par,Q_t_y,Y,Delta,0,0,EPt,EPf),
							 | 
						||
| 
								 | 
							
								  Exp_Q_EP is (1-Q_t_y)*EPf+Q_t_y*EPt,
							 | 
						||
| 
								 | 
							
								  compute_EF(RT,TH1,Y,U,Q_ch_Y_par,Q_t_y,Q_Y,0,0,EFt,EFf),
							 | 
						||
| 
								 | 
							
								  D_Qf is -1/(1-Q_t_y)+(1-Q_t)*Q_t_y*((1-Gamma)/(1-Q_t)+Gamma*EFf),
							 | 
						||
| 
								 | 
							
								  D_Gf is -log(1-Q_t)+EPf-Exp_Q_EP+Exp_log_Q_T,
							 | 
						||
| 
								 | 
							
								  Dirf is -D_Gf/D_Qf,
							 | 
						||
| 
								 | 
							
								  D_Qt is -1/Q_t_y+Q_t*(1-Q_t_y)*((1-Gamma)/Q_t+Gamma*EFt),
							 | 
						||
| 
								 | 
							
								  D_Gt is -log(Q_t)+EPt-Exp_Q_EP+Exp_log_Q_T,
							 | 
						||
| 
								 | 
							
								  Dirt is -D_Gt/D_Qt,
							 | 
						||
| 
								 | 
							
								  DirIf is Q_Y*(log(1-Q_t_y)-log(1-Q_t)),
							 | 
						||
| 
								 | 
							
								  DirIt is  Q_Y*(log(Q_t_y)-log(Q_t)),
							 | 
						||
| 
								 | 
							
								  append(QGrad0,[[Dirf,Dirt]],QGrad2),
							 | 
						||
| 
								 | 
							
								  append(IGrad0,[[DirIf,DirIt]],IGrad2),
							 | 
						||
| 
								 | 
							
								  cycle_T(T,Y,Gamma,Delta,U,Q_ch_Y_par,Q_Y,Q_t_par,Q_t_Y_par,PAX,D,QGrad2,QGrad1,IGrad2,IGrad1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_rules_with_T_in_the_body(TH,RT):-
							 | 
						||
| 
								 | 
							
								  my_get_value(tch,TCh),
							 | 
						||
| 
								 | 
							
								  rb_lookup(TH,RT,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EF([],_T,_Y,_U,_Q_ch_Y_par,Q_t_y,Q_y,EFt0,EFf0,EFt,EFf):-
							 | 
						||
| 
								 | 
							
								  EFt is EFt0*Q_y/Q_t_y,
							 | 
						||
| 
								 | 
							
								  EFf is EFf0*Q_y/(1-Q_t_y).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								compute_EF([ch(N,S)|TR],T,Y,U,Q_ch_Y_par,Q_t_y,Q_y,EFt0,EFf0,EFt,EFf):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,S1,_HL,BL),!,
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTB,_BT),
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  find_U_N(U,N,UN),
							 | 
						||
| 
								 | 
							
								  scan_UN(UN,Q_ch_y,0,0,SumUt,SumUf),
							 | 
						||
| 
								 | 
							
								  (member(T,BL)->
							 | 
						||
| 
								 | 
							
								    PTB1 is PTB/Q_t_y,
							 | 
						||
| 
								 | 
							
								    EFt1 is PTB1*SumUt+EFt0,
							 | 
						||
| 
								 | 
							
								    EFf1 = EFf0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PTB1 is PTB/(1-Q_t_y),
							 | 
						||
| 
								 | 
							
								    EFf1 is PTB1*SumUf+EFf0,
							 | 
						||
| 
								 | 
							
								    EFt1 = EFt0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  compute_EF(TR,T,Y,U,Q_ch_Y_par,Q_t_y,Q_y,EFt1,EFf1,EFt,EFf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EF([ch(N,S)|TR],T,Y,U,Q_ch_Y_par,Q_t_y,Q_y,EFt0,EFf0,EFt,EFf):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S1,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTB,_BT),
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  find_U_N(U,N,UN),
							 | 
						||
| 
								 | 
							
								  scan_UN(UN,Q_ch_y,0,0,SumUt,SumUf),
							 | 
						||
| 
								 | 
							
								  (member(T,BL)->
							 | 
						||
| 
								 | 
							
								    PTB1 is PTB/Q_t_y,
							 | 
						||
| 
								 | 
							
								    EFt1 is PTB1*SumUt+EFt0,
							 | 
						||
| 
								 | 
							
								    EFf1 = EFf0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PTB1 is PTB/(1-Q_t_y),
							 | 
						||
| 
								 | 
							
								    EFf1 is PTB1*SumUf+EFf0,
							 | 
						||
| 
								 | 
							
								    EFt1 = EFt0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  compute_EF(TR,T,Y,U,Q_ch_Y_par,Q_t_y,Q_y,EFt1,EFf1,EFt,EFf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_U_N(U,N,UN):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(N,UN,U).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								scan_UN([],_Q_ch_y,SumUt,SumUf,SumUt,SumUf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_UN([ch(N,S)-U|UT],Q_ch_y,SumUt0,SumUf0,SumUt,SumUf):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,S1,_HL,BL),!,
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								  (member(T,BL)->
							 | 
						||
| 
								 | 
							
								    vec_times(U,Q_ch_y,L),
							 | 
						||
| 
								 | 
							
								    sum_list(L,Sum),
							 | 
						||
| 
								 | 
							
								    SumUt1 is SumUt0+Sum,
							 | 
						||
| 
								 | 
							
								    SumUf1 =SumUf0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    (member(\+ T,BL)->
							 | 
						||
| 
								 | 
							
								      vec_times(U,Q_ch_y,L),
							 | 
						||
| 
								 | 
							
								      sum_list(L,Sum),
							 | 
						||
| 
								 | 
							
								      SumUf1 is SumUt0+Sum,
							 | 
						||
| 
								 | 
							
								      SumUt1 =SumUt0
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      SumUt1 =SumUt0,
							 | 
						||
| 
								 | 
							
								      SumUf1 =SumUf0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  scan_UN(UT,Q_ch_y,SumUt1,SumUf1,SumUt,SumUf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_UN([ch(N,S)-U|UT],Q_ch_y,SumUt0,SumUf0,SumUt,SumUf):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S1,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								  (member(T,BL)->
							 | 
						||
| 
								 | 
							
								    vec_times(U,Q_ch_y,L),
							 | 
						||
| 
								 | 
							
								    sum_list(L,Sum),
							 | 
						||
| 
								 | 
							
								    SumUt1 is SumUt0+Sum,
							 | 
						||
| 
								 | 
							
								    SumUf1 =SumUf0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    (member(\+ T,BL)->
							 | 
						||
| 
								 | 
							
								      vec_times(U,Q_ch_y,L),
							 | 
						||
| 
								 | 
							
								      sum_list(L,Sum),
							 | 
						||
| 
								 | 
							
								      SumUf1 is SumUt0+Sum,
							 | 
						||
| 
								 | 
							
								      SumUt1 =SumUt0
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      SumUt1 =SumUt0,
							 | 
						||
| 
								 | 
							
								      SumUf1 =SumUf0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  scan_UN(UT,Q_ch_y,SumUt1,SumUf1,SumUt,SumUf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EPT([],T,Pa_T,Q_ch_Y_par,_Q_t_Y,_Y,Delta,EPt0,EPf0,EPt,EPf):-
							 | 
						||
| 
								 | 
							
								  compute_prod_Pa_T(Pa_T,T,Q_ch_Y_par,1,Prod),
							 | 
						||
| 
								 | 
							
								  EPt is EPt0+Prod*Delta,
							 | 
						||
| 
								 | 
							
								  EPf is EPf0+(1-Prod)*Delta.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EPT([ch(N,S)|TCH],T,Pa_T,Q_ch_Y_par,Q_t_Y,Y,Delta,EPt0,EPf0,EPt,EPf):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,S1,_HL,BL),!,
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								%  ((member(T,BL);member(\+ T,BL))->
							 | 
						||
| 
								 | 
							
								    body_true_unseen(BL,_B,Y,BodyTrue),!,
							 | 
						||
| 
								 | 
							
								    (BodyTrue=:=1->
							 | 
						||
| 
								 | 
							
								      prob_body(BL,Y,1,PTB,_BT),
							 | 
						||
| 
								 | 
							
								      (member(T,BL)->
							 | 
						||
| 
								 | 
							
								        PTB_dif_T is PTB/Q_t_Y,
							 | 
						||
| 
								 | 
							
								        EPf1 is Delta,
							 | 
						||
| 
								 | 
							
								        EPt1 is 1-PTB_dif_T
							 | 
						||
| 
								 | 
							
								      ;
							 | 
						||
| 
								 | 
							
								        PTB_dif_T is PTB/(1-Q_t_Y),
							 | 
						||
| 
								 | 
							
								        EPf1 is 1-PTB_dif_T,
							 | 
						||
| 
								 | 
							
								        EPt1 is Delta
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      (member(T,BL)->
							 | 
						||
| 
								 | 
							
								        EPf1 = 0,
							 | 
						||
| 
								 | 
							
								        EPt1 is Delta
							 | 
						||
| 
								 | 
							
								      ;
							 | 
						||
| 
								 | 
							
								        EPf1 is EPf1+Delta,
							 | 
						||
| 
								 | 
							
								        EPt1 is 0
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								%  ;
							 | 
						||
| 
								 | 
							
								%    EPf1=0,
							 | 
						||
| 
								 | 
							
								%    EPt1=0
							 | 
						||
| 
								 | 
							
								%  )
							 | 
						||
| 
								 | 
							
								  ,
							 | 
						||
| 
								 | 
							
								  EPf3 is EPf0+EPf1,
							 | 
						||
| 
								 | 
							
								  EPt3 is EPt0+EPt1,
							 | 
						||
| 
								 | 
							
								  compute_EPT(TCH,T,Pa_T,Q_ch_Y_par,Q_t_Y,Y,Delta,EPt3,EPf3,EPt,EPf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EPT([ch(N,S)|TCH],T,Pa_T,Q_ch_Y_par,Q_t_Y,Y,Delta,EPt0,EPf0,EPt,EPf):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S1,_NH,HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								%  ((member(T,BL);member(\+ T,BL))->
							 | 
						||
| 
								 | 
							
								    body_true_unseen(BL,_B,Y,BodyTrue),!,
							 | 
						||
| 
								 | 
							
								    (BodyTrue=:=1->
							 | 
						||
| 
								 | 
							
								      prob_body(BL,Y,1,PTB,_BT),
							 | 
						||
| 
								 | 
							
								      rb_lookup(ch(N,S),Q_ch_y,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								      array_element(p,N,d(Theta,_Val)),
							 | 
						||
| 
								 | 
							
								      cycle_EPT_CH_val(Theta,HL,Q_ch_y,0,Sum,Q_ch_null_y),
							 | 
						||
| 
								 | 
							
								      (member(T,BL)->
							 | 
						||
| 
								 | 
							
								        PTB_dif_T is PTB/Q_t_Y,
							 | 
						||
| 
								 | 
							
								        EPf1 is Delta*(1-Q_ch_null_y),
							 | 
						||
| 
								 | 
							
								        EPt1 is PTB_dif_T*Sum+Delta*(Q_ch_null_y*PTB_dif_T+(1-Q_ch_null_y)*(1-PTB_dif_T))
							 | 
						||
| 
								 | 
							
								      ;
							 | 
						||
| 
								 | 
							
								        PTB_dif_T is PTB/(1-Q_t_Y),
							 | 
						||
| 
								 | 
							
								        EPf1 is PTB_dif_T*Sum+Delta*(Q_ch_null_y*PTB_dif_T+(1-Q_ch_null_y)*(1-PTB_dif_T)),
							 | 
						||
| 
								 | 
							
								        EPt1 is Delta*(1-Q_ch_null_y)
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      (member(T,BL)->
							 | 
						||
| 
								 | 
							
								        EPf1 = 0,
							 | 
						||
| 
								 | 
							
								        EPt1 is Delta*(1-Q_ch_null_y)
							 | 
						||
| 
								 | 
							
								      ;
							 | 
						||
| 
								 | 
							
								        EPf1 is EPf1+Delta*(1-Q_ch_null_y),
							 | 
						||
| 
								 | 
							
								        EPt1 is 0
							 | 
						||
| 
								 | 
							
								      )
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								%  ;
							 | 
						||
| 
								 | 
							
								%    EPf1=0,
							 | 
						||
| 
								 | 
							
								%    EPt1=0
							 | 
						||
| 
								 | 
							
								%  )
							 | 
						||
| 
								 | 
							
								  ,
							 | 
						||
| 
								 | 
							
								  EPf3 is EPf0+EPf1,
							 | 
						||
| 
								 | 
							
								  EPt3 is EPt0+EPt1,
							 | 
						||
| 
								 | 
							
								  compute_EPT(TCH,T,Pa_T,Q_ch_Y_par,Q_t_Y,Y,Delta,EPt3,EPf3,EPt,EPf).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_prod_Pa_T([],_T,_Q_ch_Y_par,Prod,Prod).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_prod_Pa_T([ch(N,_S)|TCH],T,Q_ch_Y_par,Prod0,Prod):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  compute_prod_Pa_T(TCH,T,Q_ch_Y_par,Prod0,Prod).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_prod_Pa_T([ch(N,S)|TCH],T,Q_ch_Y_par,Prod0,Prod):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Prob,Q_ch_Y_par),
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S1,_NH,HL,_BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,S1),
							 | 
						||
| 
								 | 
							
								  generate_nth_pos(1, Pos, HL, (T:_P)),
							 | 
						||
| 
								 | 
							
								  nth(Pos,Prob,P),
							 | 
						||
| 
								 | 
							
								  Prod1 is Prod0*(1-P),
							 | 
						||
| 
								 | 
							
								  compute_prod_Pa_T(TCH,T,Q_ch_Y_par,Prod1,Prod).
							 | 
						||
| 
								 | 
							
								      
							 | 
						||
| 
								 | 
							
								cycle_EPT_CH_val([],[],[],S,S,0).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_EPT_CH_val([_],['':_P],[Q_ch_null_y],S,S,Q_ch_null_y):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								cycle_EPT_CH_val([HTheta|TTheta],[_H:_P|T],[Q_ch_yH|Q_ch_yT],S0,S,Q_ch_null_y):-
							 | 
						||
| 
								 | 
							
								  S1 is S0+Q_ch_yH*log(HTheta),
							 | 
						||
| 
								 | 
							
								  cycle_EPT_CH_val(TTheta,T,Q_ch_yT,S1,S,Q_ch_null_y).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* given an annotated head as a list, return the list of atoms
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								get_atoms_head([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_atoms_head(['':_P],['']):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_atoms_head([H:_P|T],[H1|T1]):-
							 | 
						||
| 
								 | 
							
								  H=..[P,_|Rest],
							 | 
						||
| 
								 | 
							
								  H1=..[P|Rest],
							 | 
						||
| 
								 | 
							
								  get_atoms_head(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes R(i,ch,y)&=&
							 | 
						||
| 
								 | 
							
								\sum_{j\in p(i),x_j[y]=true,ch_i\neq x_j[y]}\prod_{ch_s\in pa_{x_j},s\neq i}Q(ch_s\neq x_j[y]|y)
							 | 
						||
| 
								 | 
							
								for all i and all y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_R([],_CH,_NH,_Y,_PAX,_Q_Y,_Q_t_y,RTot,R0,R):-!,
							 | 
						||
| 
								 | 
							
								  subt(R0,R,RTot).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_R([''],_CH,_NH,_Y,_PAX,_Q_Y,_Q_t_y,RTot,R0,R):-!,
							 | 
						||
| 
								 | 
							
								  append(R0,[0],R1),
							 | 
						||
| 
								 | 
							
								  subt(R1,R,RTot).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_R([Val|T],CH,NH,Y,PAX,Q_Y,Q_t_y,RTot0,R0,R):-
							 | 
						||
| 
								 | 
							
								/*  rule_by_num(N,Sub,_NH,_HL,BL),
							 | 
						||
| 
								 | 
							
								  match_subs(S,Sub),
							 | 
						||
| 
								 | 
							
								  prob_body(BL,Y,1,PTSB,_B),*/
							 | 
						||
| 
								 | 
							
								  Val=..[F|Arg],
							 | 
						||
| 
								 | 
							
								  X=..[F,Y|Arg],
							 | 
						||
| 
								 | 
							
								  X1=..[F,_Y|Arg],
							 | 
						||
| 
								 | 
							
								  functor(Val,P,A),
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    rb_lookup(Val,PAVal,PAX),
							 | 
						||
| 
								 | 
							
								    delete(PAVal,CH,PAVal1),
							 | 
						||
| 
								 | 
							
								    compute_R_x(PAVal1,X1,Q_Y,1,Prod0),
							 | 
						||
| 
								 | 
							
								    rb_lookup(Val,Pr_t,Q_t_y),
							 | 
						||
| 
								 | 
							
								    Prod is Prod0*Pr_t,
							 | 
						||
| 
								 | 
							
								    RTot2 is RTot0+Prod,
							 | 
						||
| 
								 | 
							
								    append(R0,[Prod],R1)  
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    (call(X)->
							 | 
						||
| 
								 | 
							
								      rb_lookup(Val,PAVal,PAX),
							 | 
						||
| 
								 | 
							
								      delete(PAVal,CH,PAVal1),
							 | 
						||
| 
								 | 
							
								      compute_R_x(PAVal1,X1,Q_Y,1,Prod),
							 | 
						||
| 
								 | 
							
								      RTot2 is RTot0+Prod,
							 | 
						||
| 
								 | 
							
								      append(R0,[Prod],R1)
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      RTot2=RTot0,
							 | 
						||
| 
								 | 
							
								      append(R0,[0],R1)
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  NH1 is NH+1,
							 | 
						||
| 
								 | 
							
								  compute_R(T,CH,NH1,Y,PAX,Q_Y,Q_t_y,RTot2,R1,R).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* subt(L,L1,RT) subts from RT all the elements of list L obtaining L1 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								subt([],[],_RT):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								subt([H|T],[H1|T1],RT):-
							 | 
						||
| 
								 | 
							
								  H1 is RT-H,
							 | 
						||
| 
								 | 
							
								  subt(T,T1,RT).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes R(i,ch,y)&=&
							 | 
						||
| 
								 | 
							
								\sum_{ch_i\neq x_j[y]}\prod_{ch_s\in pa_{x_j},s\neq i}Q(ch_s\neq x_j[y]|y)
							 | 
						||
| 
								 | 
							
								for a single value x_j
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_R_x([],_X,_Q_Y,Prod,Prod):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_R_x([ch(N,S)|T],X,Q_Y,Prod0,Prod1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Prob,Q_Y),
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,S,_NH,HL,_BL),
							 | 
						||
| 
								 | 
							
								  generate_nth_pos(1, Pos, HL, (X:_P)),
							 | 
						||
| 
								 | 
							
								%  nth(Pos,HL,(X:_P)),!,
							 | 
						||
| 
								 | 
							
								  nth(Pos,Prob,P),
							 | 
						||
| 
								 | 
							
								  Prod2 is Prod0*(1-P),
							 | 
						||
| 
								 | 
							
								  compute_R_x(T,X,Q_Y,Prod2,Prod1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*  body_true(Body,Ex,BT) sets BT to 1 if Body is true in Ex and to 0
							 | 
						||
| 
								 | 
							
								otherwise
							 | 
						||
| 
								 | 
							
								Body is a list of literals, each with the example argument 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								body_true([],_Ex,1):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								body_true([H|T],Ex,BT):-
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    body_true(T,[H],Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    (test([H|T])->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								body_true([H|T],In,Ex,BT):-
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    append(In,[H],In1),
							 | 
						||
| 
								 | 
							
								    body_true(T,In1,Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    append(In,[H|T],B),
							 | 
						||
| 
								 | 
							
								    (test(B)->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								body_true_unseen([],[],_Ex,1):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								body_true_unseen([\+ H|T],B,Ex,BT):-!,
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    body_true_unseen(T,[\+ H],B,Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    (test_unseen([\+ H|T],B)->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								body_true_unseen([H|T],B,Ex,BT):-
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    body_true_unseen(T,[ H],B,Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    (test_unseen([H|T],B)->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								body_true_unseen([\+ H|T],In,B,Ex,BT):-!,
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    append(In,[\+ H],In1),
							 | 
						||
| 
								 | 
							
								    body_true_unseen(T,In1,B,Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    append(In,[\+ H|T],BB),
							 | 
						||
| 
								 | 
							
								    (test_unseen(BB,B)->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								body_true_unseen([H|T],In,B,Ex,BT):-
							 | 
						||
| 
								 | 
							
								  (inference_ib:builtin(H)->
							 | 
						||
| 
								 | 
							
								    append(In,[H],In1),
							 | 
						||
| 
								 | 
							
								    body_true_unseen(T,In1,B,Ex,BT)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    H=..[_P,Ex|_A],
							 | 
						||
| 
								 | 
							
								    append(In,[H|T],BB),
							 | 
						||
| 
								 | 
							
								    (test_unseen(BB,B)->
							 | 
						||
| 
								 | 
							
								      BT=1
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      BT=0
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* test(L) succeeds if L is true in the database
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								test([]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test([H|T]):-
							 | 
						||
| 
								 | 
							
								  call(H),
							 | 
						||
| 
								 | 
							
								  test(T).      
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test_unseen([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test_unseen([\+ H|Tail],B):-!,
							 | 
						||
| 
								 | 
							
								  functor(H,P,A0),
							 | 
						||
| 
								 | 
							
								  A is A0-1,
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								  /*  my_get_value(t,T),
							 | 
						||
| 
								 | 
							
								    H=..[P,_|Args],
							 | 
						||
| 
								 | 
							
								    H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								    member(H1,T),*/
							 | 
						||
| 
								 | 
							
								    B=[\+ H|B1]
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    call(\+ H),
							 | 
						||
| 
								 | 
							
								    B=B1
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  test_unseen(Tail,B1).      
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								test_unseen([H|Tail],B):-
							 | 
						||
| 
								 | 
							
								  functor(H,P,A0),
							 | 
						||
| 
								 | 
							
								  A is A0-1,
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    my_get_value(t,T),
							 | 
						||
| 
								 | 
							
								    H=..[P,_|Args],
							 | 
						||
| 
								 | 
							
								    H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								    member(H1,T),
							 | 
						||
| 
								 | 
							
								    B=[H|B1]
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    call(H),
							 | 
						||
| 
								 | 
							
								    B=B1
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  test_unseen(Tail,B1).      
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes E_{Q(CH|ch_{i},y_0)}[\mathcal{D}(y,ch_{t(i,y)},ch_i)]
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_ED([],_S,_Q_y_par,ED,ED):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_ED([f(Values,D)|TD],S,Q_y_par,ED0,ED1):-
							 | 
						||
| 
								 | 
							
								  delete_matching(Values,(ch(_N,S)=_Val),Values1),!,
							 | 
						||
| 
								 | 
							
								  single_rules_ed_contrib(D,Term0),
							 | 
						||
| 
								 | 
							
								  compute_term(Values1,Q_y_par,Term0,Term),
							 | 
						||
| 
								 | 
							
								  sum(ED0,Term,ED2),
							 | 
						||
| 
								 | 
							
								  compute_ED(TD,S,Q_y_par,ED2,ED1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								delete_matching([],_El,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_matching([El|T],El,TR):-!,
							 | 
						||
| 
								 | 
							
								  delete_matching(T,El,TR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_matching([H|T],El,[H|TR]):-!,
							 | 
						||
| 
								 | 
							
								  delete_matching(T,El,TR).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes Q(ch_j|y)\mathcal{D}(y,ch_{t(i,y)},ch_i) for all values ch_j of 
							 | 
						||
| 
								 | 
							
								Ch_j
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_term([],_Q_ch_y_par,Term,Term):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_term([ch(N,S)=Val|TVal],Q_ch_y_par,Term0,Term1):-
							 | 
						||
| 
								 | 
							
								  rb_lookup(ch(N,S),Q_ch_y,Q_ch_y_par),
							 | 
						||
| 
								 | 
							
								  nth(Val,Q_ch_y,Q_ch_y_val),
							 | 
						||
| 
								 | 
							
								  times(Q_ch_y_val,Term0,Term2),
							 | 
						||
| 
								 | 
							
								  compute_term(TVal,Q_ch_y_par,Term2,Term1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								single_rules_ed_contrib([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								single_rules_ed_contrib([H|T],[SR|TSR]):-
							 | 
						||
| 
								 | 
							
								  single_rules_ed_contrib_ch_val(H,0,SR),
							 | 
						||
| 
								 | 
							
								  single_rules_ed_contrib(T,TSR).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								single_rules_ed_contrib_ch_val([],SR,SR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								single_rules_ed_contrib_ch_val([(_B,QT,D)|T],SR0,SR):-
							 | 
						||
| 
								 | 
							
								  SR1 is SR0+QT*D,
							 | 
						||
| 
								 | 
							
								  single_rules_ed_contrib_ch_val(T,SR1,SR).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* sum(L1,L2,L) sums lists L1 and L2 element by element
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								sum([],[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								sum([H0|T0],[H1|T1],[H2|T2]):-
							 | 
						||
| 
								 | 
							
								  H2 is H0+H1,
							 | 
						||
| 
								 | 
							
								  sum(T0,T1,T2).  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* vec_times(L1,L2,L) multiplies lists L1 and L2 element by element
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								vec_times([],[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								vec_times([H0|T0],[H1|T1],[H2|T2]):-
							 | 
						||
| 
								 | 
							
								  H2 is H0*H1,
							 | 
						||
| 
								 | 
							
								  vec_times(T0,T1,T2).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes 
							 | 
						||
| 
								 | 
							
								EP'(ch_i,y)
							 | 
						||
| 
								 | 
							
								&=&\\
							 | 
						||
| 
								 | 
							
								&&\log \theta_{Hd_{r(k)}=ch_i|pa_{ch_k}}[y]1\{body(pa_{ch_i})=true\}+\\
							 | 
						||
| 
								 | 
							
								&&\delta(\{body(pa_{ch_i})=false,ch_i\neq null\}+\\
							 | 
						||
| 
								 | 
							
								&&R(i,ch,y) +\\
							 | 
						||
| 
								 | 
							
								&&1\{ch_i\neq null,val(ch_i)[y]=false\})
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								compute_EP([],[],[],_BodyTrue,_PTB,_Q_t_Y_par,_Ex,[],[],_Delta,EEP,EEP):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EP([''],[Prob_ch_y],[Theta],BodyTrue,PTB,_Q_t_Y_par,_Ex,[EP],[R],Delta,EEP0,EEP1):-!,
							 | 
						||
| 
								 | 
							
								  EP is log(Theta)*BodyTrue*PTB+Delta*R,
							 | 
						||
| 
								 | 
							
								  EEP1 is EEP0+EP*Prob_ch_y.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_EP([Val|TVal],[Prob_ch_y|TP],[Theta|TTheta],BodyTrue,PTB,Q_t_Y_par,Ex,[EP|TEP],[R|TR],Delta,EEP0,EEP1):-
							 | 
						||
| 
								 | 
							
								  Val=..[F|Args],
							 | 
						||
| 
								 | 
							
								  X=..[F,Ex|Args],
							 | 
						||
| 
								 | 
							
								  functor(Val,Pred,Arity),
							 | 
						||
| 
								 | 
							
								  (unseen(Pred/Arity)->
							 | 
						||
| 
								 | 
							
								    rb_lookup(Val,XPFalse,Q_t_Y_par),
							 | 
						||
| 
								 | 
							
								    XFalse is 1- XPFalse
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    (call(X)->
							 | 
						||
| 
								 | 
							
								      XFalse=0
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      XFalse=1
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  EP is log(Theta)*BodyTrue*PTB+ Delta*((1-BodyTrue)+BodyTrue*(1-PTB)+R+XFalse),
							 | 
						||
| 
								 | 
							
								  EEP2 is EEP0+EP*Prob_ch_y,
							 | 
						||
| 
								 | 
							
								  compute_EP(TVal,TP,TTheta,BodyTrue,PTB,Q_t_Y_par,Ex,TEP,TR,Delta,EEP2,EEP1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* computes E_{Q(ch_i|y)}[\log Q(ch_i)]&=&\sum_{ch_i}Q(ch_i|y)\log Q(ch_i)
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								compute_E_log_Q_ch([],[],E,E):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								compute_E_log_Q_ch([HProb_ch_y|T],[Prob_ch|T1],E0,E1):-
							 | 
						||
| 
								 | 
							
								  E2 is E0+HProb_ch_y*log(Prob_ch),
							 | 
						||
| 
								 | 
							
								  compute_E_log_Q_ch(T,T1,E2,E1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* builds the initial Q table, with one entry for each example and each choice
							 | 
						||
| 
								 | 
							
								variable 
							 | 
						||
| 
								 | 
							
								q is an array with the example number as index
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								build_q_table(CH):-
							 | 
						||
| 
								 | 
							
								    ex(NEx),
							 | 
						||
| 
								 | 
							
								  add_Q_par(0,NEx,CH).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over the examples for building the Q table
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								add_Q_par(N,N,_CH):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_Q_par(N,NEx,CH):-
							 | 
						||
| 
								 | 
							
								  rb_new(Q_Y0),
							 | 
						||
| 
								 | 
							
								  add_Q_Y_par(CH,Q_Y0,Q_Y1),
							 | 
						||
| 
								 | 
							
								  update_array(q,N,Q_Y1),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								  add_Q_par(N1,NEx,CH).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over the choice variables and builds Q(ch|y) a rb_tree with ch(N,S) as key
							 | 
						||
| 
								 | 
							
								and the distribution in the form of a list of probabilities as value
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								add_Q_Y_par([],Q,Q).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_Q_Y_par([ch(N,S)|T],Q0,Q1):-
							 | 
						||
| 
								 | 
							
								  def_rule_by_num(N,_V,_HL,_BL),!,
							 | 
						||
| 
								 | 
							
								  rb_insert(Q0,ch(N,S),[1.0],Q2),
							 | 
						||
| 
								 | 
							
								  add_Q_Y_par(T,Q2,Q1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_Q_Y_par([ch(N,S)|T],Q0,Q1):-
							 | 
						||
| 
								 | 
							
								  rule_by_num(N,_V,_NH,HL,_BL),
							 | 
						||
| 
								 | 
							
								  length(HL,NHL),
							 | 
						||
| 
								 | 
							
								  Prob is 1/NHL,
							 | 
						||
| 
								 | 
							
								  PertSize is Prob*0.1,
							 | 
						||
| 
								 | 
							
								  gen_random_param(NHL,0,PertSize,Prob,Par),
							 | 
						||
| 
								 | 
							
								  rb_insert(Q0,ch(N,S),Par,Q2),
							 | 
						||
| 
								 | 
							
								  add_Q_Y_par(T,Q2,Q1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* generates an initial random distribution for Q(ch|y)
							 | 
						||
| 
								 | 
							
								the distribution is obtained by randomly perturbing an uniform distribution
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								gen_random_param(0,_Sum,_PertSize,_P,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								gen_random_param(N,Sum,PertSize,P,[P1|Par]):-
							 | 
						||
| 
								 | 
							
								  TotMass is 1-Sum,
							 | 
						||
| 
								 | 
							
								  Mass is TotMass/N,
							 | 
						||
| 
								 | 
							
								  LowerBound is -PertSize,
							 | 
						||
| 
								 | 
							
								  random(LowerBound,PertSize,Pert),
							 | 
						||
| 
								 | 
							
								  P2 is Mass+Pert,
							 | 
						||
| 
								 | 
							
								  N1 is N-1,
							 | 
						||
| 
								 | 
							
								  Sum2 is Sum+P2,
							 | 
						||
| 
								 | 
							
								  (Sum2>1.0->
							 | 
						||
| 
								 | 
							
								    P1 = Mass,
							 | 
						||
| 
								 | 
							
								    Sum1 is Sum+Mass
							 | 
						||
| 
								 | 
							
								  ; 
							 | 
						||
| 
								 | 
							
								    P1 = P2,
							 | 
						||
| 
								 | 
							
								    Sum1 = Sum2    
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  gen_random_param(N1,Sum1,PertSize,P,Par).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* builds the initial Q(t|y) table, with one entry for each example and each T
							 | 
						||
| 
								 | 
							
								variable 
							 | 
						||
| 
								 | 
							
								q is an array with the example number as index
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								build_qt_table(T):-
							 | 
						||
| 
								 | 
							
								    ex(NEx),
							 | 
						||
| 
								 | 
							
								  add_Qt_par(0,NEx,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over the examples for building the Q(t|y) table
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								add_Qt_par(N,N,_T):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_Qt_par(N,NEx,T):-
							 | 
						||
| 
								 | 
							
								  rb_new(Q_Y0),
							 | 
						||
| 
								 | 
							
								  add_Qt_Y_par(T,Q_Y0,Q_Y1),
							 | 
						||
| 
								 | 
							
								  update_array(qt,N,Q_Y1),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								  add_Qt_par(N1,NEx,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* cycles over the T variables and builds Q(t|y) a rb_tree with t as key
							 | 
						||
| 
								 | 
							
								and the distribution in the form of a probability
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								add_Qt_Y_par([],Q,Q).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_Qt_Y_par([H|T],Q0,Q1):-
							 | 
						||
| 
								 | 
							
								  random(Par),
							 | 
						||
| 
								 | 
							
								  rb_insert(Q0,H,Par,Q2),
							 | 
						||
| 
								 | 
							
								  add_Qt_Y_par(T,Q2,Q1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* builds the p table with one entry for each example and each choice
							 | 
						||
| 
								 | 
							
								variable 
							 | 
						||
| 
								 | 
							
								p is an array with the rule number as index
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								build_p_table(Rules):-
							 | 
						||
| 
								 | 
							
								  setting(max_rules,MR),
							 | 
						||
| 
								 | 
							
								%  length(Rules,N),
							 | 
						||
| 
								 | 
							
								  array(p,MR),
							 | 
						||
| 
								 | 
							
								  add_P_par(Rules).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* retrieves the initial values of the theta vectore and stores it in the
							 | 
						||
| 
								 | 
							
								p array
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								add_P_par([]).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_P_par([def_rule(_N,_S,_H,_BL)|T]):-!,
							 | 
						||
| 
								 | 
							
								  add_P_par(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_P_par([rule(N,_V,_NH,HL,_BL,_LogF)|T]):-
							 | 
						||
| 
								 | 
							
								  find_atoms_head(HL,Atoms,Probs),
							 | 
						||
| 
								 | 
							
								  update_array(p,N,d(Probs,Atoms)),
							 | 
						||
| 
								 | 
							
								  add_P_par(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* builds the Bayesian network equivalent to the current model
							 | 
						||
| 
								 | 
							
								*/  
							 | 
						||
| 
								 | 
							
								build_network_IB(CH,PAX,T,TCh,R,LogSize):-
							 | 
						||
| 
								 | 
							
								  ex(NEx),
							 | 
						||
| 
								 | 
							
								  get_ouptut_atoms(O),
							 | 
						||
| 
								 | 
							
								  %rb_new(C0),
							 | 
						||
| 
								 | 
							
								  generate_ground1(0,NEx,O,[],L),
							 | 
						||
| 
								 | 
							
								  build_ground_lpad(L,CL),
							 | 
						||
| 
								 | 
							
								%  write(find_ground_atoms),nl,
							 | 
						||
| 
								 | 
							
								%  flush_output,
							 | 
						||
| 
								 | 
							
								  find_ground_atoms(CL,[],GAD0,[],GUAD0),
							 | 
						||
| 
								 | 
							
								  generate_goal_DB(0,NEx,O,[],GL),
							 | 
						||
| 
								 | 
							
								  get_atoms(GL,Atoms1),
							 | 
						||
| 
								 | 
							
								  append(GAD0,Atoms1,GAD),
							 | 
						||
| 
								 | 
							
								  remove_duplicates(GAD,X),
							 | 
						||
| 
								 | 
							
								%  write('X'),write(X),nl,
							 | 
						||
| 
								 | 
							
								  remove_duplicates(GUAD0,T),
							 | 
						||
| 
								 | 
							
								%  write('T'),write(T),nl,
							 | 
						||
| 
								 | 
							
								  rb_new(R0),
							 | 
						||
| 
								 | 
							
								  choice_vars_IB(CL,CH,0,LogSize0,R0,R1),
							 | 
						||
| 
								 | 
							
								  length(T,LST),
							 | 
						||
| 
								 | 
							
								  LogSize is LogSize0+LST,
							 | 
						||
| 
								 | 
							
								  rb_visit(R1,R),
							 | 
						||
| 
								 | 
							
								%  write('R'),write(R),nl,
							 | 
						||
| 
								 | 
							
								  rb_new(PAX0),
							 | 
						||
| 
								 | 
							
								  get_X_parents(CL,PAX0,PAX1),
							 | 
						||
| 
								 | 
							
								  add_parentless_X(X,PAX1,PAX),
							 | 
						||
| 
								 | 
							
								  rb_new(TCh0),
							 | 
						||
| 
								 | 
							
								  get_T_children(CL,TCh0,TCh1),
							 | 
						||
| 
								 | 
							
								  add_childless_T(T,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								find_ground_atoms([],GA,GA,GUA,GUA):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_ground_atoms([d(_N,_S,H,Body)|T],GA0,GA,GUA0,GUA):-!,
							 | 
						||
| 
								 | 
							
								  %write(fga),
							 | 
						||
| 
								 | 
							
								        H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  functor(H1,P,A),
							 | 
						||
| 
								 | 
							
								  (input_cw(P/A)->
							 | 
						||
| 
								 | 
							
								    find_atoms_body(T,GA0,GA,GUA0,GUA)
							 | 
						||
| 
								 | 
							
								  ;        
							 | 
						||
| 
								 | 
							
								    (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								                  find_atoms_body(T,GA0,GA1,[H1|GUA0],GUA1)
							 | 
						||
| 
								 | 
							
								          ;
							 | 
						||
| 
								 | 
							
								                  find_atoms_body(T,[H1|GA0],GA1,GUA0,GUA1)
							 | 
						||
| 
								 | 
							
								          )
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  find_atoms_body(Body,GA1,GA2,GUA1,GUA2),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms(T,GA2,GA,GUA2,GUA).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_ground_atoms([(_N,_S,Head,Body)|T],GA0,GA,GUA0,GUA):-
							 | 
						||
| 
								 | 
							
								  %write(fga),
							 | 
						||
| 
								 | 
							
								  find_atoms_head(Head,GA0,GA1,GUA0,GUA1),
							 | 
						||
| 
								 | 
							
								  find_atoms_body(Body,GA1,GA2,GUA1,GUA2),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms(T,GA2,GA,GUA2,GUA).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_body([],GA,GA,GUA,GUA):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_body([\+H|T],GA0,GA,GUA0,GUA):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(H),!,
							 | 
						||
| 
								 | 
							
								  find_atoms_body(T,GA0,GA,GUA0,GUA).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_body([H|T],GA0,GA,GUA0,GUA):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(H),!,
							 | 
						||
| 
								 | 
							
								  find_atoms_body(T,GA0,GA,GUA0,GUA).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_body([\+H|T],GA0,GA,GUA0,GUA):-!,
							 | 
						||
| 
								 | 
							
								  H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  functor(H1,P,A),
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    find_atoms_body(T,GA0,GA,[H1|GUA0],GUA)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    find_atoms_body(T,[H1|GA0],GA,GUA0,GUA)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_body([H|T],GA0,GA,GUA0,GUA):-!,
							 | 
						||
| 
								 | 
							
								  H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  functor(H1,P,A),
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    find_atoms_body(T,GA0,GA,[H1|GUA0],GUA)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    find_atoms_body(T,[H1|GA0],GA,GUA0,GUA)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_head([],GA,GA,GUA,GUA).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_head(['':_P],GA,GA,GUA,GUA):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								find_atoms_head([H:_P|T],GA0,GA,GUA0,GUA):-
							 | 
						||
| 
								 | 
							
								  H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  functor(H1,P,A),
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    find_atoms_head(T,GA0,GA,[H1|GUA0],GUA)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    find_atoms_head(T,[H1|GA0],GA,GUA0,GUA)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_T_children([],TCh,TCh):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_T_children([d(N,S,_Head,Body)|T],TCh0,TCh):-!,
							 | 
						||
| 
								 | 
							
								  scan_body_for_T(Body,N,S,TCh0,TCh1),
							 | 
						||
| 
								 | 
							
								  get_T_children(T,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_T_children([(N,S,_Head,Body)|T],TCh0,TCh):-
							 | 
						||
| 
								 | 
							
								  scan_body_for_T(Body,N,S,TCh0,TCh1),
							 | 
						||
| 
								 | 
							
								  get_T_children(T,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* collects the atoms in the head of the rule corresponding to ch(M,S)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								scan_body_for_T([],_N,_S,TCh,TCh):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_body_for_T([\+ H|T],N,S,TCh0,TCh):-!,
							 | 
						||
| 
								 | 
							
								  H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  functor(H1,P,A),
							 | 
						||
| 
								 | 
							
								  (unseen(P/A)->
							 | 
						||
| 
								 | 
							
								    (rb_lookup(H,Ch,TCh0)->
							 | 
						||
| 
								 | 
							
								      rb_update(TCh0,H,[ch(N,S)|Ch],TCh1)
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      rb_insert(TCh0,H,[ch(N,S)],TCh1)
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    TCh1=TCh0
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  scan_body_for_T(T,N,S,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_body_for_T([H|T],N,S,TCh0,TCh):-  
							 | 
						||
| 
								 | 
							
								  H=..[F,_|R],
							 | 
						||
| 
								 | 
							
								  H1=..[F|R],
							 | 
						||
| 
								 | 
							
								  (rb_lookup(H1,Ch,TCh0)->
							 | 
						||
| 
								 | 
							
								    rb_update(TCh0,H1,[ch(N,S)|Ch],TCh1)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(TCh0,H1,[ch(N,S)],TCh1)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  scan_body_for_T(T,N,S,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								get_X_parents([],_CL,PAX,PAX):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_X_parents([X|TX],CL,PAX0,PAX1):-
							 | 
						||
| 
								 | 
							
								  X=..[F|Args],
							 | 
						||
| 
								 | 
							
								  X1=..[F,_Y|Args],
							 | 
						||
| 
								 | 
							
								  findall(ch(N,S),
							 | 
						||
| 
								 | 
							
								  (
							 | 
						||
| 
								 | 
							
								    member((N,S,Head,_Body),CL),member((X1:_P),Head)
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								    member(d(N,S,X1,_Body),CL)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								    PAX),
							 | 
						||
| 
								 | 
							
								  rb_insert(PAX0,X,PAX,PAX2),
							 | 
						||
| 
								 | 
							
								  get_X_parents(TX,CL,PAX2,PAX1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_parentless_X([],PAX,PAX).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_parentless_X([X|T],PAX0,PAX1):-
							 | 
						||
| 
								 | 
							
								  (rb_lookup(X,_PA,PAX0)->
							 | 
						||
| 
								 | 
							
								    PAX2=PAX0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(PAX0,X,[],PAX2)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  add_parentless_X(T,PAX2,PAX1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_childless_T([],TCh,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_childless_T([T|TT],TCh0,TCh):-
							 | 
						||
| 
								 | 
							
								  (rb_lookup(T,_Children,TCh0)->
							 | 
						||
| 
								 | 
							
								    TCh1=TCh0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(TCh0,T,[],TCh1)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  add_childless_T(TT,TCh1,TCh).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* for each ground atoms, it finds the choice variables that are its parents
							 | 
						||
| 
								 | 
							
								for each grounding of a clause, it collects the atoms in the head
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								get_X_parents([],PAX,PAX):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_X_parents([d(N,S,Head,_Body)|T],PAX0,PAX1):-
							 | 
						||
| 
								 | 
							
								  scan_head([Head:1.0],N,S,PAX0,PAX2),
							 | 
						||
| 
								 | 
							
								  get_X_parents(T,PAX2,PAX1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_X_parents([(N,S,Head,_Body)|T],PAX0,PAX1):-
							 | 
						||
| 
								 | 
							
								  scan_head(Head,N,S,PAX0,PAX2),
							 | 
						||
| 
								 | 
							
								  get_X_parents(T,PAX2,PAX1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* collects the atoms in the head of the rule corresponding to ch(M,S)
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								scan_head([],_N,_S,PAX,PAX).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_head(['':_P],_N,_S,PAX,PAX):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								scan_head([H:_P|T],N,S,PAX0,PAX1):-  
							 | 
						||
| 
								 | 
							
								  H=..[F,_Y|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[F|Args],
							 | 
						||
| 
								 | 
							
								  (rb_lookup(H1,Par,PAX0)->
							 | 
						||
| 
								 | 
							
								    rb_update(PAX0,H1,[ch(N,S)|Par],PAX2)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(PAX0,H1,[ch(N,S)],PAX2)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  scan_head(T,N,S,PAX2,PAX1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* generates the grounding of a model 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								generate_ground(L1,GA):-
							 | 
						||
| 
								 | 
							
								  find_modes(Modes),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms_modes(Modes,[],GA),
							 | 
						||
| 
								 | 
							
								  findall(rule(N,V,HL,BL),rule_by_num(N,V,_NH,HL,BL),LR),
							 | 
						||
| 
								 | 
							
								  ground_rules(LR,[],L1).
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								generate_ground(L1,GA):-
							 | 
						||
| 
								 | 
							
								  find_modes(Modes),
							 | 
						||
| 
								 | 
							
								%  get_types(Modes,[],Types),
							 | 
						||
| 
								 | 
							
								  rb_new(Types0),
							 | 
						||
| 
								 | 
							
								  get_constants_types(Modes,Types0,Types1),
							 | 
						||
| 
								 | 
							
								  rb_visit(Types1,TypesL),
							 | 
						||
| 
								 | 
							
								  asser_all_const(TypesL),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms_modes(Modes,[],GA),
							 | 
						||
| 
								 | 
							
								  format("Atoms ~p~n",[GA]),
							 | 
						||
| 
								 | 
							
								  findall(rule(N,V,HL,BL),rule_by_num(N,V,_NH,HL,BL),LR),
							 | 
						||
| 
								 | 
							
								  ground_rules(LR,[],L1).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground1(N,N,_O,L0,L):-!,
							 | 
						||
| 
								 | 
							
								  remove_duplicates(L0,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground1(N0,N,O,L0,L1):-
							 | 
						||
| 
								 | 
							
								  %format("Ex ~d~n",[N0]),
							 | 
						||
| 
								 | 
							
								  %(N0=320->bp;true),
							 | 
						||
| 
								 | 
							
								  generate_goal1(O,N0,[],GL),
							 | 
						||
| 
								 | 
							
								  generate_ground1_goals(GL,[],Exp0),
							 | 
						||
| 
								 | 
							
								  append(Exp0,Exp1),
							 | 
						||
| 
								 | 
							
								  %length(Exp1,Len),write(Len),nl,
							 | 
						||
| 
								 | 
							
								  remove_head(Exp1,Exp),
							 | 
						||
| 
								 | 
							
								  append(Exp,L0,L2),
							 | 
						||
| 
								 | 
							
								%  add_to_tree(Exp,L0,L2),
							 | 
						||
| 
								 | 
							
								  %write(add_to_tree),
							 | 
						||
| 
								 | 
							
								%  flush_output,
							 | 
						||
| 
								 | 
							
								  N1 is N0+1,
							 | 
						||
| 
								 | 
							
								  generate_ground1(N1,N,O,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground1_goals([],Exp,Exp).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground1_goals([H|T],Exp0,Exp):-
							 | 
						||
| 
								 | 
							
								  setting(depth_bound,DB),
							 | 
						||
| 
								 | 
							
								  findall(Deriv,inference_ib:find_deriv_inf1([H],DB,Deriv),Exp1),
							 | 
						||
| 
								 | 
							
								  append(Exp0,Exp1,Exp2),
							 | 
						||
| 
								 | 
							
								  generate_ground1_goals(T,Exp2,Exp).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_to_tree([],L,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_to_tree([(R,S)|T],L0,L):-
							 | 
						||
| 
								 | 
							
								  %write(t),
							 | 
						||
| 
								 | 
							
								  (rb_lookup((R,S),_,L0)->
							 | 
						||
| 
								 | 
							
								    L1=L0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(L0,(R,S),true,L1)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  add_to_tree(T,L1,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground2(N,N,_O,L,L):-%write(fine),nl,
							 | 
						||
| 
								 | 
							
								  !.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_ground2(N0,N,O,L0,L1):-
							 | 
						||
| 
								 | 
							
								  generate_goal(O,N0,[],GL),
							 | 
						||
| 
								 | 
							
								  %format("Ex ~d~n",[N0]),
							 | 
						||
| 
								 | 
							
								  setting(depth_bound,DB),
							 | 
						||
| 
								 | 
							
								  findall(Deriv,inference_ib:find_deriv_inf1(GL,DB,Deriv),Exp0),
							 | 
						||
| 
								 | 
							
								  append(Exp0,Exp1),
							 | 
						||
| 
								 | 
							
								  remove_head(Exp1,Exp),
							 | 
						||
| 
								 | 
							
								  add_to_list(Exp,L0,L2),
							 | 
						||
| 
								 | 
							
								  N1 is N0+1,
							 | 
						||
| 
								 | 
							
								  generate_ground2(N1,N,O,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_to_list([],L,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_to_list([(R,S)|T],L0,L):-
							 | 
						||
| 
								 | 
							
								  (member(((R,S)-_),L0)->
							 | 
						||
| 
								 | 
							
								    L1=L0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    L1=[((R,S)-true)|L0]
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  add_to_list(T,L1,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_constants_types([],Types,Types).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_constants_types([H|T],Types0,Types1):-
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,N),
							 | 
						||
| 
								 | 
							
								  length(Args1,N),  
							 | 
						||
| 
								 | 
							
								  H1=..[F,Mod|Args1],
							 | 
						||
| 
								 | 
							
								  get_const_atom(Args,Args1,Mod,Args1,H1,Types0,Types2),
							 | 
						||
| 
								 | 
							
								  get_constants_types(T,Types2,Types1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_const_atom([],[],_Mod,_Args1,_H,Types,Types).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								get_const_atom([+Type|TT],[V|TV],Mod,Args1,H,Types0,Types1):-
							 | 
						||
| 
								 | 
							
								  delete(Args1,V,Vars),
							 | 
						||
| 
								 | 
							
								  setof(V,(Vars,Mod)^H,L),
							 | 
						||
| 
								 | 
							
								  insert_const(L,Type,Types0,Types2),
							 | 
						||
| 
								 | 
							
								  get_const_atom(TT,TV,Mod,Args1,H,Types2,Types1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								get_const_atom([-Type|TT],[V|TV],Mod,Args1,H,Types0,Types1):-
							 | 
						||
| 
								 | 
							
								  delete(Args1,V,Vars),
							 | 
						||
| 
								 | 
							
								  setof(V,(Vars,Mod)^H,L),
							 | 
						||
| 
								 | 
							
								  insert_const(L,Type,Types0,Types2),
							 | 
						||
| 
								 | 
							
								  get_const_atom(TT,TV,Mod,Args1,H,Types2,Types1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								insert_const(L,Type,Types0,Types1):-
							 | 
						||
| 
								 | 
							
								  (rb_lookup(Type,LA,Types0)->
							 | 
						||
| 
								 | 
							
								    append(L,LA,LP),
							 | 
						||
| 
								 | 
							
								    remove_duplicates(LP,LPP),
							 | 
						||
| 
								 | 
							
								    rb_update(Types0,Type,LPP,Types1)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(Types0,Type,L,Types1)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								asser_all_const([]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								asser_all_const([Type-Const|T]):-
							 | 
						||
| 
								 | 
							
								  format("Type ~a const ~p~n",[Type,Const]),
							 | 
						||
| 
								 | 
							
								  assert_const(Const,Type),
							 | 
						||
| 
								 | 
							
								  asser_all_const(T).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								assert_const([],_Type).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								assert_const([H|T],Type):-
							 | 
						||
| 
								 | 
							
								  At=..[Type,H],
							 | 
						||
| 
								 | 
							
								  assertz(At),
							 | 
						||
| 
								 | 
							
								  assert_const(T,Type).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* generates the grounding of a set of rules 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								ground_rules([],L,L):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_rules([rule(N,V,HL,BL)|T],L0,L1):-
							 | 
						||
| 
								 | 
							
								  HL=[A:_P|_T],
							 | 
						||
| 
								 | 
							
								  A=..[_F,Y|_Args],
							 | 
						||
| 
								 | 
							
								  remove_module_head(HL,HL1),
							 | 
						||
| 
								 | 
							
								  remove_module(BL,BL1),
							 | 
						||
| 
								 | 
							
								  setof((N,V,HL1,BL1),Y^(ground_head(HL),ground_body(BL)),L),!,
							 | 
						||
| 
								 | 
							
								  append(L0,L,L2),
							 | 
						||
| 
								 | 
							
								  ground_rules(T,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_rules([_H|T],L0,L1):-
							 | 
						||
| 
								 | 
							
								  ground_rules(T,L0,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* removes the module (example) argument from the atoms of a head
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								remove_module_head(['':P],['':P]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_module_head([H:P|T],[H1:P|T1]):-
							 | 
						||
| 
								 | 
							
								  H=..[F,_Y|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[F|Args],
							 | 
						||
| 
								 | 
							
								  remove_module_head(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* removes the module (example) argument from the atoms of a body
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								remove_module([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_module([\+H|T],[\+H1|T1]):-!,
							 | 
						||
| 
								 | 
							
								  H=..[P,_Y|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								  remove_module(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_module([H|T],[H1|T1]):-
							 | 
						||
| 
								 | 
							
								  H=..[P,_Y|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[P|Args],
							 | 
						||
| 
								 | 
							
								  remove_module(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* adds the module (example) argument from the atoms of a body
							 | 
						||
| 
								 | 
							
								the value of the argument is Y
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								add_module([],_Y,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_module([\+H|T],Y,[\+H1|T1]):-!,
							 | 
						||
| 
								 | 
							
								  H=..[P|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[P,Y|Args],
							 | 
						||
| 
								 | 
							
								  add_module(T,Y,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_module([H|T],Y,[H1|T1]):-
							 | 
						||
| 
								 | 
							
								  H=..[P|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[P,Y|Args],
							 | 
						||
| 
								 | 
							
								  add_module(T,Y,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* instantiates a head
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								/* instantiates a head
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								ground_head(['':_P]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_head([H:_P|T]):-
							 | 
						||
| 
								 | 
							
								  \+ \+ H,!,
							 | 
						||
| 
								 | 
							
								  call(H),
							 | 
						||
| 
								 | 
							
								  ground_head(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_head([H:_P|T]):-
							 | 
						||
| 
								 | 
							
								  call(neg(H)),
							 | 
						||
| 
								 | 
							
								  ground_head(T).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* instantiates a body
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								ground_body([]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_body([\+H|T]):-!,
							 | 
						||
| 
								 | 
							
								  \+call(H),
							 | 
						||
| 
								 | 
							
								  ground_body(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_body([H|T]):-
							 | 
						||
| 
								 | 
							
								  call(H),
							 | 
						||
| 
								 | 
							
								  ground_body(T).
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								ground_head(['':_P]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_head([H:_P|T]):-
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,N),
							 | 
						||
| 
								 | 
							
								  length(Args1,N),
							 | 
						||
| 
								 | 
							
								  H1=..[F|Args1],
							 | 
						||
| 
								 | 
							
								  modeh(_,H1),
							 | 
						||
| 
								 | 
							
								  instantiate_args(Args1,Args),
							 | 
						||
| 
								 | 
							
								  ground_head(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								instantiate_args([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								instantiate_args([+Type|T],[V|T1]):-!,
							 | 
						||
| 
								 | 
							
								  A=..[Type,V],
							 | 
						||
| 
								 | 
							
								  call(A),
							 | 
						||
| 
								 | 
							
								  instantiate_args(T,T1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								instantiate_args([-Type|T],[V|T1]):-
							 | 
						||
| 
								 | 
							
								  A=..[Type,V],
							 | 
						||
| 
								 | 
							
								  call(A),
							 | 
						||
| 
								 | 
							
								  instantiate_args(T,T1).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* instantiates a body
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								ground_body([]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_body([\+H|T]):-!,
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,N),
							 | 
						||
| 
								 | 
							
								  length(Args1,N),
							 | 
						||
| 
								 | 
							
								  H1=..[F|Args1],
							 | 
						||
| 
								 | 
							
								  modeb(_,H1),
							 | 
						||
| 
								 | 
							
								  instantiate_args(Args1,Args),
							 | 
						||
| 
								 | 
							
								  ground_body(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ground_body([H|T]):-
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,N),
							 | 
						||
| 
								 | 
							
								  length(Args1,N),
							 | 
						||
| 
								 | 
							
								  H1=..[F|Args1],
							 | 
						||
| 
								 | 
							
								  modeb(_,H1),
							 | 
						||
| 
								 | 
							
								  instantiate_args(Args1,Args),
							 | 
						||
| 
								 | 
							
								  ground_body(T).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								/* returns the set of modes specified in the language bias
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								find_modes(Modes):-
							 | 
						||
| 
								 | 
							
								  findall(Pred,modeh(_,Pred),L0),
							 | 
						||
| 
								 | 
							
								  findall(Pred,modeb(_,Pred),L1),
							 | 
						||
| 
								 | 
							
								  findall(Pred,mode(_,Pred),L2),
							 | 
						||
| 
								 | 
							
								  append(L0,L1,L3),
							 | 
						||
| 
								 | 
							
								  append(L3,L2,Modes).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_types([],L,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								get_types([H|T],L0,L1):-
							 | 
						||
| 
								 | 
							
								  H=..[_F|Args],
							 | 
						||
| 
								 | 
							
								  remove_io(Args,L0,L2),
							 | 
						||
| 
								 | 
							
								  get_types(T,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_io([],L,L).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_io([+H|T],L0,L1):-
							 | 
						||
| 
								 | 
							
								  (member(H,L0)->
							 | 
						||
| 
								 | 
							
								    L2=L0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    append(L0,[H],L2)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  remove_io(T,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_io([-H|T],L0,L1):-
							 | 
						||
| 
								 | 
							
								  (member(H,L0)->
							 | 
						||
| 
								 | 
							
								    L2=L0
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    append(L0,[H],L2)
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  remove_io(T,L2,L1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* find all the ground atoms for each mode 
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								find_ground_atoms_modes([],GA,GA):-!.
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								find_ground_atoms_modes([A|T],GA0,GA1):-
							 | 
						||
| 
								 | 
							
								  A=..[P|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,L),
							 | 
						||
| 
								 | 
							
								  length(Args1,L),
							 | 
						||
| 
								 | 
							
								  A1=..[P,Y|Args1],
							 | 
						||
| 
								 | 
							
								  A2=..[P|Args1],
							 | 
						||
| 
								 | 
							
								  (setof(A2,Y^A1,LInst)->
							 | 
						||
| 
								 | 
							
								  /*  (setof(A2,Y^neg(A1),LInstN)->
							 | 
						||
| 
								 | 
							
								      append(LInst,LInstN,LI)
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      LI=LInst
							 | 
						||
| 
								 | 
							
								    )*/
							 | 
						||
| 
								 | 
							
								    LI=LInst
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    LI=[]
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  remove_duplicates(LI,LI1),
							 | 
						||
| 
								 | 
							
								  append(GA0,LI1,GA2),
							 | 
						||
| 
								 | 
							
								  assert_all(LI1),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms_modes(T,GA2,GA1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								find_ground_atoms_modes([],GA,GA):-!.
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								find_ground_atoms_modes([A|T],GA0,GA1):-
							 | 
						||
| 
								 | 
							
								  A=..[P|Args],
							 | 
						||
| 
								 | 
							
								  length(Args,L),
							 | 
						||
| 
								 | 
							
								  length(Args1,L),
							 | 
						||
| 
								 | 
							
								  A2=..[P|Args1],
							 | 
						||
| 
								 | 
							
								  findall(A2,instantiate_args(Args,Args1),LInst),
							 | 
						||
| 
								 | 
							
								  append(GA0,LInst,GA2),
							 | 
						||
| 
								 | 
							
								%  assert_all(LInst),
							 | 
						||
| 
								 | 
							
								  find_ground_atoms_modes(T,GA2,GA1).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								/* assert_all(L) asserts all the atoms of list L
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								assert_all([]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								assert_all([H|T]):-
							 | 
						||
| 
								 | 
							
								  assert(H),
							 | 
						||
| 
								 | 
							
								  assert_all(T).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								/* choice_vars_IB(CL,CH,0,LogSize,R0,R1) given the grounding CL of an LPAD 
							 | 
						||
| 
								 | 
							
								returns the list of choice variables, the log size and an rb tree of rules R1,
							 | 
						||
| 
								 | 
							
								where each rule id is associated to the set of the substitution that instantiate
							 | 
						||
| 
								 | 
							
								it
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								choice_vars_IB([],[],LogSize,LogSize,R,R):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								choice_vars_IB([d(N,S,_H,_B)|T],CH,LogSize0,LogSize1,R0,R1):-
							 | 
						||
| 
								 | 
							
								  (rb_lookup(N,L,R0)->
							 | 
						||
| 
								 | 
							
								    (member(S,L)->
							 | 
						||
| 
								 | 
							
								      CH=CH1,
							 | 
						||
| 
								 | 
							
								      R2=R0      
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      rb_update(R0,N,[S|L],R2),
							 | 
						||
| 
								 | 
							
								      CH=[ch(N,S)|CH1]
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(R0,N,[S],R2),
							 | 
						||
| 
								 | 
							
								    CH=[ch(N,S)|CH1]
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  choice_vars_IB(T,CH1,LogSize0,LogSize1,R2,R1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								choice_vars_IB([(N,S,H,_B)|T],CH,LogSize0,LogSize1,R0,R1):-
							 | 
						||
| 
								 | 
							
								  (rb_lookup(N,L,R0)->
							 | 
						||
| 
								 | 
							
								    (member(S,L)->
							 | 
						||
| 
								 | 
							
								      LogSize2 = LogSize0,
							 | 
						||
| 
								 | 
							
								      CH=CH1,
							 | 
						||
| 
								 | 
							
								      R2=R0      
							 | 
						||
| 
								 | 
							
								    ;
							 | 
						||
| 
								 | 
							
								      rb_update(R0,N,[S|L],R2),
							 | 
						||
| 
								 | 
							
								      length(H,SizeCH),
							 | 
						||
| 
								 | 
							
								      LogSize2 is LogSize0+log(SizeCH),
							 | 
						||
| 
								 | 
							
								      CH=[ch(N,S)|CH1]
							 | 
						||
| 
								 | 
							
								    )
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    rb_insert(R0,N,[S],R2),
							 | 
						||
| 
								 | 
							
								    length(H,SizeCH),
							 | 
						||
| 
								 | 
							
								    LogSize2 is LogSize0+log(SizeCH),
							 | 
						||
| 
								 | 
							
								    CH=[ch(N,S)|CH1]
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  choice_vars_IB(T,CH1,LogSize2,LogSize1,R2,R1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_goal_DB(N,N,_O,GL,GL):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_goal_DB(N0,N,O,G0,G1):-
							 | 
						||
| 
								 | 
							
								  generate_goal(O,N0,G0,G2),
							 | 
						||
| 
								 | 
							
								  N1 is N0+1,
							 | 
						||
| 
								 | 
							
								  generate_goal_DB(N1,N,O,G2,G1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* unused
							 | 
						||
| 
								 | 
							
								random_restarts(1,Model,SS,CLL,Model,SS,CLL,_DB):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								random_restarts(N,Model0,SS0,CLL0,Model1,SS1,CLL1,DB):-
							 | 
						||
| 
								 | 
							
								  setting(verbosity,Ver),
							 | 
						||
| 
								 | 
							
								  (Ver>4->
							 | 
						||
| 
								 | 
							
								    setting(random_restarts_number,NMax),
							 | 
						||
| 
								 | 
							
								    Num is NMax-N+1,
							 | 
						||
| 
								 | 
							
								    format("Restart number ~d~n",[Num])
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  randomize(Model0,ModelR),
							 | 
						||
| 
								 | 
							
								  em_iteration(ModelR,ModelR1,SSR,CLLR,DB),
							 | 
						||
| 
								 | 
							
								  (Ver>4->
							 | 
						||
| 
								 | 
							
								    format("CLL ~f~n",[CLLR])
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ),
							 | 
						||
| 
								 | 
							
								  N1 is N-1,
							 | 
						||
| 
								 | 
							
								  (CLLR>CLL0->
							 | 
						||
| 
								 | 
							
								    random_restarts(N1,ModelR1,SSR,CLLR,Model1,SS1,CLL1,DB)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    random_restarts(N1,Model0,SS0,CLL0,Model1,SS1,CLL1,DB)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								randomize([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								randomize([rule(N,V,NH,HL,BL,LogF)|T],[rule(N,V,NH,HL1,BL,LogF)|T1]):-!,
							 | 
						||
| 
								 | 
							
								  length(HL,L),
							 | 
						||
| 
								 | 
							
								  Int is 1.0/L,
							 | 
						||
| 
								 | 
							
								  randomize_head(Int,HL,0,HL1),
							 | 
						||
| 
								 | 
							
								  randomize(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								randomize([H|T],[H|T1]):-
							 | 
						||
| 
								 | 
							
								  randomize(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								randomize_head(_Int,['':_],P,['':PNull1]):-!,
							 | 
						||
| 
								 | 
							
								  PNull is 1.0-P,
							 | 
						||
| 
								 | 
							
								  (PNull>=0.0->
							 | 
						||
| 
								 | 
							
								    PNull1 =PNull
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PNull1=0.0
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								randomize_head(_Int,[H:_],P,[H:PN]):-!,
							 | 
						||
| 
								 | 
							
								  PN is 1.0-P.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								randomize_head(Int,[H:_|T],P,[H:PH1|NT]):-
							 | 
						||
| 
								 | 
							
								  PMax is 1.0-P,
							 | 
						||
| 
								 | 
							
								  random(0,PMax,PH1),
							 | 
						||
| 
								 | 
							
								  P1 is P+PH1,  
							 | 
						||
| 
								 | 
							
								  randomize_head(Int,T,P1,NT).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* asserts the model in the database
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								assert_model([]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								assert_model([def_rule(N,S,H,BL)|T]):-
							 | 
						||
| 
								 | 
							
								  assertz(def_rule(H,BL,N,S)),
							 | 
						||
| 
								 | 
							
								  assertz(def_rule_by_num(N,S,H,BL)),
							 | 
						||
| 
								 | 
							
								  assert_model(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								assert_model([rule(N,V,NH,HL,BL,_LogF)|T]):-
							 | 
						||
| 
								 | 
							
								  assert_rules(HL,0,HL,BL,NH,N,V),
							 | 
						||
| 
								 | 
							
								  assertz(rule_by_num(N,V,NH,HL,BL)),
							 | 
						||
| 
								 | 
							
								  assert_model(T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* retracts the model from the database
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								retract_model:-!,
							 | 
						||
| 
								 | 
							
								  retractall(rule_by_num(_,_,_,_,_)),
							 | 
						||
| 
								 | 
							
								  retractall(rule(_,_,_,_,_,_,_,_)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* returns the list of predicates specification for output atoms
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								get_ouptut_atoms(O):-
							 | 
						||
| 
								 | 
							
								  findall((A/Ar),output((A/Ar)),O).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* generates the list of goals that must be asked for computing the CLL
							 | 
						||
| 
								 | 
							
								and the grounding of an LPAD
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								generate_goal([],_H,G,G):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_goal([P/A|T],H,G0,G1):-
							 | 
						||
| 
								 | 
							
								  functor(Pred,P,A),
							 | 
						||
| 
								 | 
							
								  Pred=..[P|Rest],
							 | 
						||
| 
								 | 
							
								  Pred1=..[P,H|Rest],
							 | 
						||
| 
								 | 
							
								  findall(Pred1,call(Pred1),L),
							 | 
						||
| 
								 | 
							
								  findall(\+ Pred1,call(neg(Pred1)),LN),
							 | 
						||
| 
								 | 
							
								  append(G0,L,G2),
							 | 
						||
| 
								 | 
							
								  append(G2,LN,G3),
							 | 
						||
| 
								 | 
							
								  generate_goal(T,H,G3,G1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								generate_goal1([],_H,G,G):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_goal1([P/A|T],H,G0,G1):-
							 | 
						||
| 
								 | 
							
								  functor(Pred,P,A),
							 | 
						||
| 
								 | 
							
								  Pred=..[P|Rest],
							 | 
						||
| 
								 | 
							
								  Pred1=..[P,H|Rest],
							 | 
						||
| 
								 | 
							
								  findall(Pred1,call(Pred1),L),
							 | 
						||
| 
								 | 
							
								  findall(Pred1,call(neg(Pred1)),LN),
							 | 
						||
| 
								 | 
							
								  append(G0,L,G2),
							 | 
						||
| 
								 | 
							
								  append(G2,LN,G3),
							 | 
						||
| 
								 | 
							
								  generate_goal1(T,H,G3,G1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								sum(_NS,[],[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								sum(NS,[H0|T0],[H1|T1],[H2|T2]):-
							 | 
						||
| 
								 | 
							
								  H2 is H0+H1*NS,
							 | 
						||
| 
								 | 
							
								  sum(NS,T0,T1,T2).  
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								times(_NS,[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								times(NS,[H0|T0],[H1|T1]):-
							 | 
						||
| 
								 | 
							
								  H1 is H0*NS,
							 | 
						||
| 
								 | 
							
								  times(NS,T0,T1).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								divide(_NS,[],[]):-!.  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								divide(NS,[H0|T0],[H1|T1]):-
							 | 
						||
| 
								 | 
							
								  H1 is H0/NS,
							 | 
						||
| 
								 | 
							
								  divide(NS,T0,T1).  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* End of computation of log likelihood and sufficient stats */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* Utility predicates */
							 | 
						||
| 
								 | 
							
								set(Parameter,Value):-
							 | 
						||
| 
								 | 
							
								  retract(setting(Parameter,_)),
							 | 
						||
| 
								 | 
							
								  assert(setting(Parameter,Value)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_file_names(File,FileKB,FileOut,FileL,FileLPAD,FileBG):-
							 | 
						||
| 
								 | 
							
								  generate_file_name(File,".kb",FileKB),
							 | 
						||
| 
								 | 
							
								  generate_file_name(File,".rules",FileOut),
							 | 
						||
| 
								 | 
							
								  generate_file_name(File,".cpl",FileLPAD),
							 | 
						||
| 
								 | 
							
								  generate_file_name(File,".l",FileL),
							 | 
						||
| 
								 | 
							
								  generate_file_name(File,".bg",FileBG).        
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_file_name(File,Ext,FileExt):-
							 | 
						||
| 
								 | 
							
								  name(File,FileString),
							 | 
						||
| 
								 | 
							
								  append(FileString,Ext,FileStringExt),
							 | 
						||
| 
								 | 
							
								  name(FileExt,FileStringExt).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								load_initial_model(File,Model):-
							 | 
						||
| 
								 | 
							
								  open(File,read,S),
							 | 
						||
| 
								 | 
							
								  read_clauses1(S,C),
							 | 
						||
| 
								 | 
							
								  close(S),
							 | 
						||
| 
								 | 
							
								  process_clauses(C,0,_N,[],Model).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_clauses([(end_of_file,[])],N,N,Model,Model).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_clauses([((H:-B),V)|T],N,N2,Model0,[rule(N,V,NH,HL,BL,0)|Model1]):-
							 | 
						||
| 
								 | 
							
								  H=(_;_),!,
							 | 
						||
| 
								 | 
							
								  list2or(HL1,H),
							 | 
						||
| 
								 | 
							
								  process_head(HL1,HL,VI),
							 | 
						||
| 
								 | 
							
								  list2and(BL0,B),
							 | 
						||
| 
								 | 
							
								  add_int_atom(BL0,BL,VI),
							 | 
						||
| 
								 | 
							
								  length(HL,LH),
							 | 
						||
| 
								 | 
							
								  listN(0,LH,NH),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V,NH,HL,BL)),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_clauses([((H:-B),V)|T],N,N2,Model0,[rule(N,V,NH,HL,BL,0)|Model1]):-
							 | 
						||
| 
								 | 
							
								  H=(_:_),!,
							 | 
						||
| 
								 | 
							
								  list2or(HL1,H),
							 | 
						||
| 
								 | 
							
								  process_head(HL1,HL,VI),
							 | 
						||
| 
								 | 
							
								  list2and(BL0,B),
							 | 
						||
| 
								 | 
							
								  add_int_atom(BL0,BL,VI),
							 | 
						||
| 
								 | 
							
								  length(HL,LH),
							 | 
						||
| 
								 | 
							
								  listN(0,LH,NH),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V1,NH,HL,BL)),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								process_clauses([((H:-B),V)|T],N,N2,Model0,[def_rule(N,V,H1,BL)|Model1]):-!,
							 | 
						||
| 
								 | 
							
								  list2and(BL0,B),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								  add_int_atom([H|BL0],[H1|BL],_VI),
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V1,NH,HL,BL)),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_clauses([(H,V)|T],N,N2,Model0,[rule(N,V,NH,HL,[],0)|Model1]):-
							 | 
						||
| 
								 | 
							
								  H=(_;_),!,
							 | 
						||
| 
								 | 
							
								  list2or(HL1,H),
							 | 
						||
| 
								 | 
							
								  process_head(HL1,HL,_VI),
							 | 
						||
| 
								 | 
							
								  length(HL,LH),
							 | 
						||
| 
								 | 
							
								  listN(0,LH,NH),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V,NH,HL,[])),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_clauses([(H,V)|T],N,N2,Model0,[rule(N,V,NH,HL,[],0)|Model1]):-
							 | 
						||
| 
								 | 
							
								  H=(_:_),!,
							 | 
						||
| 
								 | 
							
								  list2or(HL1,H),
							 | 
						||
| 
								 | 
							
								  process_head(HL1,HL,_VI),
							 | 
						||
| 
								 | 
							
								  length(HL,LH),
							 | 
						||
| 
								 | 
							
								  listN(0,LH,NH),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V,NH,HL,[])),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								process_clauses([(H,V)|T],N,N2,Model0,[def_rule(N,V,H1,[])|Model1]):-
							 | 
						||
| 
								 | 
							
								  add_int_atom([H],[H1],_VI),
							 | 
						||
| 
								 | 
							
								  N1 is N+1,
							 | 
						||
| 
								 | 
							
								%  assertz(rule(N,V,NH,HL,[])),
							 | 
						||
| 
								 | 
							
								  process_clauses(T,N1,N2,Model0,Model1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* if the annotation in the head are not ground, the null atom is not added
							 | 
						||
| 
								 | 
							
								and the eventual formulas are not evaluated */
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								process_head([H:P|T],NHL,VI):-!,
							 | 
						||
| 
								 | 
							
								    process_head_prob([H:P|T],0.0,NHL,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_head(HL,NHL,VI):-
							 | 
						||
| 
								 | 
							
								    process_head_random(HL,0.0,NHL,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_head_random([],P,['':PNull1],_VI):-
							 | 
						||
| 
								 | 
							
								  PNull is 1.0-P,
							 | 
						||
| 
								 | 
							
								  (PNull>=0.0->
							 | 
						||
| 
								 | 
							
								    PNull1 =PNull
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    PNull1=0.0
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								process_head_random([H|T],P,[H1:PH1|NT],VI):-
							 | 
						||
| 
								 | 
							
								  add_int_atom([H],[H1],VI),
							 | 
						||
| 
								 | 
							
								  PMax is 1.0-P,
							 | 
						||
| 
								 | 
							
								  random(0,PMax,PH1),
							 | 
						||
| 
								 | 
							
								  P1 is P+PH1,  
							 | 
						||
| 
								 | 
							
								  process_head_random(T,P1,NT,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								process_head_prob([H:PH],P,[H1:PH1],VI):-
							 | 
						||
| 
								 | 
							
								  add_int_atom([H],[H1],VI),
							 | 
						||
| 
								 | 
							
								  PH1 is PH,
							 | 
						||
| 
								 | 
							
								  PNull is 1.0-P-PH1,
							 | 
						||
| 
								 | 
							
								  PNull<1e-10,!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								process_head_prob([H:PH],P,[H1:PH1,'':PNull],VI):-
							 | 
						||
| 
								 | 
							
								  add_int_atom([H],[H1],VI),
							 | 
						||
| 
								 | 
							
								  PH1 is PH,
							 | 
						||
| 
								 | 
							
								  PNull is 1.0-P-PH1.
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								process_head_prob([H:PH|T],P,[H1:PH1|NT],VI):-
							 | 
						||
| 
								 | 
							
								  add_int_atom([H],[H1],VI),
							 | 
						||
| 
								 | 
							
								  PH1 is PH,
							 | 
						||
| 
								 | 
							
								  P1 is P+PH1,
							 | 
						||
| 
								 | 
							
								  process_head_prob(T,P1,NT,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_int_atom([],[],_VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_int_atom([H|T],[H|T1],VI):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(H),!,
							 | 
						||
| 
								 | 
							
								  add_int_atom(T,T1,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_int_atom([\+ H|T],[\+ H1|T1],VI):-!,
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[F,VI|Args],
							 | 
						||
| 
								 | 
							
								  add_int_atom(T,T1,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								add_int_atom([H|T],[H1|T1],VI):-
							 | 
						||
| 
								 | 
							
								  H=..[F|Args],
							 | 
						||
| 
								 | 
							
								  H1=..[F,VI|Args],
							 | 
						||
| 
								 | 
							
								  add_int_atom(T,T1,VI).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* predicates for reading in the program clauses */
							 | 
						||
| 
								 | 
							
								read_clauses1(S,Clauses):-
							 | 
						||
| 
								 | 
							
								    read_clauses_ground_body1(S,Clauses).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								read_clauses_ground_body1(S,[(Cl,V)|Out]):-
							 | 
						||
| 
								 | 
							
								  read_term(S,Cl,[variable_names(V)]),
							 | 
						||
| 
								 | 
							
								  (Cl=end_of_file->
							 | 
						||
| 
								 | 
							
								    Out=[]
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    read_clauses_ground_body1(S,Out)
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								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,BL)),
							 | 
						||
| 
								 | 
							
								  Pos1 is Pos+1,
							 | 
						||
| 
								 | 
							
								  assert_rules(T,Pos1,HL,BL,NH,N,V1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								listN(N,N,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								listN(NIn,N,[NIn|T]):-
							 | 
						||
| 
								 | 
							
								  N1 is NIn+1,
							 | 
						||
| 
								 | 
							
								  listN(N1,N,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list0(N,N,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list0(NIn,N,[0|T]):-
							 | 
						||
| 
								 | 
							
								  N1 is NIn+1,
							 | 
						||
| 
								 | 
							
								  list0(N1,N,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list1(N,N,[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list1(NIn,N,[1|T]):-
							 | 
						||
| 
								 | 
							
								  N1 is NIn+1,
							 | 
						||
| 
								 | 
							
								  list1(N1,N,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* end of predicates for parsing an input file containing a program */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								load_models(File):-
							 | 
						||
| 
								 | 
							
								    open(File,read,Stream),
							 | 
						||
| 
								 | 
							
								    read_models(Stream,0,Ex),
							 | 
						||
| 
								 | 
							
								    retractall(ex(_)),
							 | 
						||
| 
								 | 
							
								    assert(ex(Ex)),
							 | 
						||
| 
								 | 
							
								    close(Stream).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								read_models(Stream,N,NEx):-
							 | 
						||
| 
								 | 
							
								    read(Stream,begin(model(_Name))),!,
							 | 
						||
| 
								 | 
							
								    %format("Model ~p Y ~d~n",[Name,N]),
							 | 
						||
| 
								 | 
							
								    read_all_atoms(Stream,N),
							 | 
						||
| 
								 | 
							
								    N1 is N+1,
							 | 
						||
| 
								 | 
							
								    read_models(Stream,N1,NEx).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								read_models(_S,N,N).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								read_all_atoms(Stream,Name):-
							 | 
						||
| 
								 | 
							
								      read(Stream,At),
							 | 
						||
| 
								 | 
							
								      (At \=end(model(_Name))->
							 | 
						||
| 
								 | 
							
								        (At=neg(Atom)->    
							 | 
						||
| 
								 | 
							
								      Atom=..[Pred|Args],
							 | 
						||
| 
								 | 
							
								          Atom1=..[Pred,Name|Args],
							 | 
						||
| 
								 | 
							
								          assertz(neg(Atom1))
							 | 
						||
| 
								 | 
							
								        ;
							 | 
						||
| 
								 | 
							
								          At=..[Pred|Args],
							 | 
						||
| 
								 | 
							
								          Atom1=..[Pred,Name|Args],
							 | 
						||
| 
								 | 
							
								          assertz(Atom1)
							 | 
						||
| 
								 | 
							
								    ),
							 | 
						||
| 
								 | 
							
								        read_all_atoms(Stream,Name)
							 | 
						||
| 
								 | 
							
								;
							 | 
						||
| 
								 | 
							
								    true
							 | 
						||
| 
								 | 
							
								  ).    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2or([],true):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2or([X],X):-
							 | 
						||
| 
								 | 
							
								    X\=;(_,_),!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2or([H|T],(H ; Ta)):-!,
							 | 
						||
| 
								 | 
							
								    list2or(T,Ta).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2and([],true):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2and([X],X):-
							 | 
						||
| 
								 | 
							
								    X\=(_,_),!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								list2and([H|T],(H,Ta)):-!,
							 | 
						||
| 
								 | 
							
								    list2and(T,Ta).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								lgamma1(A,B):-
							 | 
						||
| 
								 | 
							
								  (A>=1.0->
							 | 
						||
| 
								 | 
							
								    lgamma(A,B)
							 | 
						||
| 
								 | 
							
								  ;
							 | 
						||
| 
								 | 
							
								    B=0.0
							 | 
						||
| 
								 | 
							
								  ).
							 | 
						||
| 
								 | 
							
								write_model([],_Stream):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_model([def_rule(_N,_S,H,[])|Rest],Stream):-!,
							 | 
						||
| 
								 | 
							
								  copy_term(H,H1),
							 | 
						||
| 
								 | 
							
								    numbervars(H1,0,_M),
							 | 
						||
| 
								 | 
							
								    remove_int_atom(H1,H2),
							 | 
						||
| 
								 | 
							
								    format(Stream,"~p.~n~n",[H2]),
							 | 
						||
| 
								 | 
							
								    write_model(Rest,Stream).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_model([def_rule(_N,_S,H,BL)|Rest],Stream):-!,
							 | 
						||
| 
								 | 
							
								  copy_term((H,BL),(H1,BL1)),
							 | 
						||
| 
								 | 
							
								    numbervars((H1,BL1),0,_M),
							 | 
						||
| 
								 | 
							
								  remove_int_atom(H1,H2),
							 | 
						||
| 
								 | 
							
								    format(Stream,"~p :- ~n",[H2]),
							 | 
						||
| 
								 | 
							
								    write_body(Stream,BL1),
							 | 
						||
| 
								 | 
							
								    format(Stream,".~n~n",[]),
							 | 
						||
| 
								 | 
							
								    write_model(Rest,Stream).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_model([rule(_N,_V,_NH,HL,BL,_LogF)|Rest],Stream):-
							 | 
						||
| 
								 | 
							
								  copy_term((HL,BL),(HL1,BL1)),
							 | 
						||
| 
								 | 
							
								    numbervars((HL1,BL1),0,_M),
							 | 
						||
| 
								 | 
							
								    write_disj_clause(Stream,(HL1:-BL1)),
							 | 
						||
| 
								 | 
							
								    format(Stream,".~n~n",[]),
							 | 
						||
| 
								 | 
							
								    write_model(Rest,Stream).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_disj_clause(S,(H:-[])):-!,
							 | 
						||
| 
								 | 
							
								  write_head(S,H).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								write_disj_clause(S,(H:-B)):-
							 | 
						||
| 
								 | 
							
								  write_head(S,H),
							 | 
						||
| 
								 | 
							
								  write(S,' :-'),
							 | 
						||
| 
								 | 
							
								  nl(S),
							 | 
						||
| 
								 | 
							
								  write_body(S,B).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								write_head(S,[A:1.0|_Rest]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"~p",[A1]).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								write_head(S,[A:P,'':_P]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"~p:~f",[A1,P]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_head(S,[A:P]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"~p:~f",[A1,P]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_head(S,[A:P|Rest]):-
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"~p:~f ; ",[A1,P]),
							 | 
						||
| 
								 | 
							
								    write_head(S,Rest).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[\+ A]):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(A),!,
							 | 
						||
| 
								 | 
							
								    format(S,"\t\\+ ~p",[A]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[\+ A]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"\t\\+ ~p",[A1]).
							 | 
						||
| 
								 | 
							
								 
							 | 
						||
| 
								 | 
							
								write_body(S,[A]):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(A),!,
							 | 
						||
| 
								 | 
							
								    format(S,"\t~p",[A]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[A]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"\t~p",[A1]).
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								write_body(S,[\+ A|T]):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(A),!,
							 | 
						||
| 
								 | 
							
								    format(S,"\t\\+ ~p,~n",[A]),
							 | 
						||
| 
								 | 
							
								    write_body(S,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[\+ A|T]):-!,
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"\t\\+ ~p,~n",[A1]),
							 | 
						||
| 
								 | 
							
								    write_body(S,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[A|T]):-
							 | 
						||
| 
								 | 
							
								  inference_ib:builtin(A),!,
							 | 
						||
| 
								 | 
							
								    format(S,"\t~p,~n",[A]),
							 | 
						||
| 
								 | 
							
								    write_body(S,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								write_body(S,[A|T]):-
							 | 
						||
| 
								 | 
							
								  remove_int_atom(A,A1),
							 | 
						||
| 
								 | 
							
								    format(S,"\t~p,~n",[A1]),
							 | 
						||
| 
								 | 
							
								    write_body(S,T).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								remove_int_atom(A,A1):-
							 | 
						||
| 
								 | 
							
								  A=..[F,_|T],
							 | 
						||
| 
								 | 
							
								  A1=..[F|T].
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_ground_lpad([],[]):-!.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_ground_lpad([d(R,S)|T],[d(R,S,Head,Body)|T1]):-!,
							 | 
						||
| 
								 | 
							
								  %write(g),
							 | 
						||
| 
								 | 
							
								  user:def_rule_by_num(R,S,Head,Body),
							 | 
						||
| 
								 | 
							
								  build_ground_lpad(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								build_ground_lpad([(R,S)|T],[(R,S,Head,Body)|T1]):-
							 | 
						||
| 
								 | 
							
								  %write(g),
							 | 
						||
| 
								 | 
							
								  user:rule_by_num(R,S,_,Head,Body),
							 | 
						||
| 
								 | 
							
								  build_ground_lpad(T,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								remove_head([],[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								remove_head([(_N,R,S)|T],[(R,S)|T1]):-
							 | 
						||
| 
								 | 
							
								  remove_head(T,T1).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								generate_nth_pos(I, I, [Head|_], Head):-!.
							 | 
						||
| 
								 | 
							
								generate_nth_pos(I, IN, [_|List], El) :-
							 | 
						||
| 
								 | 
							
								  I1 is I+1,
							 | 
						||
| 
								 | 
							
								  generate_nth_pos(I1, IN, List, El).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								my_get_value(K,V):-
							 | 
						||
| 
								 | 
							
								  recorded(K,V,_R).
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								my_set_value(K,V):-
							 | 
						||
| 
								 | 
							
								  eraseall(K),
							 | 
						||
| 
								 | 
							
								  recorda(K,V,_R).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_matching([],_El,[]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_matching([El|T],El,T1):-!,
							 | 
						||
| 
								 | 
							
								        delete_matching(T,El,T1).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_matching([H|T],El,[H|T1]):-
							 | 
						||
| 
								 | 
							
								        delete_matching(T,El,T1).
							 | 
						||
| 
								 | 
							
								
							 |