slipcover

This module performs learning over Logic Programs with Annotated Disjunctions and CP-Logic programs. It performs both parameter and structure learning.

See https://github.com/friguzzi/cplint/blob/master/doc/manual.pdf or http://ds.ing.unife.it/~friguzzi/software/cplint-swi/manual.html for details.

author
- Fabrizio Riguzzi, Elena Bellodi
license
- Artistic License 2.0
   16/*
   17
   18SLIPCOVER
   19
   20Copyright (c) 2016, Fabrizio Riguzzi and Elena Bellodi
   21
   22*/
   23:-module(liftcover,[set_lift/2,setting_lift/2,
   24  induce_lift/2,induce_par_lift/2,test_lift/7,
   25  filter_rules/2,filter_rules/3,sort_rules/2,
   26  remove_zero/2,
   27  op(500,fx,#),op(500,fx,'-#'),
   28  test_prob_lift/6,
   29  prob_lift/2,prob_lift/3,
   30  explain_lift/2,explain_lift/3,
   31  ranked_answers/3,
   32  ranked_answers/4,
   33  rank/3,
   34  rank_answer/3,
   35  rank_answer/4,
   36  hits_at_k/6,
   37  hits_at_k/7,
   38  rank_ex/3,
   39  rank_exs/4,
   40  inst_exs/4,
   41  induce_par_kg/2,
   42  induce_par_pos_kg/2,
   43  compute_stats_kg/2,
   44  compute_stats_pos_kg/2,
   45  compute_par_kg/3,
   46  write_rules_kg/1,
   47  write_rules_kg/2,
   48  write_rules_anyburl/2,
   49  read_rules_anyburl/2
   50  ]).   51:-use_module(library(auc)).   52:-use_module(library(lists)).   53:-use_module(library(random)).   54:-use_module(library(system)).   55:-use_module(library(terms)).   56:-use_module(library(ordsets)).   57:-use_module(library(apply)).   58:-use_module(library(settings)).   59:-use_module(library(clpfd), [transpose/2]).   60
   61:-use_module(library(dcg/basics)).   62:-absolute_file_name(library(lbfgs),F,[solutions(all)]),atomic_concat(F,'.pl',Fpl),exists_file(Fpl),use_module(library(lbfgs));true.   63%:-use_foreign_library(foreign(bddem),install).
   64:-set_prolog_flag(unknown,warning).   65
   66%:-multifile setting_lift/2.
   67%:-use_module(library(sandbox)).
   68
   69
   70:- dynamic lift_input_mod/1.   71
   72
   73:- thread_local v/3, lift_input_mod/1, local_setting/2, rule_lift_n/1.   74
   75:- meta_predicate induce_lift(:,-).   76:- meta_predicate induce_rules(:,-).   77:- meta_predicate induce_par_lift(:,-).   78:- meta_predicate induce_parameters(:,-).   79
   80
   81
   82:- meta_predicate test_lift(:,+,-,-,-,-,-).   83:- meta_predicate test_prob_lift(:,+,-,-,-,-).   84:- meta_predicate prob_lift(:,-).   85:- meta_predicate prob_lift(:,+,-).   86:- meta_predicate explain_lift(:,-).   87:- meta_predicate explain_lift(:,+,-).   88:- meta_predicate ranked_answers(:,-,-).   89:- meta_predicate ranked_answers(:,-,+,-).   90:- meta_predicate rank_answer(:,+,-).   91:- meta_predicate rank_answer(:,+,+,-).   92:- meta_predicate hits_at_k(:,+,+,+,-,-).   93:- meta_predicate hits_at_k(:,+,+,+,+,-,-).   94:- meta_predicate rank_ex(:,+,+).   95:- meta_predicate rank_exs(:,+,+,+).   96:- meta_predicate inst_exs(:,+,+,+).   97:- meta_predicate set_lift(:,+).   98:- meta_predicate setting_lift(:,-).   99:- meta_predicate filter_rules(:,-).  100
  101:- meta_predicate induce_par_kg(:,-).  102:- meta_predicate induce_par_pos_kg(:,-).  103:- meta_predicate compute_stats_kg(:,+).  104:- meta_predicate compute_stats_pos_kg(:,+).  105:- meta_predicate compute_par_kg(:,+,-).  106
  107
  108
  109:- setting(max_threads, integer, 256,
  110    'Maximum number of threads to use in scoring clause refinements and parameter learning').  111:- setting(allow_gpu, boolean, true,
  112    'Whether the use of GPU is allowed').  113
  114
  115
  116default_setting_lift(eps,0.0001).
  117default_setting_lift(eps_f,0.00001).
  118
  119
  120default_setting_lift(random_restarts_number,1). % number of random restarts of parameter learning
  121default_setting_lift(random_restarts_number_str_learn,1). % number of random restarts during structure learning of parameter learning for single clauses
  122default_setting_lift(iter,100).
  123default_setting_lift(d,1).
  124default_setting_lift(verbosity,1).
  125default_setting_lift(logzero,log(0.000001)).
  126default_setting_lift(megaex_bottom,1).
  127default_setting_lift(initial_clauses_per_megaex,1).
  128default_setting_lift(max_iter,10).
  129default_setting_lift(max_var,4).
  130default_setting_lift(maxdepth_var,2).
  131default_setting_lift(beamsize,100).
  132default_setting_lift(max_clauses,1000).
  133default_setting_lift(max_body_length,100).
  134default_setting_lift(neg_literals,false).
  135
  136default_setting_lift(specialization,bottom).
  137/* allowed values: mode,bottom */
  138
  139default_setting_lift(seed,rand(10,1231,3032)).
  140default_setting_lift(neg_ex,cw).
  141
  142
  143default_setting_lift(epsilon_parsing, 1e-5).
  144
  145
  146
  147
  148default_setting_lift(zero,0.000001).
  149default_setting_lift(minus_infinity,-1.0e20).
  150
  151default_setting_lift(regularization,l1). % regularization: no, l1, l2, bayesian 
  152default_setting_lift(gamma,10). % set the value of gamma for regularization l1 and l2
  153default_setting_lift(ab,[0,10]). % set the value of a and b for regularization baysian
  154default_setting_lift(min_probability,1e-5).  % Threshold of the probability under which the clause is dropped
  155default_setting_lift(parameter_learning,em). % parameter learning algorithm: em_python, em, lbfgs, gd_python, gd 
  156default_setting_lift(max_initial_weight,0.5). % initial weights of dphil in [-0.5 0.5]
  157
  158default_setting_lift(parameter_update,fixed_learning_rate). % values: fixed_learning_rate,adam
  159default_setting_lift(eta,0.01). % fixed learning rate
  160default_setting_lift(adam_params,[0.001,0.9,0.999,1e-8]). % default Adam hyper-pameters
  161default_setting_lift(processor,cpu). % where to run em_python and gd_python: cpu or gpu
  162default_setting_lift(threads,1). % number of threads to use in scoring clause refinements and parameter learning
  163default_setting_lift(single_var,false). %false:1 variable for every grounding of a rule; true: 1 variable for rule (even if a rule has more groundings),simpler.
 induce_lift(:TrainFolds:list_of_atoms, -P:probabilistic_program) is det
The predicate performs structure learning using the folds indicated in TrainFolds for training. It returns in P the learned probabilistic program. /
  173induce_lift(TrainFolds,P):-
  174  induce_rules(TrainFolds,P0),
  175  rules2terms(P0,P).
 test_lift(:P:probabilistic_program, +TestFolds:list_of_atoms, -LL:float, -AUCROC:float, -ROC:dict, -AUCPR:float, -PR:dict) is det
The predicate takes as input in P a probabilistic program, tests P on the folds indicated in TestFolds and returns the log likelihood of the test examples in LL, the area under the Receiver Operating Characteristic curve in AUCROC, a dict containing the points of the ROC curve in ROC, the area under the Precision Recall curve in AUCPR and a dict containing the points of the PR curve in PR /
  186test_lift(P,TestFolds,LL,AUCROC,ROC,AUCPR,PR):-
  187  test_prob_lift(P,TestFolds,_NPos,_NNeg,LL,LG),
  188  compute_areas_diagrams(LG,AUCROC,ROC,AUCPR,PR).
 test_prob_lift(:P:probabilistic_program, +TestFolds:list_of_atoms, -NPos:int, -NNeg:int, -LL:float, -Results:list) is det
The predicate takes as input in P a probabilistic program, tests P on the folds indicated in TestFolds and returns the number of positive examples in NPos, the number of negative examples in NNeg, the log likelihood in LL and in Results a list containing the probabilistic result for each query contained in TestFolds. /
  199test_prob_lift(M:P,TestFolds,NPos,NNeg,CLL,Results) :-
  200  write2(M,'Testing\n'),
  201  make_dynamic(M),
  202  process_clauses(P,M,PRules),
  203  generate_clauses(PRules,M,0,Prog),
  204  (M:bg(RBG0)->
  205    process_clauses(RBG0,M,RBG),
  206    generate_clauses_bg(RBG,ClBG),
  207    assert_all(ClBG,M,ClBGRef)
  208  ;
  209    true
  210  ),
  211  findall(Exs,(member(F,TestFolds),M:fold(F,Exs)),L),
  212  append(L,DB),
  213  test_no_area(DB,M,Prog,NPos,NNeg,CLL,Results),
  214  (M:bg(RBG0)->
  215    retract_all(ClBGRef)
  216  ;
  217    true
  218  ).
  219
  220induce_rules(M:Folds,R):-
  221  load_python_module(M),
  222  make_dynamic(M),
  223  M:local_setting(seed,Seed),
  224  setrand(Seed),
  225  findall(Exs,(member(F,Folds),M:fold(F,Exs)),L),
  226  append(L,DB),
  227  (M:bg(RBG0)->
  228    process_clauses(RBG0,M,RBG),
  229    generate_clauses_bg(RBG,ClBG),
  230    assert_all(ClBG,M,ClBGRef)
  231  ;
  232    true
  233  ),
  234  find_ex(DB,M,Pos,Neg,NPos,_Neg),
  235  M:local_setting(megaex_bottom, NumMB),
  236  (NPos >= NumMB ->
  237      true
  238    ;
  239      format2(M,"~nWARN: Number of required bottom clauses is greater than the number of training examples!~n. The number of required bottom clauses will be equal to the number of training examples", []),
  240      M:set_lift(megaex_bottom, NPos)
  241  ),
  242  statistics(walltime,[_,_]),
  243  (M:local_setting(specialization,bottom)->
  244    M:local_setting(megaex_bottom,MB),
  245    deduct(MB,M,DB,[],InitialTheory),
  246    remove_duplicates(InitialTheory,R1)
  247  ;
  248    get_head_atoms(O,M),
  249    generate_top_cl(O,M,R1)
  250  ),
  251  learn_struct(Pos,Neg,M,R1,R2,Score),
  252  sort_rules_int(R2,R),
  253  statistics(walltime,[_,WT]),
  254  WTS is WT/1000,
  255  write2(M,'\n\n'),
  256  format2(M,'/* Final score ~f~n',[Score]),
  257  format2(M,'Wall time ~f */~n',[WTS]),
  258  write_rules2(M,R,user_output),
  259  (M:bg(RBG0)->
  260    retract_all(ClBGRef)
  261  ;
  262    true
  263  ),
  264  retractall(M:ref_clause(_)),
  265  retractall(M:ref(_)).
 sort_rules(+RulesIn:list_of_rules, -RulesOut:list_of_rules) is det
The predicate sorts RulesIn according to the probability of the rules /
  272sort_rules(R0,R):-
  273  rules2terms(P0,R0),
  274  sort_rules_int(P0,P),
  275  rules2terms(P,R).
  276
  277sort_rules_int(P0,P):-
  278  maplist(to_pair,P0,P1),
  279  sort(1,@>=,P1,P2),
  280  maplist(to_pair,P,P2).
  281
  282to_pair(rule(N,[H:P|R],BL,Lit),P-rule(N,[H:P|R],BL,Lit)).
  283
  284
  285make_dynamic(M):-
  286  M:(dynamic int/1),
  287  findall(O,M:output(O),LO),
  288  findall(I,M:input(I),LI),
  289  findall(I,M:input_cw(I),LIC),
  290  findall(D,M:determination(D,_DD),LDH),
  291  findall(DD,M:determination(_D,DD),LDD),
  292  findall(DH,(M:modeh(_,_,_,LD),member(DH,LD)),LDDH),
  293  append([LO,LI,LIC,LDH,LDD,LDDH],L0),
  294  remove_duplicates(L0,L),
  295  maplist(to_dyn(M),L).
  296
  297to_dyn(M,P/A):-
  298  A1 is A+1,
  299  M:(dynamic P/A1),
  300  A2 is A1+1,
  301  M:(dynamic P/A2).
  302
  303
  304
  305learn_struct(Pos,Neg,Mod,Beam,R,Score):-  %+Beam:initial theory of the form [rule(NR,[h],[b]],...], -R:final theory of the same form, -CLL
  306  format2(Mod,"Clause search~n~n",[]),
  307  Mod:local_setting(max_iter,M),
  308  Mod:local_setting(beamsize,BS),
  309  Mod:local_setting(max_clauses,MC),
  310  cycle_beam(Beam,Mod,Pos,Neg,[],CL,0,M,BS,MC),
  311  maplist(get_cl,CL,LC,MIC,MINC),
  312  maplist(append,MIC,MIC1),
  313  transpose(MIC1,MI),
  314  append(MINC,MIN),
  315  length(LC,NumCL),
  316  write2(Mod,"Final parameter learning"),nl2(Mod),
  317  Mod:local_setting(random_restarts_number,RR),
  318  learn_param_int(MI,MIN,NumCL,Mod,RR,Par,Score),
  319  update_theory(LC,Par,Program1),
  320  remove_zero(Program1,R),
  321  format2(Mod,"Best target theory~n~n",[]),
  322  write_rules2(Mod,R,user_output).
  323
  324get_cl(c(_,C,[MI,MIN]),C,MI,MIN).
  325
  326pick_first(0,_,[]):-!.
  327
  328pick_first(_,[],[]):-!.
  329
  330pick_first(N,[(H,_S)|T],[H|T1]):-
  331  N1 is N-1,
  332  pick_first(N1,T,T1).
  333
  334remove_score([],[]).
  335
  336remove_score([(H,_S)|T],[H|T1]):-
  337  remove_score(T,T1).
  338
  339init_gd_par(0,_Max,[]):-!.
  340
  341init_gd_par(I,Max,[W|TW]):-
  342  I1 is I-1,
  343  W is -Max+random_float*2*Max,
  344  init_gd_par(I1,Max,TW).
  345
  346init_par(_Env,0):-!.
  347
  348init_par(Env,I):-
  349  I1 is I-1,
  350  optimizer_set_x(Env,I1,0.5),
  351  init_par(Env,I1).
  352
  353evaluate_L(Env,M,MIP,MI,L):-
  354  compute_likelihood_pos(MIP,Env,M,0,0,LP),
  355  compute_likelihood_neg(MI,Env,M,LN),
  356  compute_likelihood(LN,M,LP,L).
  357  
  358gen_initial_counts(0,[]):-!.
  359
  360gen_initial_counts(N0,[0|MIP0]):-
  361  N1 is N0-1,
  362  gen_initial_counts(N1,MIP0).
  363
  364evaluate(Env,L,_N,_Step,[M,MIP,MI]):-
  365%  M:mip(MIP),
  366%  M:mi(MI),
  367  compute_likelihood_pos(MIP,Env,M,0,0,LP),
  368  compute_likelihood_neg(MI,Env,M,LN),
  369  compute_likelihood(LN,M,LP,L),
  370  compute_grad(MIP,Env,M,0,MI,LN).
  371
  372compute_grad([],_Env,_M,_N,_MI,_LN):-!.
  373
  374compute_grad([HMIP|TMIP],Env,M,N0,MI,LN):-
  375  compute_sum_neg(MI,M,LN,N0,0,S),
  376  optimizer_get_x(Env,N0,P0),
  377  M:local_setting(zero,Zero),
  378  (P0=<0 ->
  379    PI=Zero
  380  ;
  381    (P0>=1.0->
  382       PI is 1.0-Zero
  383     ;
  384       PI=P0
  385     )
  386  ),
  387
  388 (PI=:= 1.0->
  389    G is 1.0/Zero
  390  ;
  391    G is (HMIP-S)/(1.0-PI)
  392  ),
  393  optimizer_set_g(Env,N0,G),
  394  N1 is N0+1,
  395  compute_grad(TMIP,Env,M,N1,MI,LN).
  396
  397compute_sum_neg([],_M,_LN,_I,S,S).
  398
  399compute_sum_neg([HMI|TMI],M,[HLN|TLN],I,S0,S):-
  400  nth0(I,HMI,MIR),
  401  Den is 1.0-exp(-HLN),
  402  M:local_setting(zero,Zero),
  403  (Den=<0.0->
  404    Den1 is Zero
  405  ;
  406    Den1 = Den
  407  ),
  408  S1 is S0+MIR*exp(-HLN)/Den1,
  409  compute_sum_neg(TMI,M,TLN,I,S1,S).
  410
  411compute_likelihood([],_M,L,L).
  412
  413compute_likelihood([HP|TP],M,L0,L):-
  414  A is 1.0-exp(-HP),
  415  M:local_setting(zero,Zero),
  416  (A=<0.0->
  417    A1 is Zero
  418  ;
  419    A1=A
  420  ),
  421  L1 is L0-log(A1),
  422  compute_likelihood(TP,M,L1,L).
  423
  424compute_likelihood_neg([],_Env,_M,[]).
  425
  426compute_likelihood_neg([HMI|TMI],Env,M,[HLN|TLN]):-
  427  compute_likelihood_pos(HMI,Env,M,0,0,HLN),
  428  compute_likelihood_neg(TMI,Env,M,TLN).
  429
  430compute_likelihood_pos([],_Env,_M,_,LP,LP).
  431
  432compute_likelihood_pos([HMIP|TMIP],Env,M,I,LP0,LP):-
  433  optimizer_get_x(Env,I,P0),
  434  M:local_setting(zero,Zero),
  435  (P0=<0.0 ->
  436    P=Zero
  437  ;
  438    (P0>=1.0->
  439       P is 1-Zero
  440     ;
  441       P=P0
  442     )
  443  ),
  444  LP1 is LP0-log(1-P)*HMIP,
  445  I1 is I+1,
  446  compute_likelihood_pos(TMIP,Env,M,I1,LP1,LP).
  447
  448progress(_Env,FX,X_Norm,G_Norm,Step,_N,Iteration,Ls,0,[M|_]) :-
  449  format4(M,'~d. Iteration :  f(X)=~4f  |X|=~4f
  450                |g(X)|=~4f  Step=~4f  Ls=~4f~n',
  451                [Iteration,FX,X_Norm,G_Norm,Step,Ls]).
  452
  453gen_par(NC,NC,[]):-!.
  454
  455gen_par(N0,NC,[[N0,[0.5,0.5]]|T]):-
  456  N1 is N0+1,
  457  gen_par(N1,NC,T).
  458
  459
  460logistic(X,Sigma_X):-
  461  Sigma_X is 1/(1+exp(-X)).
  462
  463
  464load_python_module(M):-
  465  M:local_setting(parameter_learning,PL),
  466  (PL=em_python;PL=gd_python; PL=em_torch),!,
  467  absolute_file_name(library('liftcover.pl'), F),
  468  file_directory_name(F,Dir),
  469  py_add_lib_dir(Dir),
  470  processor(M,Proc),
  471  M:local_setting(verbosity,Verb),
  472  py_call(liftcover:init(PL,Proc,Verb)).
  473
  474load_python_module(_).
  475
  476processor(M,Proc):-
  477  M:local_setting(processor,Proc0),
  478  (setting(allow_gpu,true)->
  479    Proc=Proc0
  480  ;
  481    Proc = cpu
  482  ).
 induce_par_lift(:TrainFolds:list_of_atoms, -P:probabilistic_program) is det
The predicate learns the parameters of the program stored in the in/1 fact of the input file using the folds indicated in TrainFolds for training. It returns in P the input program with the updated parameters. /
  491induce_par_lift(Folds,ROut):-
  492  induce_parameters(Folds,R),
  493  rules2terms(R,ROut).
  494
  495induce_parameters(M:Folds,R):-
  496  load_python_module(M),
  497  make_dynamic(M),
  498  M:local_setting(seed,Seed),
  499  setrand(Seed),
  500  findall(Exs,(member(F,Folds),M:fold(F,Exs)),L),
  501  append(L,DB),
  502  statistics(walltime,[_,_]),
  503  (M:bg(RBG0)->
  504    process_clauses(RBG0,M,RBG),
  505    generate_clauses_bg(RBG,ClBG),
  506    assert_all(ClBG,M,ClBGRef)
  507  ;
  508    true
  509  ),
  510  M:in(R00),
  511  process_clauses(R00,M,R0),
  512  statistics(walltime,[_,_]),
  513  find_ex(DB,M,Pos,Neg,_NPos,_NNeg),
  514  M:local_setting(random_restarts_number_str_learn,RR),
  515  number_of_threads(M,Th),
  516  learn_param(R0,M,Pos,Neg,RR,Th,R1,Score,_MI,_MIN),
  517  sort_rules_int(R1,R),
  518  statistics(walltime,[_,CT]),
  519  CTS is CT/1000,
  520  format2(M,'/* Final score ~f~n',[Score]),
  521  format2(M,'Wall time ~f */~n',[CTS]),
  522  write_rules2(M,R,user_output),
  523  (M:bg(RBG0)->
  524    retract_all(ClBGRef)
  525  ;
  526    true
  527  ).
 induce_par_kg(:P:probabilistic_program, -P1:probabilistic_program) is det
The predicate learns the parameters of the program stored in the in/1 fact of the input file using the folds indicated in TrainFolds for training. It returns in P the input program with the updated parameters. /
  537induce_par_kg(M:R,R1):-
  538  load_python_module(M),
  539  setof(Rel,(H,T)^(M:t(H,Rel,T)),Rels),
  540  assert(M:rules(R)),
  541  maplist(partition_rules(M),Rels),
  542  retract(M:rules(R)),
  543  (parallel(M)->
  544    concurrent_maplist(compute_statistics_kg(M),Rels,MI,MIN)
  545  ;
  546    maplist(compute_statistics_kg(M),Rels,MI,MIN)
  547  ),
  548  maplist(induce_parameters_kg(M),Rels,MI,MIN,Par0),
  549  append(Par0,Par),
  550  retractall(M:rules(_,_)),
  551  maplist(update_rule,R,Par,R1).
  552
  553induce_par_pos_kg(M:R,R1):-
  554  load_python_module(M),
  555  setof(Rel,(H,T)^(M:t(H,Rel,T)),Rels),
  556  assert(M:rules(R)),
  557  maplist(partition_rules(M),Rels),
  558  retract(M:rules(R)),
  559  (parallel(M)->
  560    concurrent_maplist(compute_statistics_pos_kg(M),Rels,MI,MIN)
  561  ;
  562    maplist(compute_statistics_pos_kg(M),Rels,MI,MIN)
  563  ),
  564  maplist(induce_parameters_kg(M),Rels,MI,MIN,Par0),
  565  append(Par0,Par),
  566  retractall(M:rules(_,_)),
  567  maplist(update_rule,R,Par,R1).
  568
  569compute_stats_kg(M:R,File):-
  570  setof(Rel,(H,T)^(M:t(H,Rel,T)),Rels),
  571  assert(M:rules(R)),
  572  maplist(partition_rules(M),Rels),
  573  retract(M:rules(R)),
  574  (parallel(M)->
  575    concurrent_maplist(compute_statistics_kg(M),Rels,MI,MIN)
  576  ;
  577    maplist(compute_statistics_kg(M),Rels,MI,MIN)
  578  ),
  579  retractall(M:rules(_,_)),
  580  open(File,write,S),
  581  writeln(S,m(MI,MIN)),writeln(S,'.'),
  582  close(S).
  583
  584compute_stats_pos_kg(M:R,File):-
  585  setof(Rel,(H,T)^(M:t(H,Rel,T)),Rels),
  586  assert(M:rules(R)),
  587  maplist(partition_rules(M),Rels),
  588  retract(M:rules(R)),
  589  (parallel(M)->
  590    concurrent_maplist(compute_statistics_pos_kg(M),Rels,MI,MIN)
  591  ;
  592    maplist(compute_statistics_pos_kg(M),Rels,MI,MIN)
  593  ),
  594  retractall(M:rules(_,_)),
  595  open(File,write,S),
  596  writeln(S,m(MI,MIN)),writeln(S,'.'),
  597  close(S).
  598
  599compute_par_kg(M:R,FileStat,R1):-
  600  load_python_module(M),
  601  open(FileStat,read,S),
  602  read_term(S,m(MI,MIN),[]),
  603  close(S),
  604  setof(Rel,(H,T)^(M:t(H,Rel,T)),Rels),
  605  maplist(induce_parameters_kg(M),Rels,MI,MIN,Par0),
  606  append(Par0,Par),
  607  maplist(update_rule,R,Par,R1).
  608
  609parallel(M):-
  610  number_of_threads(M,Th),
  611  Th>1.
  612  
  613induce_parameters_kg(M,Rel,MI,MIN,Par):-
  614  format4(M,'Tuning parameters for relation ~w~n',[Rel]),
  615  M:local_setting(random_restarts_number,RR),
  616  length(MI,N),
  617  learn_param_int(MI,MIN,N,M,RR,Par,_LL).
  618
  619
  620partition_rules(M,Rel):-
  621  M:rules(R),
  622  findall(R1,(member(R1,R),R1=(tt(_,Rel,_): _ :- _)),RRel),
  623  assert(M:rules(Rel,RRel)).
  624
  625compute_statistics_kg(M,Rel,MI,MIN):-
  626  M:rules(Rel,R),
  627  length(R,N),
  628  format4(M,'Computing clause statistics for relation ~q, ~d clauses~n',[Rel,N]),
  629  find_ex_kg(Rel,M,Pos,Neg),
  630  length(Pos,NPos),
  631  length(Neg,NNeg),
  632  format4(M,'Pos ex ~d neg ex ~d~n',[NPos,NNeg]),
  633  clauses_statistics_kg(R,M,Rel,Pos,Neg,MI,MIN).
  634
  635compute_statistics_pos_kg(M,Rel,MI,MIN):-
  636  M:rules(Rel,R),
  637  length(R,N),
  638  format4(M,'Computing clause statistics for relation ~q, ~d clauses~n',[Rel,N]),
  639  find_pos_ex_kg(Rel,M,Pos),
  640  length(Pos,NPos),
  641  format4(M,'Pos ex ~d neg ex ~d~n',[NPos,0]),
  642  clauses_statistics_kg(R,M,Rel,Pos,[],MI,MIN).
  643
  644number_of_threads(M,Th):-
  645  M:local_setting(threads,Th0),
  646  current_prolog_flag(cpu_count,Cores),
  647  ((Th0=cpu;Th0>Cores)->
  648    Th1 = Cores
  649  ;
  650    Th1 = Th0
  651  ),
  652  setting(max_threads,ThMax),
  653  Th is min(Th1,ThMax).
  654
  655
  656update_rule((H:_ :- B),P,(H:P :- B)).
  657
  658find_ex_kg(Rel,M,Pos,Neg):-
  659  find_pos_ex_kg(Rel,M,Pos),
  660  findall(tt(S,Rel,T),(M:t(S,Rel1,T),Rel1 \= Rel,\+ M:t(S,Rel,T)),Neg).
  661
  662find_pos_ex_kg(Rel,M,Pos):-
  663  findall(tt(S,Rel,T),M:t(S,Rel,T),Pos).
 filter_rules(:RulesIn:list_of_rules, -RulesOut:list_of_rules) is det
The predicate removes the rules with a probability below or equal to the min_prob parmeter. /
  671filter_rules(M:R0,R):-
  672  M:local_setting(min_probability,Min_prob),
  673  filter_rules(R0,R,Min_prob).
 filter_rules(+RulesIn:list_of_rules, -RulesOut:list_of_rules, +Min_prob:float) is det
The predicate removes from the rules with a probability below or equal to Min_prob. /
  681filter_rules(R0,R,Min_prob):-
  682  (R0=[(_ :- _)|_]->
  683    rules2terms(R0At,R0),
  684    remove_clauses(R0At,Min_prob,RAt,_Num),
  685    rules2terms(RAt,R)
  686  ;
  687    remove_clauses(R0,Min_prob,R,_Num)  
  688  ).
 remove_zero(+RulesIn:list_of_rules, -RulesOut:list_of_rules) is det
The predicate removes the rules with a probability of 0.0. /
  695remove_zero(R0,R1):-
  696  filter_rules(R0,R1,0.0).
  697
  698
  699remove_clauses(Rules,Prob,RulesOut,Num):-
  700  remove_clauses_loop(Rules,Prob,0,Num,[],RulesOut).
  701
  702remove_clauses_loop([],_,Num,Num,Rules,Rules).
  703remove_clauses_loop([Rule|Rest],Prob,NumCur,Num,RulesCur,RulesOut):-
  704  Rule=rule(_N,[_Head:Par|_],_,_),
  705  Par =< Prob,!,
  706  NumCur1 is NumCur+1,
  707  remove_clauses_loop(Rest, Prob, NumCur1,Num,RulesCur, RulesOut).
  708
  709remove_clauses_loop([Rule|Rest],Prob,NumCur,Num,RulesCur,[Rule|RulesOut]):-
  710  remove_clauses_loop(Rest, Prob, NumCur,Num,RulesCur, RulesOut).
  711
  712
  713test_theory_neg_prob(Ex,M,Theory,MIP0,MIP):-
  714  (M:local_setting(single_var,false)->
  715    test_clause_prob(Theory,M,Ex,MIP0,MIP)
  716  ;
  717    test_clause_prob_sv(Theory,M,Ex,MIP0,MIP)
  718  ).
  719
  720test_clause_prob([],_M,_Exs,MIP,MIP).
  721
  722test_clause_prob([(H,B,V,_P)|Rest],M,Exs,[MIPH0|MIPT0],[MIPH|MIPT]):-
  723  maplist(test_ex(V,H,B,M),Exs,L),
  724  sum_list(L,MIP),
  725  MIPH is MIPH0+MIP,
  726  test_clause_prob(Rest,M,Exs,MIPT0,MIPT).
  727
  728test_ex(_V,H,B,M,E,N):-
  729  findall(1,(H=E,M:B),L),
  730  length(L,N).
  731
  732test_clause_prob_sv([],_M,_Exs,MIP,MIP).
  733
  734test_clause_prob_sv([(H,B,V,_P)|Rest],M,Exs,[MIPH0|MIPT0],[MIPH|MIPT]):-
  735  maplist(test_ex_sv(V,H,B,M),Exs,L),
  736  sum_list(L,MIP),
  737  MIPH is MIPH0+MIP,
  738  test_clause_prob_sv(Rest,M,Exs,MIPT0,MIPT).
  739
  740
  741test_ex_sv(_V,H,B,M,E,N):-
  742  (\+ (H=E,M:B)->
  743    N=0
  744  ;
  745    N=1
  746  ).  
  747
  748test_theory_pos_prob(Ex,M,Th,N,LMI):-
  749  (M:local_setting(single_var,false)->
  750    test_theory_pos_prob_mv(Ex,M,Th,N,LMI)
  751  ;
  752    test_theory_pos_prob_sv(Ex,M,Th,N,LMI)
  753  ).
  754
  755test_theory_pos_prob_mv([],_M,_Theory,_N,[]).
  756
  757test_theory_pos_prob_mv([Ex|Rest],M,Th,N,[MI|LMI]):-
  758  gen_initial_counts(N,MI0),
  759  test_clause_prob(Th,M,[Ex],MI0,MI),
  760  test_theory_pos_prob_mv(Rest,M,Th,N,LMI).
  761
  762test_theory_pos_prob_sv([],_M,_Theory,_N,[]).
  763
  764test_theory_pos_prob_sv([Ex|Rest],M,Th,N,[MI|LMI]):-
  765  gen_initial_counts(N,MI0),
  766  test_clause_prob_sv(Th,M,[Ex],MI0,MI),
  767  test_theory_pos_prob_sv(Rest,M,Th,N,LMI).
  768
  769
  770
  771test_theory_pos_kg(M,Rel,(H:_ :-B),MI):-
  772  M:pos(Rel,Ex),
  773  maplist(check_rule(H,B,M),Ex,MI).
  774
  775
  776check_rule(H1,B1,M,Ex,Cov):-
  777  copy_term((H1,B1),(H,B)),
  778  term_variables(B,Vars),
  779  ((H=Ex,M:B,oi(Vars))->
  780    Cov=1
  781  ;
  782    Cov=0
  783  ).
  784
  785test_theory_neg_kg(M,Rel,(H:_ :-B),MIN):-
  786  M:neg(Rel,Ex),
  787  foldl(update_min(H,B,M),Ex,0,MIN).
  788
  789update_min(H1,B1,M,Ex,MIN0,MIN):-
  790  copy_term((H1,B1),(H,B)),
  791  term_variables(B,Vars),
  792  ((H=Ex,M:B,oi(Vars))->
  793    MIN is MIN0+1
  794  ;
  795    MIN=MIN0
  796  ).
  797
  798oi(Vars):-
  799  sort(Vars,VarsOI),
  800  length(VarsOI,LOI),
  801  length(Vars,L),
  802  L=LOI.
  803
  804
  805
  806
  807learn_param([],M,_,_,_,_,[],MInf,[],[]):-!,
  808  M:local_setting(minus_infinity,MInf).
  809
  810learn_param(Program0,M,Pos,Neg,RR,Th,Program,LL,MI,MIN):-
  811  generate_clauses(Program0,M,0,Pr1),
  812  length(Program0,N),
  813  format4(M,'Computing clause statistics~n',[]),
  814  gen_initial_counts(N,MIN0),
  815  clauses_statistics(Pr1,N,M,Pos,Neg,MIN0,MI,MIN,Th),
  816  format4(M,'Updating parameters~n',[]),
  817  learn_param_int(MI,MIN,N,M,RR,Par,LL),
  818  update_theory(Program0,Par,Program1),
  819  remove_zero(Program1,Program).
  820
  821
  822clauses_statistics(Pr,N,M,Pos,Neg,MIN0,MI,MIN,Th):-
  823  (Th=1->
  824    test_theory_neg_prob(Neg,M,Pr,MIN0,MIN),
  825    test_theory_pos_prob(Pos,M,Pr,N,MI)
  826  ;
  827    current_prolog_flag(cpu_count,Cores),
  828    ((Th=cpu;Th>Cores)->
  829      Chunks = Cores
  830    ;
  831      Chunks = Th
  832    ),
  833    chunks(Pos,Chunks,PosC),
  834    chunks(Neg,Chunks,NegC),
  835    concurrent_maplist(test_theory_neg_prob_conc(Pr,M,MIN0),NegC,MINC),
  836    concurrent_maplist(test_theory_pos_prob_conc(Pr,M,N),PosC,MIC),
  837    append(MIC,MI),
  838    transpose(MINC,MINT),
  839    maplist(sum_list,MINT,MIN)
  840  ).
  841
  842test_theory_neg_prob_conc(Pr,M,MIN0,Neg,MIN):-
  843  test_theory_neg_prob(Neg,M,Pr,MIN0,MIN).
  844
  845test_theory_pos_prob_conc(Pr,M,N,Pos,MI):-
  846  test_theory_pos_prob(Pos,M,Pr,N,MI).
  847
  848
  849clauses_statistics_kg(Pr,M,Rel,Pos,Neg,MI,MIN):-
  850  assert(M:pos(Rel,Pos)),
  851  assert(M:neg(Rel,Neg)),
  852  maplist(test_theory_neg_kg(M,Rel),Pr,MIN),
  853  maplist(test_theory_pos_kg(M,Rel),Pr,MIT),
  854  transpose(MIT,MI),
  855  retract(M:pos(Rel,Pos)),
  856  retract(M:neg(Rel,Neg)).
  857
  858chunks(L,N,Chunks):-
  859  length(L,Len),
  860  LenChunks is round(Len/N),
  861  split_list(L,N,LenChunks,Chunks).
  862
  863split_list(L,1,_,[L]):-!.
  864
  865split_list(L0,N,NL,[H|L]):-
  866  N>1,
  867  N1 is N-1,
  868  length(H1,NL),
  869  (append(H1,T,L0)->
  870    H=H1,
  871    split_list(T,N1,NL,L)
  872  ;
  873    H=L0,
  874    L=[]
  875  ).
  876
  877learn_param_int(MI,MIN,_N,M,NR,Par,LL):-
  878  M:local_setting(parameter_learning,em_torch),!,
  879  M:local_setting(eps,EA),
  880  M:local_setting(eps_f,ER),
  881  M:local_setting(iter,Iter),
  882  M:local_setting(regularization,Reg),
  883  M:local_setting(gamma,Gamma),
  884  M:local_setting(zero,Zero),
  885  M:local_setting(ab,[A,B]),
  886  M:local_setting(verbosity,Verb),
  887  processor(M,Device),
  888  py_call(liftcover:random_restarts_torch(MI,MIN,Device,NR,Iter,EA,ER,Reg,Zero,Gamma,A,B,Verb),-(Par,LL)),
  889  format3(M,"Final LL ~f~n",[LL]).
  890
  891
  892learn_param_int(MI,MIN,N,M,NR,Par,LL):-
  893  M:local_setting(parameter_learning,em),!,
  894  random_restarts(0,NR,M,-1e20,LL,N,initial,Par,MI,MIN),
  895  format3(M,"Final LL ~f~n",[LL]).
  896
  897learn_param_int(MI,MIN,_N,M,NR,Par,LL):-
  898  M:local_setting(parameter_learning,em_python),!,
  899  M:local_setting(eps,EA),
  900  M:local_setting(eps_f,ER),
  901  M:local_setting(iter,Iter),
  902  M:local_setting(regularization,Reg),
  903  M:local_setting(gamma,Gamma),
  904  M:local_setting(zero,Zero),
  905  M:local_setting(ab,[A,B]),
  906  M:local_setting(verbosity,Verb),
  907  processor(M,Device),
  908  py_call(liftcover:random_restarts(MI,MIN,Device,NR,Iter,EA,ER,Reg,Zero,Gamma,A,B,Verb),-(Par,LL)),
  909  format3(M,"Final LL ~f~n",[LL]).
  910
  911learn_param_int(MI,MIN,N,M,NR,Par,LL):-
  912  M:local_setting(parameter_learning,gd),!,
  913  random_restarts_gd(0,NR,M,-1e20,PLL,N,initial,ParR,MI,MIN),  %computes new parameters Par
  914  maplist(logistic,ParR,Par),
  915  LL is -PLL,
  916  format3(M,"Final LL ~f~n",[LL]).
  917
  918
  919learn_param_int(MI,MIN,_N,M,NR,Par,LL):-
  920  M:local_setting(parameter_learning,gd_python),!,
  921  M:local_setting(verbosity,Verb),
  922  M:local_setting(parameter_update,UpdateMethod),
  923  M:local_setting(iter,Iter),
  924  M:local_setting(eps,Eps),
  925  M:local_setting(adam_params,[Eta,Beta1,Beta2,Epsilon]),
  926  M:local_setting(eta,LearningRate),
  927  M:local_setting(gamma,Gamma),
  928  M:local_setting(regularization,Reg),
  929  M:local_setting(zero,Zero),
  930  processor(M,Device),
  931  py_call(liftcover:random_restarts_gd(MI,MIN,Device,NR,UpdateMethod,
  932    Iter,Eps,Reg,Gamma,LearningRate,Eta,-(Beta1,Beta2),Epsilon,Zero,Verb),-(Par,LL)),
  933  format3(M,"Final LL ~f~n",[LL]).
  934
  935
  936learn_param_int(MI,MIN,N,M,_,Par,LL):-
  937  M:local_setting(parameter_learning,lbfgs),
  938  optimizer_initialize(N,liftcover,evaluate,progress,[M,MIN,MI],Env),
  939  init_par(Env,N),
  940  evaluate_L(Env,M,MIN,MI,L),
  941% parte da modificare fine
  942  IL is -L,
  943  format4(M,"~nInitial L ~f~n",[IL]),
  944  optimizer_run(Env,_LL,Status),
  945  format4(M,"Status ~p~n",[Status]),
  946  new_pars_lbfgs(Env,M,0,N,Par),
  947  evaluate_L(Env,M,MIN,MI,NewL),
  948  LL is -NewL,
  949  optimizer_finalize(Env).
  950
  951
  952new_pars_lbfgs(_Env,_M,N,N,[]):-!.
  953
  954new_pars_lbfgs(Env,M,N,NMax,[P|Rest1]):-
  955    optimizer_get_x(Env,N,P0),
  956    M:local_setting(zero,Zero),
  957    (P0=<0.0->
  958      P=Zero
  959    ;
  960      (P0>=1.0->
  961        P is 1.0-Zero
  962      ;
  963        P=P0
  964      )
  965    ),
  966    N1 is N+1,
  967    new_pars_lbfgs(Env,M,N1,NMax,Rest1).
  968
  969
  970random_restarts(N,N,_M,Score,Score,_N,Par,Par,_MI,_MIN):-!.
  971
  972random_restarts(N,NMax,M,Score0,Score,NR,Par0,Par,MI,MIN):-
  973  N1 is N+1,
  974  format3(M,"Restart number ~d~n~n",[N1]),
  975  length(Par1,NR),
  976  maplist(random,Par1),
  977  M:local_setting(eps,EA),
  978  M:local_setting(eps_f,ER),
  979  M:local_setting(iter,Iter),
  980  em(EA,ER,0,Iter,M,NR,Par1,-1e20,MI,MIN,ParR,ScoreR),
  981  format3(M,"Random_restart: Score ~f~n",[ScoreR]),
  982  (ScoreR>Score0->
  983    random_restarts(N1,NMax,M,ScoreR,Score,NR,ParR,Par,MI,MIN)
  984  ;
  985    random_restarts(N1,NMax,M,Score0,Score,NR,Par0,Par,MI,MIN)
  986  ).
  987
  988random_restarts_gd(N,N,_M,Score,Score,_N,Par,Par,_MI,_MIN):-!.
  989
  990random_restarts_gd(N,NMax,M,_Score0,Score,NR,_Par0,Par,MI,MIN):-
  991  N1 is N+1,
  992  format3(M,"Restart number ~d~n~n",[N1]),
  993  M:local_setting(max_initial_weight,Max),
  994  init_gd_par(NR,Max,Par1),
  995  evaluate_L_gd(M,MIN,MI,Par1,L),
  996  ScoreIn is -L,
  997  format3(M,"GD Random_restart: initial score ~f~n",[ScoreIn]),
  998  M:local_setting(eps,EA),
  999  M:local_setting(eps_f,ER),
 1000  M:local_setting(iter,Iter),
 1001  (M:local_setting(parameter_update,adam)->
 1002    findall(0,between(1,NR,_),M0),
 1003    findall(0,between(1,NR,_),M1),
 1004    gd_adam(EA,ER,0,Iter,M,NR,Par1,M0,M1,-1e20,MI,MIN,ParR,ScoreR)
 1005  ;
 1006    gd(EA,ER,0,Iter,M,NR,Par1,-1e20,MI,MIN,ParR,ScoreR)
 1007  ),
 1008  format3(M,"GD Random_restart: Score ~f~n",[ScoreR]),
 1009  random_restarts_gd(N1,NMax,M,ScoreR,Score,NR,ParR,Par,MI,MIN).
 1010
 1011
 1012gd(_EA,_ER,MaxIter,MaxIter,_M,_NR,Par,Score,_MI,_MIP,Par,Score):-!.
 1013
 1014gd(EA,ER,Iter0,MaxIter,M,NR,Par0,Score0,MI,MIP,Par,Score):-
 1015  compute_gradient_gd(MIP,MI,M,Par0,G,LL),
 1016  Score1 is -LL,
 1017  Iter is Iter0+1,
 1018  format4(M,"GD Iteration ~d LL ~f~n",[Iter,Score1]),
 1019  Diff is Score1-Score0,
 1020  Fract is -Score1*ER,
 1021  (( Diff<EA;Diff<Fract)->
 1022    Score=Score1,
 1023    Par=Par0
 1024  ;
 1025    M:local_setting(eta,Eta),
 1026    M:local_setting(gamma,Gamma),
 1027    (M:local_setting(regularization,l2)->
 1028      maplist(l2,Par0,Reg)
 1029    ;
 1030      (M:local_setting(regularization,l1)->
 1031        maplist(l1,Par0,Reg)
 1032      ;
 1033        findall(0,between(1,NR,_),Reg)
 1034      )
 1035    ),
 1036    maplist(update_par(Eta,Gamma),Par0,Reg,G,Par1),
 1037    gd(EA,ER,Iter,MaxIter,M,NR,Par1,Score1,MI,MIP,Par,Score)
 1038  ).
 1039
 1040gd_adam(_EA,_ER,Iter,Iter,_M,_NR,Par,_M0,_M1,Score,_MI,_MIP,Par,Score):-!.
 1041
 1042gd_adam(EA,ER,Iter0,MaxIter,M,NR,Par0,M00,M10,Score0,MI,MIP,Par,Score):-
 1043  compute_gradient_gd(MIP,MI,M,Par0,G,LL),
 1044  Score1 is -LL,
 1045  Iter is Iter0+1,
 1046  format4(M,"Iteration ~d LL ~f~n",[Iter,Score1]),
 1047  Diff is Score1-Score0,
 1048  Fract is -Score1*ER,
 1049  (( Diff<EA;Diff<Fract)->
 1050    Score=Score1,
 1051    Par=Par0
 1052  ;
 1053    M:local_setting(gamma,Gamma),
 1054    M:local_setting(adam_params,[Eta,Beta1,Beta2,Epsilon]),
 1055    (M:local_setting(regularization,l2)->
 1056      maplist(l2,Par0,Reg)
 1057    ;
 1058      (M:local_setting(regularization,l1)->
 1059        maplist(l1,Par0,Reg)
 1060      ;
 1061        findall(0,between(1,NR,_),Reg)
 1062      )
 1063    ),
 1064    maplist(update_grad(Gamma),G,Reg,G1),
 1065    maplist(update_M0(Beta1),M00,G1,M0),
 1066    maplist(update_M1(Beta2),M10,G1,M1),
 1067    EtaIter is Eta*sqrt(1-Beta2^Iter)/(1-Beta1^Iter),
 1068    maplist(update_par_adam(EtaIter,Epsilon),Par0,M0,M1,Par1),
 1069    gd_adam(EA,ER,Iter,MaxIter,M,NR,Par1,M0,M1,Score1,MI,MIP,Par,Score)
 1070  ).
 1071
 1072update_par_adam(EtaIter,Epsilon,Par0,M0,M1,Par1):-
 1073  Par1 is Par0-EtaIter*M0/(sqrt(M1)+Epsilon).
 1074
 1075
 1076update_M0(Beta1,M00,G,M0):-
 1077  M0 is Beta1*M00+(1-Beta1)*G.
 1078
 1079update_M1(Beta2,M10,G,M1):-
 1080  M1 is Beta2*M10+(1-Beta2)*G^2.
 1081
 1082update_grad(Gamma,G,Reg,G1):-
 1083  G1 is G+Gamma*Reg.
 1084
 1085
 1086l1(W,R):-
 1087  logistic(W,S),
 1088  R is S*(1-S).
 1089
 1090l2(W,R):-
 1091  logistic(W,S),
 1092  R is 2*S^2*(1-S).
 1093
 1094update_par(Eta,Gamma,Par0,Reg,G,Par1):-
 1095  Par1 is Par0-Eta*(G+Gamma*Reg).
 1096
 1097
 1098
 1099evaluate_L_gd(M,MIP,MI,Par,L):-
 1100  maplist(logistic,Par,Prob),
 1101  compute_likelihood_pos_gd(MIP,Prob,M,0,LP),
 1102%  write(lpos),nl,
 1103  compute_likelihood_neg_gd(MI,Prob,M,LN),
 1104%  write(lneg),nl,
 1105  compute_likelihood_gd(LN,M,LP,L).
 1106
 1107
 1108
 1109compute_gradient_gd(MIP,MI,M,Par,G,L):-
 1110  maplist(logistic,Par,Prob),
 1111  compute_likelihood_pos_gd(MIP,Prob,M,0,LP),
 1112  compute_likelihood_neg_gd(MI,Prob,M,LN),
 1113  compute_likelihood_gd(LN,M,LP,L),
 1114  compute_grad_gd(MIP,Prob,M,0,MI,LN,G).
 1115%  write(grad),nl.
 1116
 1117compute_likelihood_neg_gd([],_Prob,_M,[]).
 1118
 1119compute_likelihood_neg_gd([HMI|TMI],Prob,M,[HLN|TLN]):-
 1120  compute_likelihood_pos_gd(HMI,Prob,M,0,HLN),
 1121  compute_likelihood_neg_gd(TMI,Prob,M,TLN).
 1122
 1123compute_likelihood_pos_gd([],[],_M,LP,LP).
 1124
 1125compute_likelihood_pos_gd([HMIP|TMIP],[P|TP],M,LP0,LP):-
 1126  LP1 is LP0-log(1-P)*HMIP,
 1127  compute_likelihood_pos_gd(TMIP,TP,M,LP1,LP).
 1128
 1129
 1130compute_likelihood_gd([],_M,L,L).
 1131
 1132compute_likelihood_gd([HP|TP],M,L0,L):-
 1133  A is 1.0-exp(-HP),
 1134  (A=:=0.0->
 1135    M:local_setting(logzero,LZ),
 1136    L1 is L0-LZ
 1137  ;
 1138    L1 is L0-log(A)
 1139  ),
 1140  compute_likelihood_gd(TP,M,L1,L).
 1141
 1142
 1143compute_grad_gd([],[],_M,_N,_MI,_LN,[]):-!.
 1144
 1145compute_grad_gd([HMIP|TMIP],[P|TP],M,N0,MI,LN,[G|TG]):-
 1146%  write(prima_comp_grad),nl,
 1147  compute_sum_neg(MI,M,LN,N0,0,S),
 1148%  write(opt),nl,
 1149  G is (HMIP-S)*P,
 1150  N1 is N0+1,
 1151  compute_grad_gd(TMIP,TP,M,N1,MI,LN,TG).
 1152
 1153compute_sum_neg_gd([],_M,_LN,_I,S,S).
 1154
 1155compute_sum_neg_gd([HMI|TMI],M,[HLN|TLN],I,S0,S):-
 1156%  write(HMI),write(hmi),nl,
 1157%  write(I),write('I'),nl,
 1158  nth0(I,HMI,MIR),
 1159%  write(MIR),write(mir),nl,
 1160%  write(HLN),write(hln),nl,
 1161  Den is 1.0-exp(-HLN),
 1162  S1 is S0+MIR*exp(-HLN)/Den,
 1163  compute_sum_neg_gd(TMI,M,TLN,I,S1,S).
 1164
 1165
 1166em(_EA,_ER,MaxIter,MaxIter,_M,_NR,Par,Score,_MI,_MIN,Par,Score):-!.
 1167
 1168em(EA,ER,Iter0,MaxIter,M,NR,Par0,Score0,MI,MIN,Par,Score):-
 1169  length(Eta0,NR),
 1170  expectation_quick(Par0,M,MI,MIN,Eta0,Eta,Score1),
 1171  Iter is Iter0+1,
 1172  format4(M,"Iteration ~d LL ~f~n",[Iter,Score1]),
 1173  maximization_quick(Eta,M,Par1),
 1174  Diff is Score1-Score0,
 1175  Fract is -Score1*ER,
 1176  (( Diff<EA;Diff<Fract)->
 1177    Score=Score1,
 1178    Par=Par1
 1179  ;
 1180    em(EA,ER,Iter,MaxIter,M,NR,Par1,Score1,MI,MIN,Par,Score)
 1181  ).
 1182
 1183expectation_quick(Par,M,MI,MIN,Eta0,Eta,Score):-
 1184 /* LLO is the negative examples contribution in the LL*/
 1185  M:local_setting(logzero,LogZero),
 1186  foldl(llm(LogZero),Par,MIN,0,LL0),
 1187  maplist(eta0,MIN,Eta0),
 1188  /* positive examples contibution in LL*/
 1189  scan_pos(MI,M,Par,LL0,Eta0,Score,Eta).
 1190
 1191maximization_quick(Eta,M,Par):-
 1192  (M:local_setting(regularization,l1)->
 1193    maplist(maximize_L1(M),Eta,Par)
 1194  ;
 1195    (M:local_setting(regularization,l2)->
 1196      maplist(maximize_L2(M),Eta,Par)
 1197  ;
 1198      (M:local_setting(regularization,bayesian)->
 1199        maplist(maximize_bayesian(M),Eta,Par)
 1200      ;
 1201        maplist(maximize(M),Eta,Par)
 1202  )
 1203    )
 1204  ).
 1205
 1206maximize(_M,[Eta0,Eta1],Par):-
 1207  (Eta0+Eta1=:=0.0->
 1208    Par=0.0
 1209  ;
 1210    Par is Eta1/(Eta0+Eta1)  
 1211  ).
 1212
 1213
 1214maximize_L1(M,[Eta0,Eta1],Par):-
 1215  M:local_setting(gamma,Gamma),
 1216/*(((Eta0+Eta1)^2+Gamma^2+2*Gamma*(Eta0-Eta1))<0 ->
 1217writeln((Eta0+Eta1)^2+Gamma^2+2*Gamma*(Eta0-Eta1)),
 1218  Par is 4*Eta1/(2*(Gamma+Eta0+Eta1))
 1219;((2*(Gamma+Eta0+Eta1+sqrt((Eta0+Eta1)^2+Gamma^2+2*Gamma*(Eta0-Eta1)))=:=0.0)->
 1220writeln((2*(Gamma+Eta0+Eta1+sqrt((Eta0+Eta1)^2+Gamma^2+2*Gamma*(Eta0-Eta1)))))
 1221
 1222;*/
 1223  Par is 4*Eta1/(2*(Gamma+Eta0+Eta1+sqrt((Eta0+Eta1)^2+Gamma^2+2*Gamma*(Eta0-Eta1))))
 1224%)
 1225  %)
 1226  .
 1227
 1228maximize_L2(M,[Eta0,Eta1],Par):-
 1229  M:local_setting(gamma,Gamma),
 1230  Sum is 3*Eta0+3*Eta1+Gamma,
 1231  Arccos is acos(sqrt(Gamma/Sum)*(9*Eta0/2-9*Eta1+Gamma)/(3*Eta0+3*Eta1+Gamma)),
 1232  Par is 2*sqrt(Sum/Gamma)*cos(Arccos/3-2*pi/3)/3+1/3.
 1233
 1234maximize_bayesian(M,[Eta0,Eta1],Par):-
 1235  M:local_setting(ab,[A,B]),
 1236  Par is (Eta1+A)/(Eta0+Eta1+A+B).
 1237
 1238/*....scan_pos predicate..... */
 1239
 1240scan_pos([],_M,_Par,LL,Eta,LL,Eta).
 1241
 1242scan_pos([MIH|MIT],M,Par,LL0,Eta0,LL,Eta):-
 1243  M:local_setting(logzero,LogZero),
 1244  foldl(rule_contrib,MIH,Par,1,Prod),
 1245  ProbEx is 1-Prod,
 1246  (ProbEx=:=0.0->
 1247    LLCurrent is LL0+LogZero
 1248   ;
 1249    LLCurrent is LL0+log(ProbEx)
 1250  ),
 1251  maplist(update_eta(ProbEx,M),Eta0,Par,MIH,EtaCurrent),
 1252  scan_pos(MIT,M,Par,LLCurrent,EtaCurrent,LL,Eta).
 1253
 1254
 1255update_eta(ProbEx,M,[Etai00,Etai10],Pi,MIR,[Etai0,Etai1]):-
 1256  M:local_setting(zero,Zero),
 1257  ( ProbEx=:=0.0->
 1258    CondP is Pi/Zero
 1259  ;
 1260    CondP is Pi/ProbEx
 1261  ),
 1262  OCondP0 is 1-CondP,
 1263  ( OCondP0 <0.0->
 1264    OCondP = 0.0
 1265  ;
 1266    OCondP = OCondP0
 1267  ),
 1268  Etai0 is Etai00+MIR*OCondP,
 1269  Etai1 is Etai10+MIR*CondP.
 1270
 1271rule_contrib(MIR,Pi,P0,P):-
 1272  P is P0*(1-Pi)^MIR.
 1273
 1274llm(LogZero,Pi,MI,LL0,LL):-
 1275  ((1-Pi)=:=0.0 ->
 1276
 1277    ( MI==0 ->
 1278      LL is LL0
 1279     ;
 1280       LL is LL0+MI*LogZero
 1281    )
 1282   ;
 1283    ( MI==0 ->
 1284       LL is LL0
 1285     ;
 1286       LL is LL0+MI*log(1-Pi)
 1287    )
 1288
 1289  ).
 1290
 1291eta0(MIN,[MIN,0]).
 1292
 1293
 1294update_theory([],_N,[]):-!.
 1295
 1296update_theory([rule(Name,[H:_,_],B,L)|Rest],[P|T],[rule(Name,[H:P,'':PN],B,L)|Rest1]):-
 1297    PN is 1-P,
 1298    update_theory(Rest,T,Rest1).
 1299
 1300
 1301
 1302cycle_beam([],_Mod,_Pos,_Neg,CL,CL,_M0,_M,_BS,_MC):-!.
 1303
 1304cycle_beam(_Beam,_Mod,_Pos,_Neg,CL,CL,M,M,_BS,_MC):-!.
 1305
 1306cycle_beam(Beam,Mod,Pos,Neg,CL0,CL,M0,M,BS,MC):-
 1307  M1 is M0+1,%decreases the number of max_iter M
 1308  format2(Mod,"Clause iteration ~d~n~n",[M1]),
 1309  /*write('\n\ncurrent beam\n\n'),
 1310  write(Beam),
 1311  write('\n\n'),*/
 1312  cycle_clauses(Beam,Mod,Pos,Neg,[],NB0,CL0,CL1),
 1313  (length(NB,BS),append(NB,_,NB0)->
 1314    true
 1315  ;
 1316   NB=NB0 
 1317  ),
 1318  (MC=:= inf ->
 1319    CL2=CL1
 1320  ;
 1321    (length(CL2,MC),append(CL2,_,CL1)->
 1322      true
 1323    ;
 1324      CL2=CL1
 1325    )
 1326  ),
 1327  cycle_beam(NB,Mod,Pos,Neg,CL2,CL,M1,M,BS,MC).
 1328
 1329cycle_clauses([],_M,_Pos,_Neg,NB,NB,CL,CL):-!.
 1330
 1331cycle_clauses([c(_ScoreH,RH,_)|T],M,Pos,Neg,NB0,NB,CL0,CL):-
 1332%  write3('\n\nRevising clause\n'),
 1333%  write_rules3([RH],user_output),
 1334%  RH=rule(_,H,B,Lits),
 1335%  write3(H),write3(' '),write3(B),
 1336%  write3('\n'),write3(Lits),write3('\n'),
 1337  findall(RS,specialize_rule(RH,M,RS,_L),LR),!,   %-LR:list of lists, each one correponding to a different revised theory; specialize_rule defined in revise.pl
 1338  length(LR,NR),
 1339  write3(M,'Number of revisions '),write3(M,NR),write3(M,'\n'),
 1340  score_clause_refinements(LR,M,Pos,Neg,NB0,NB1,CL0,CL1),
 1341  cycle_clauses(T,M,Pos,Neg,NB1,NB,CL1,CL).
 1342
 1343
 1344score_clause_refinements(LR,M,Pos,Neg,NB0,NB,CL0,CL):-  %scans the list of revised theories
 1345  number_of_threads(M,Th),
 1346  (Th=1->
 1347     score_clause_refinements_int(M,1,Pos,Neg,LR,NB1,CL1),
 1348     list_to_ord_set(NB1,NB1OS),
 1349     ord_union(NB1OS,NB0,NB),
 1350     list_to_ord_set(CL1,CL1OS),
 1351     ord_union(CL1OS,CL0,CL)
 1352  ;
 1353    chunks(LR,Th,LRC),
 1354    concurrent_maplist(score_clause_refinements_int(M,1,Pos,Neg),LRC,NBs,CLs),
 1355    merge_ordsets(NBs,NB0,NB),
 1356    merge_ordsets(CLs,CL0,CL)
 1357  ).
 1358
 1359merge_ordsets([],OS,OS).
 1360
 1361merge_ordsets([H|T],OS0,OS):-
 1362  list_to_ord_set(H,HOS),
 1363  ord_union(HOS,OS0,OS1),
 1364  merge_ordsets(T,OS1,OS).
 1365
 1366
 1367score_clause_refinements_int(_M,_N,_Pos,_Neg,[],[],[]):-!.
 1368
 1369score_clause_refinements_int(M,Nrev,Pos,Neg,[R1|T],[c(Score,R3,_)|NB],CL):-  %scans the list of revised theories
 1370  already_scored_clause(R1,R3,M,Score),!,
 1371  format3(M,'Score ref.  ~d~n',[Nrev]),
 1372  write3(M,'Already scored, updated refinement\n'),
 1373  write_rules3(M,[R3],user_output),
 1374  write3(M,'Score '),write3(M,Score),write3(M,'\n\n\n'),
 1375  Nrev1 is Nrev+1,
 1376  score_clause_refinements_int(M,Nrev1,Pos,Neg,T,NB,CL).
 1377
 1378score_clause_refinements_int(M,Nrev,Pos,Neg,[R1|T],NB,CL):-
 1379  format3(M,'Score ref.  ~d~n',[Nrev]),
 1380  write_rules3(M,[R1],user_output),
 1381  M:local_setting(random_restarts_number_str_learn,NR),
 1382  learn_param([R1],M,Pos,Neg,NR,1,NewR,Score,MI,MIN),
 1383  write3(M,'Updated refinement\n'),
 1384  write_rules3(M,NewR,user_output),
 1385  write3(M,'Score (CLL) '),write3(M,Score),write3(M,'\n\n\n'),
 1386  (NewR=[R3]->
 1387    NB=[c(Score,R3,_)|NB0],
 1388    (range_restricted(R3)->
 1389      CL=[c(Score,R3,[MI,MIN])|CL0]
 1390    ;
 1391      CL=CL0
 1392    ),
 1393    format2(M,"Added a target clause~n",[]),
 1394    store_clause_refinement(R1,R3,M,Score),
 1395    Nrev1 is Nrev+1
 1396  ;
 1397    NB=NB0,
 1398    CL=CL0,
 1399    Nrev1=Nrev+1
 1400  ),
 1401  score_clause_refinements_int(M,Nrev1,Pos,Neg,T,NB0,CL0).
 1402
 1403range_restricted(rule(_N,HL,BL,_Lit)):-
 1404  term_variables(HL,VH),
 1405  term_variables(BL,VB),
 1406  sublisteq(VH,VB).
 1407
 1408sublisteq([],_).
 1409
 1410sublisteq([H|T],L):-
 1411  member_eq(H,L),
 1412  sublisteq(T,L).
 1413
 1414target(R,M):-
 1415  get_output_preds(R,O),
 1416  member(T,O),
 1417  M:output(T),!.
 1418
 1419get_output_preds(rule(_N,HL,_BL,_Lit),O):-
 1420  scan_head(HL,[],O).
 1421
 1422scan_head(['':_],O,O):-!.
 1423scan_head([],O,O):-!.
 1424scan_head([H:_P|T],O0,O):-
 1425  functor(H,F,N),
 1426  (member(F/N,O0)->
 1427    O1=O0
 1428  ;
 1429    O1=[F/N|O0]
 1430  ),
 1431  scan_head(T,O1,O).
 1432
 1433
 1434store_clause_refinement(Ref,RefP,M,Score):-
 1435  elab_clause_ref(Ref,Ref1),
 1436  assert(M:ref_clause(r(Ref1,RefP,Score))).
 1437
 1438store_refinement(Ref,RefP,M,Score):-
 1439  elab_ref(Ref,Ref1),
 1440  assert(M:ref(r(Ref1,RefP,Score))).
 1441
 1442already_scored_clause(R,R1,M,Score):-
 1443  elab_ref([R],[rule(H,B)]),
 1444  M:ref_clause(r(rule(H,B1),R1,Score)),
 1445  permutation(B,B1).
 1446
 1447already_scored(R,R1,M,Score):-
 1448  elab_ref(R,RR),
 1449  M:ref(r(RR,R1,Score)).
 1450
 1451
 1452elab_clause_ref(rule(_NR,H,B,_Lits),rule(H1,B1)):-
 1453  copy_term((H,B),(H1,B1)).
 1454
 1455elab_ref([],[]).
 1456
 1457elab_ref([rule(_NR,H,B,_Lits)|T],[rule(H1,B1)|T1]):-!,
 1458  copy_term((H,B),(H1,B1)),
 1459  numbervars((H1,B1),0,_N),
 1460  elab_ref(T,T1).
 1461
 1462elab_ref([def_rule(H,B,_Lits)|T],[rule(H1,B1)|T1]):-
 1463  copy_term((H,B),(H1,B1)),
 1464  numbervars((H1,B1),0,_N),
 1465  elab_ref(T,T1).
 1466
 1467%insertion in the beam
 1468insert_in_order([],C,BeamSize,[C]):-
 1469  BeamSize>0,!.
 1470
 1471insert_in_order(Beam,_New,0,Beam):-!.
 1472
 1473insert_in_order([[Th1,Heuristic1|Rest1]|RestBeamIn],[Th,Heuristic|Rest],BeamSize,BeamOut):-
 1474  Heuristic>Heuristic1,!,
 1475  % larger heuristic, insert here
 1476  NewBeam=[[Th,Heuristic|Rest],[Th1,Heuristic1|Rest1]|RestBeamIn],
 1477  length(NewBeam,L),
 1478  (L>BeamSize->
 1479    nth1(L,NewBeam,_Last,BeamOut)
 1480  ;
 1481    BeamOut=NewBeam
 1482  ).
 1483
 1484insert_in_order([[Th1,Heuristic1|Rest1]|RestBeamIn],[Th,Heuristic|Rest],BeamSize,
 1485[[Th1,Heuristic1|Rest1]|RestBeamOut]):-
 1486  BeamSize1 is BeamSize -1,
 1487  insert_in_order(RestBeamIn,[Th,Heuristic|Rest],BeamSize1,
 1488  RestBeamOut).
 1489
 1490
 1491
 1492remove_int_atom_list([],[]).
 1493
 1494remove_int_atom_list([\+ A|T],[\+ A1|T1]):-!,
 1495  A=..[F,_|Arg],
 1496  A1=..[F|Arg],
 1497  remove_int_atom_list(T,T1).
 1498
 1499remove_int_atom_list([A|T],[A1|T1]):-
 1500  A=..[F,_|Arg],
 1501  A1=..[F|Arg],
 1502  remove_int_atom_list(T,T1).
 1503
 1504
 1505
 1506remove_int_atom(\+ A,\+ A1):-!,
 1507  A=..[F,_|T],
 1508  A1=..[F|T].
 1509
 1510remove_int_atom(A,A1):-
 1511  A=..[F,_|T],
 1512  A1=..[F|T].
 1513
 1514
 1515get_heads([],[]).
 1516
 1517get_heads([_-H|T],[H|TN]):-
 1518  get_heads(T,TN).
 1519
 1520randomize([],[]):-!.
 1521
 1522randomize([rule(N,V,NH,HL,BL,LogF)|T],[rule(N,V,NH,HL1,BL,LogF)|T1]):-
 1523  length(HL,L),
 1524  Int is 1.0/L,
 1525  randomize_head(Int,HL,0,HL1),
 1526  randomize(T,T1).
 1527
 1528randomize_head(_Int,['':_],P,['':PNull1]):-!,
 1529  PNull is 1.0-P,
 1530  (PNull>=0.0->
 1531    PNull1 =PNull
 1532  ;
 1533    PNull1=0.0
 1534  ).
 1535
 1536randomize_head(Int,[H:_|T],P,[H:PH1|NT]):-
 1537  PMax is 1.0-P,
 1538  random(0,PMax,PH1),
 1539  P1 is P+PH1,
 1540  randomize_head(Int,T,P1,NT).
 1541
 1542
 1543
 1544update_head([],[],_N,[]):-!.
 1545
 1546update_head([H:_P|T],[PU|TP],N,[H:P|T1]):-
 1547  P is PU/N,
 1548  update_head(T,TP,N,T1).
 1549
 1550/* utilities */
 1551
 1552
 1553rules2terms(R,T):-
 1554  maplist(rule2term,R,T).
 1555
 1556rule2term(rule(_N,HL,BL,_Lit),(H:-B)):-!,
 1557  list2or(HL,H),
 1558  list2and(BL,B).
 1559
 1560rule2term(def_rule(H,BL,_Lit),((H:1.0):-B)):-
 1561  list2and(BL,B).
 1562
 1563
 1564and2list((A,B),[A|L]):-
 1565  !,
 1566  and2list(B,L).
 1567
 1568and2list(A,[A]).
 1569
 1570write_rules_anyburl(R,File):-
 1571  open(File,write,S),
 1572  maplist(print_rule(S),R),
 1573  close(S).
 1574
 1575print_rule(S, (H:P :- B) ):-
 1576  copy_term((H,B),(H1,B1)),
 1577  triple_to_atom(H1,HA),
 1578  numbervars(HA,23,_),
 1579  and2list(B1,BL),
 1580  maplist(triple_to_atom,BL,BLA),
 1581  numbervars(BLA,0,_),
 1582  Supp is round(1000000*P),
 1583  format(S,"1000000\t~w\t~w\t~w <= ",[Supp,P,HA]),
 1584  write_body_ab(S,BLA).
 1585
 1586triple_to_atom(H,HA):-
 1587  H=..[_,S,R,T],
 1588  (R=i(RR)->
 1589    HA=..[RR,T,S]
 1590  ;
 1591    HA=..[R,S,T]
 1592  ).
 1593
 1594write_body_ab(S,[A]):-!,
 1595  write(S,A),nl(S).
 1596
 1597write_body_ab(S,[A|T]):-
 1598  write(S,A),write(S,', '),
 1599  write_body_ab(S,T).
 1600
 1601
 1602
 1603
 1604write_rules_kg(R,File):-
 1605  open(File,write,S),
 1606  writeln(S,'out(['),
 1607  write_clauses_kg(R,S),
 1608  writeln(S,']).'),
 1609  close(S).
 1610
 1611
 1612write_rules_kg(R):-
 1613  maplist(write_clause_kg_screen,R).
 1614
 1615write_clause_kg_screen(Cl):-
 1616  write_clause_kg(user_output,Cl),
 1617  writeln('.').
 1618
 1619write_clauses_kg([Cl],S):-!,
 1620  write(S,'('),
 1621  write_clause_kg(S,Cl),
 1622  writeln(S,')').
 1623
 1624write_clauses_kg([ClH|ClT],S):-
 1625  write(S,'('),
 1626  write_clause_kg(S,ClH),
 1627  writeln(S,'),'),
 1628  write_clauses_kg(ClT,S).
 1629
 1630write_clause_kg(S,(H:-B)):-
 1631  copy_term((H,B),(H1,B1)),
 1632  numbervars((H1,B1),0,_),
 1633  write_head_kg(H1,S),
 1634  format(S,' :-',[]),
 1635  and2list(B1,L),
 1636  write_body_kg(L,S).
 1637
 1638write_head_kg(A:P,S):-
 1639  format(S,"~q:~g",[A,P]).
 1640
 1641write_body_kg([],S):-!,
 1642  format(S,'  true',[]).
 1643
 1644write_body_kg([A],S):-!,
 1645  format(S,'  ~q',[A]).
 1646
 1647write_body_kg([A|T],S):-
 1648  format(S,'  ~q,',[A]),
 1649  write_body_kg(T,S).
 1650
 1651
 1652read_rules_anyburl(File,R):-
 1653  phrase_from_file(rules(R),File).
 1654
 1655
 1656rules([H|T])-->
 1657  rule(H),!,
 1658  rules(T).
 1659
 1660rules([])--> blanks_to_nl,[].
 1661
 1662rule(((tt(X,R,Y):C):-BC))-->
 1663  integer(_SB),
 1664  "\t",
 1665  integer(_S),
 1666  "\t",
 1667  float(C),
 1668  "\t",
 1669  atm(t(X,R,Y),[],V),
 1670  " <= ",
 1671  body(B,V,_),
 1672  {list2and(B,BC)}.
 1673
 1674atm(A,V0,V)-->
 1675  string_without("\n\t(",P),
 1676  {atom_string(PA,P)},
 1677  "(",
 1678  param(Par1,V0,V1),
 1679  ",",
 1680  param(Par2,V1,V),
 1681  ")",
 1682  {A=t(Par1,PA,Par2)}.
 1683
 1684body([],V,V)-->
 1685  "\n",!.
 1686
 1687body([A],V0,V)-->
 1688  atm(A,V0,V),"\n",!.
 1689
 1690body([A|T],V0,V)-->
 1691  atm(A,V0,V1),
 1692  ", ",!,
 1693  body(T,V1,V).
 1694
 1695
 1696
 1697param(Var,V0,V)-->
 1698  prolog_var_name(P),!,
 1699  {find_var(P,V0,V,Var)}.
 1700
 1701param(PA,V,V)-->
 1702  string_without(",)",P),
 1703  {atom_string(PA,P)}.
 1704
 1705find_var(VN,V0,V0,V):-
 1706  member(VN:V,V0),!.
 1707
 1708find_var(VN,V0,[VN:V|V0],V).
 1709
 1710
 1711
 1712
 1713
 1714write_rules([],_S).
 1715
 1716write_rules([rule(_N,HL,BL,Lit)|T],S):-!,
 1717  copy_term((HL,BL,Lit),(HL1,BL1,Lit1)),
 1718  numbervars((HL1,BL1,Lit1),0,_M),
 1719  write_disj_clause(S,(HL1:-BL1)),
 1720  write_rules(T,S).
 1721
 1722write_rules([def_rule(H,BL,Lit)|T],S):-
 1723  copy_term((H,BL,Lit),(H1,BL1,Lit1)),
 1724  numbervars((H1,BL1,Lit1),0,_M),
 1725  write_disj_clause(S,([H1:1.0]:-BL1)),
 1726  write_rules(T,S).
 1727
 1728
 1729new_par([],[],[]).
 1730
 1731new_par([HP|TP],[Head:_|TO],[Head:HP|TN]):-
 1732  new_par(TP,TO,TN).
 1733
 1734
 1735
 1736write_disj_clause(S,(H:-[])):-!,
 1737  write_head(S,H),
 1738  format(S,".~n~n",[]).
 1739
 1740write_disj_clause(S,(H:-B)):-
 1741  write_head(S,H),
 1742  format(S,' :-',[]),
 1743  nl(S),
 1744  write_body(S,B).
 1745
 1746
 1747write_head(S,[A:1.0|_Rest]):-!,
 1748  format(S,"~q:1.0",[A]).
 1749
 1750write_head(S,[A:P,'':_P]):-!,
 1751  format(S,"~q:~g",[A,P]).
 1752
 1753write_head(S,[A:P]):-!,
 1754  format(S,"~q:~g",[A,P]).
 1755
 1756write_head(S,[A:P|Rest]):-
 1757  format(S,"~q:~g ; ",[A,P]),
 1758  write_head(S,Rest).
 1759
 1760write_body(S,[]):-!,
 1761  format(S,"  true.~n~n",[]).
 1762
 1763write_body(S,[A]):-!,
 1764  format(S,"  ~q.~n~n",[A]).
 1765
 1766write_body(S,[A|T]):-
 1767  format(S,"  ~q,~n",[A]),
 1768  write_body(S,T).
 list2or(+List:list, -Or:term) is det
list2or(-List:list, +Or:term) is det
The predicate succeeds when Or is a disjunction (using the ; operator) of the terms in List /
 1777list2or([],true):-!.
 1778
 1779list2or([X],X):-
 1780    X\=;(_,_),!.
 1781
 1782list2or([H|T],(H ; Ta)):-!,
 1783    list2or(T,Ta).
 list2and(+List:list, -And:term) is det
list2and(-List:list, +And:term) is det
The predicate succeeds when And is a conjunction (using the , operator) of the terms in List /
 1793list2and([],true):-!.
 1794
 1795list2and([X],X):-
 1796    X\=(_,_),!.
 1797
 1798list2and([H|T],(H,Ta)):-!,
 1799    list2and(T,Ta).
 1800
 1801
 1802deduct(0,_Mod,_DB,Th,Th):-!.
 1803
 1804deduct(NM,Mod,DB,InTheory0,InTheory):-
 1805  get_head_atoms(O,Mod),
 1806  sample_lift(1,DB,Sampled,DB1),
 1807  (Sampled=[M]->
 1808    generate_head(O,M,Mod,[],HL),
 1809    %gtrace,
 1810    ( HL \== [] ->
 1811       (generate_body(HL,Mod,InTheory1),
 1812    	append(InTheory0,InTheory1,InTheory2),
 1813    	NM1 is NM-1,
 1814    	deduct(NM1,Mod,DB1,InTheory2,InTheory)
 1815       )
 1816      ;
 1817       deduct(NM,Mod,DB,InTheory0,InTheory)
 1818    )
 1819  ;
 1820    InTheory=InTheory0
 1821  ).
 1822
 1823
 1824get_head_atoms(O,M):-
 1825  findall(A,M:modeh(_,A),O).
 1826
 1827generate_top_cl([],_M,[]):-!.
 1828
 1829generate_top_cl([A|T],M,[(rule(R,[A1:0.5,'':0.5],[],true),-1e20)|TR]):-
 1830  A=..[F|ArgM],
 1831  keep_const(ArgM,Arg),
 1832  A1=..[F|Arg],
 1833  get_next_rule_number(M,R),
 1834  generate_top_cl(T,M,TR).
 1835
 1836
 1837generate_head([],_M,_Mod,HL,HL):-!.
 1838
 1839generate_head([A|T],M,Mod,H0,H1):-
 1840  functor(A,F,N),
 1841  functor(F1,F,N),
 1842  F1=..[F|Arg],
 1843  Pred1=..[F,M|Arg],
 1844  A=..[F|ArgM],
 1845  keep_const(ArgM,Arg),
 1846  findall((A,Pred1),call(Mod:Pred1),L),
 1847  Mod:local_setting(initial_clauses_per_megaex,IC),
 1848  sample_lift(IC,L,L1),
 1849  append(H0,L1,H2),
 1850  generate_head(T,M,Mod,H2,H1).
 1851
 1852generate_head_goal([],_M,[]).
 1853
 1854generate_head_goal([H|T],M,[H1|T1]):-
 1855  H=..[F|Arg],
 1856  H1=..[F,M|Arg],
 1857  generate_head_goal(T,M,T1).
 1858
 1859keep_const([],[]).
 1860
 1861keep_const([- _|T],[_|T1]):-!,
 1862  keep_const(T,T1).
 1863
 1864keep_const([+ _|T],[_|T1]):-!,
 1865  keep_const(T,T1).
 1866
 1867keep_const([-# _|T],[_|T1]):-!,
 1868  keep_const(T,T1).
 1869
 1870keep_const([H|T],[H1|T1]):-
 1871  H=..[F|Args],
 1872  keep_const(Args,Args1),
 1873  H1=..[F|Args1],
 1874  keep_const(T,T1).
 sample_lift(+N, List:list, -Sampled:list, -Rest:list) is det
Samples N elements from List and returns them in Sampled. The rest of List is returned in Rest If List contains less than N elements, Sampled is List and Rest is []. */
 1885sample_lift(0,List,[],List):-!.
 1886
 1887sample_lift(N,List,List,[]):-
 1888  length(List,L),
 1889  L=<N,!.
 1890
 1891sample_lift(N,List,[El|List1],Li):-
 1892  length(List,L),
 1893  random(0,L,Pos),
 1894  nth0(Pos,List,El,Rest),
 1895  N1 is N-1,
 1896  sample_lift(N1,Rest,List1,Li).
 1897
 1898sample_lift(0,_List,[]):-!.
 1899
 1900sample_lift(N,List,List):-
 1901  length(List,L),
 1902  L=<N,!.
 1903
 1904sample_lift(N,List,[El|List1]):-
 1905  length(List,L),
 1906  random(0,L,Pos),
 1907  nth0(Pos,List,El,Rest),
 1908  N1 is N-1,
 1909  sample_lift(N1,Rest,List1).
 1910
 1911get_args([],[],[],A,A,AT,AT,_).
 1912
 1913get_args([HM|TM],[H|TH],[(H,HM)|TP],A0,A,AT0,AT,M):-
 1914  HM=..[F|ArgsTypes],
 1915  H=..[F,M|Args],
 1916  append(A0,Args,A1),
 1917  append(AT0,ArgsTypes,AT1),
 1918  get_args(TM,TH,TP,A1,A,AT1,AT,M).
 1919
 1920/* Generation of the bottom clauses */
 1921
 1922gen_head([],P,['':P]).
 1923
 1924gen_head([H|T],P,[H:P|TH]):-
 1925  gen_head(T,P,TH).
 1926
 1927get_modeb([],_Mod,B,B).
 1928
 1929get_modeb([F/AA|T],Mod,B0,B):-
 1930  findall((R,B),(Mod:modeb(R,B),functor(B,F,AA)),BL),
 1931  (Mod:local_setting(neg_literals,true)->
 1932    findall((R,(\+ B)),(Mod:modeb(R,B),functor(B,F,AA),all_plus(B)),BNL)
 1933  ;
 1934    BNL=[]
 1935  ),
 1936  append([B0,BL,BNL],B1),
 1937  get_modeb(T,Mod,B1,B).
 1938
 1939all_plus(B):-
 1940  B=..[_|Args],
 1941  all_plus_args(Args).
 1942
 1943all_plus_args([]).
 1944
 1945all_plus_args([+ _ |T]):-!,
 1946  all_plus_args(T).
 1947
 1948all_plus_args([H|T]):-
 1949  H \= - _,
 1950  H \= # _,
 1951  H \= -# _,
 1952  H=..[_|Args],
 1953  all_plus_args(Args),
 1954  all_plus_args(T).
 1955
 1956generate_body([],_Mod,[]):-!.
 1957
 1958generate_body([(A,H)|T],Mod,Out):-
 1959  functor(A,F,AA),
 1960%  findall((R,B),(Mod:modeb(R,B),functor(B,FB,AB),Mod:determination(F/AA,FB/AB)),BL),
 1961  findall(FB/AB,Mod:determination(F/AA,FB/AB),Det),
 1962  get_modeb(Det,Mod,[],BL),
 1963  A=..[F|ArgsTypes],
 1964  H=..[F,M|Args],
 1965  Mod:local_setting(d,D),
 1966  format2(Mod,"Bottom clause: example ~q~n",[H]),
 1967  cycle_modeb(ArgsTypes,Args,[],[],Mod,BL,a,[],BLout0,D,M),
 1968  variabilize(([(H,A)]:-BLout0),CLV),  %+(Head):-Bodylist;  -CLV:(Head):-Bodylist with variables _num in place of constants
 1969  CLV=([Head1]:-BodyList1),
 1970  (range_restricted(rule(_,Head1,BodyList1,_))->
 1971    remove_int_atom(Head1,Head),
 1972    remove_int_atom_list(BodyList1,BodyList2),
 1973    remove_duplicates(BodyList2,BodyList),
 1974    get_next_rule_number(Mod,R),
 1975    copy_term((Head,BodyList),(HeadV,BodyListV)),
 1976    numbervars((HeadV,BodyListV),0,_V),
 1977    format2(Mod,"Clause~n~q:0.5 :-~n",[HeadV]),
 1978    write_body2(Mod,user_output,BodyListV),
 1979    Out=[c(-inf, rule(R,[Head:0.5,'':0.5],[],BodyList),_)|CL0]
 1980  ;
 1981    format2(Mod,"No range restricted bottom clause~n~n",[]),
 1982    Out=CL0
 1983  ),
 1984  generate_body(T,Mod,CL0).
 1985
 1986
 1987variabilize((H:-B),(H1:-B1)):-
 1988  variabilize_list(H,H1,[],AS,M),
 1989  variabilize_list(B,B1,AS,_AS,M).
 1990
 1991
 1992variabilize_list([],[],A,A,_M).
 1993
 1994variabilize_list([(\+ H,Mode)|T],[\+ H1|T1],A0,A,M):-
 1995  builtin(H),!,
 1996  H=..[F|Args],
 1997  Mode=..[F|ArgTypes],
 1998  variabilize_args(Args,ArgTypes, Args1,A0,A1),
 1999  H1=..[F,M|Args1],
 2000  variabilize_list(T,T1,A1,A,M).
 2001
 2002variabilize_list([(\+ H,Mode)|T],[\+ H1|T1],A0,A,M):-!,
 2003  H=..[F,_M|Args],
 2004  Mode=..[F|ArgTypes],
 2005  variabilize_args(Args,ArgTypes, Args1,A0,A1),
 2006  H1=..[F,M|Args1],
 2007  variabilize_list(T,T1,A1,A,M).
 2008
 2009variabilize_list([(H,Mode)|T],[H1|T1],A0,A,M):-
 2010  builtin(H),!,
 2011  H=..[F|Args],
 2012  Mode=..[F|ArgTypes],
 2013  variabilize_args(Args,ArgTypes, Args1,A0,A1),
 2014  H1=..[F,M|Args1],
 2015  variabilize_list(T,T1,A1,A,M).
 2016
 2017variabilize_list([(H,Mode)|T],[H1|T1],A0,A,M):-
 2018  H=..[F,_M|Args],
 2019  Mode=..[F|ArgTypes],
 2020  variabilize_args(Args,ArgTypes, Args1,A0,A1),
 2021  H1=..[F,M|Args1],
 2022  variabilize_list(T,T1,A1,A,M).
 2023
 2024
 2025variabilize_args([],[],[],A,A).
 2026
 2027variabilize_args([C|T],[C|TT],[C|TV],A0,A):-!,
 2028  variabilize_args(T,TT,TV,A0,A).
 2029
 2030variabilize_args([C|T],[# _Ty|TT],[C|TV],A0,A):-!,
 2031  variabilize_args(T,TT,TV,A0,A).
 2032
 2033variabilize_args([C|T],[-# _Ty|TT],[C|TV],A0,A):-!,
 2034  variabilize_args(T,TT,TV,A0,A).
 2035
 2036variabilize_args([C|T],[Ty|TT],[V|TV],A0,A):-
 2037  (Ty = +Ty1;Ty = -Ty1),
 2038  member(C/Ty1/V,A0),!,
 2039  variabilize_args(T,TT,TV,A0,A).
 2040
 2041variabilize_args([C|T],[Ty|TT],[V|TV],A0,A):-
 2042  (Ty = +Ty1;Ty = -Ty1),!,
 2043  variabilize_args(T,TT,TV,[C/Ty1/V|A0],A).
 2044
 2045variabilize_args([C|T],[Ty|TT],[V|TV],A0,A):-
 2046  compound(C),
 2047  C=..[F|Args],
 2048  Ty=..[F|ArgsT],
 2049  variabilize_args(Args,ArgsT,ArgsV,A0,A1),
 2050  V=..[F|ArgsV],
 2051  variabilize_args(T,TT,TV,A1,A).
 2052
 2053
 2054cycle_modeb(ArgsTypes,Args,ArgsTypes,Args,_Mod,_BL,L,L,L,_,_M):-!.
 2055
 2056cycle_modeb(_ArgsTypes,_Args,_ArgsTypes1,_Args1,_Mod,_BL,_L,L,L,0,_M):-!.
 2057
 2058cycle_modeb(ArgsTypes,Args,_ArgsTypes0,_Args0,Mod,BL,_L0,L1,L,D,M):-
 2059  find_atoms(BL,Mod,ArgsTypes,Args,ArgsTypes1,Args1,L1,L2,M),
 2060  D1 is D-1,
 2061  cycle_modeb(ArgsTypes1,Args1,ArgsTypes,Args,Mod,BL,L1,L2,L,D1,M).
 2062
 2063
 2064find_atoms([],_Mod,ArgsTypes,Args,ArgsTypes,Args,L,L,_M).
 2065
 2066find_atoms([(R,\+ H)|T],Mod,ArgsTypes0,Args0,ArgsTypes,Args,L0,L1,M):-!,
 2067  H=..[F|ArgsT],
 2068  findall((A,H),instantiate_query_neg(ArgsT,ArgsTypes0,Args0,F,M,A),L),
 2069  call_atoms(L,Mod,[],At),
 2070  remove_duplicates(At,At1),
 2071  ((R = '*' ) ->
 2072    R1= +1e20
 2073  ;
 2074    R1=R
 2075  ),
 2076  sample_lift(R1,At1,At2),
 2077  append(L0,At2,L2),
 2078  find_atoms(T,Mod,ArgsTypes0,Args0,ArgsTypes,Args,L2,L1,M).
 2079
 2080find_atoms([(R,H)|T],Mod,ArgsTypes0,Args0,ArgsTypes,Args,L0,L1,M):-
 2081  H=..[F|ArgsT],
 2082  findall((A,H),instantiate_query(ArgsT,ArgsTypes0,Args0,F,M,A),L),
 2083  call_atoms(L,Mod,[],At),
 2084  remove_duplicates(At,At1),
 2085  ((R = '*' ) ->
 2086    R1= +1e20
 2087  ;
 2088    R1=R
 2089  ),
 2090  sample_lift(R1,At1,At2),
 2091  extract_output_args(At2,ArgsT,ArgsTypes0,Args0,ArgsTypes1,Args1),
 2092  append(L0,At2,L2),
 2093  find_atoms(T,Mod,ArgsTypes1,Args1,ArgsTypes,Args,L2,L1,M).
 2094
 2095
 2096call_atoms([],_Mod,A,A).
 2097
 2098call_atoms([(H,M)|T],Mod,A0,A):-
 2099  findall((H,M),Mod:H,L),
 2100  append(A0,L,A1),
 2101  call_atoms(T,Mod,A1,A).
 2102
 2103
 2104extract_output_args([],_ArgsT,ArgsTypes,Args,ArgsTypes,Args).
 2105
 2106extract_output_args([(H,_At)|T],ArgsT,ArgsTypes0,Args0,ArgsTypes,Args):-
 2107  builtin(H),!,
 2108  H=..[_F|ArgsH],
 2109  add_const(ArgsH,ArgsT,ArgsTypes0,Args0,ArgsTypes1,Args1),
 2110  extract_output_args(T,ArgsT,ArgsTypes1,Args1,ArgsTypes,Args).
 2111
 2112extract_output_args([(H,_At)|T],ArgsT,ArgsTypes0,Args0,ArgsTypes,Args):-
 2113  H=..[_F,_M|ArgsH],
 2114  add_const(ArgsH,ArgsT,ArgsTypes0,Args0,ArgsTypes1,Args1),
 2115  extract_output_args(T,ArgsT,ArgsTypes1,Args1,ArgsTypes,Args).
 2116
 2117
 2118add_const([],[],ArgsTypes,Args,ArgsTypes,Args).
 2119
 2120add_const([_A|T],[+_T|TT],ArgsTypes0,Args0,ArgsTypes,Args):-!,
 2121  add_const(T,TT,ArgsTypes0,Args0,ArgsTypes,Args).
 2122
 2123add_const([A|T],[-Type|TT],ArgsTypes0,Args0,ArgsTypes,Args):-!,
 2124  (already_present(ArgsTypes0,Args0,A,Type)->
 2125    ArgsTypes1=ArgsTypes0,
 2126    Args1=Args0
 2127  ;
 2128    ArgsTypes1=[+Type|ArgsTypes0],
 2129    Args1=[A|Args0]
 2130  ),
 2131  add_const(T,TT,ArgsTypes1,Args1,ArgsTypes,Args).
 2132
 2133add_const([A|T],[-# Type|TT],ArgsTypes0,Args0,ArgsTypes,Args):-!,
 2134  (already_present(ArgsTypes0,Args0,A,Type)->
 2135    ArgsTypes1=ArgsTypes0,
 2136    Args1=Args0
 2137  ;
 2138    ArgsTypes1=[+Type|ArgsTypes0],
 2139    Args1=[A|Args0]
 2140  ),
 2141  add_const(T,TT,ArgsTypes1,Args1,ArgsTypes,Args).
 2142
 2143add_const([_A|T],[# _|TT],ArgsTypes0,Args0,ArgsTypes,Args):-!,
 2144  add_const(T,TT,ArgsTypes0,Args0,ArgsTypes,Args).
 2145
 2146add_const([A|T],[A|TT],ArgsTypes0,Args0,ArgsTypes,Args):-
 2147  atomic(A),!,
 2148  add_const(T,TT,ArgsTypes0,Args0,ArgsTypes,Args).
 2149
 2150add_const([A|T],[AT|TT],ArgsTypes0,Args0,ArgsTypes,Args):-
 2151  A=..[F|Ar],
 2152  AT=..[F|ArT],
 2153  add_const(Ar,ArT,ArgsTypes0,Args0,ArgsTypes1,Args1),
 2154  add_const(T,TT,ArgsTypes1,Args1,ArgsTypes,Args).
 2155
 2156
 2157already_present([+T|_TT],[C|_TC],C,T):-!.
 2158
 2159already_present([_|TT],[_|TC],C,T):-
 2160  already_present(TT,TC,C,T).
 2161
 2162
 2163instantiate_query_neg(ArgsT,ArgsTypes,Args,F,M,A):-
 2164  instantiate_input(ArgsT,ArgsTypes,Args,ArgsB),
 2165  A1=..[F|ArgsB],
 2166  (builtin(A1)->
 2167    A= (\+ A1)
 2168  ;
 2169    A0=..[F,M|ArgsB],
 2170    A = (\+ A0)
 2171  ).
 2172
 2173instantiate_query(ArgsT,ArgsTypes,Args,F,M,A):-
 2174  instantiate_input(ArgsT,ArgsTypes,Args,ArgsB),
 2175  A1=..[F|ArgsB],
 2176  (builtin(A1)->
 2177    A=A1
 2178  ;
 2179    A=..[F,M|ArgsB]
 2180  ).
 2181
 2182
 2183instantiate_input([],_AT,_A,[]).
 2184
 2185instantiate_input([-_Type|T],AT,A,[_V|TA]):-!,
 2186  instantiate_input(T,AT,A,TA).
 2187
 2188instantiate_input([+Type|T],AT,A,[H|TA]):-!,
 2189  find_val(AT,A,+Type,H),
 2190  instantiate_input(T,AT,A,TA).
 2191
 2192instantiate_input([# Type|T],AT,A,[H|TA]):-!,
 2193  find_val(AT,A,+Type,H),
 2194  instantiate_input(T,AT,A,TA).
 2195
 2196instantiate_input([-# _Type|T],AT,A,[_V|TA]):-!,
 2197  instantiate_input(T,AT,A,TA).
 2198
 2199instantiate_input([C|T],AT,A,[C1|TA]):-
 2200  C=..[F|Args],
 2201  instantiate_input(Args,AT,A,Args1),
 2202  C1=..[F|Args1],
 2203  instantiate_input(T,AT,A,TA).
 2204
 2205
 2206find_val([T|_TT],[A|_TA],T,A).
 2207
 2208find_val([HT|_TT],[HA|_TA],T,A):-
 2209  nonvar(HA),
 2210  HT=..[F|ArgsT],
 2211  HA=..[F|Args],
 2212  find_val(ArgsT,Args,T,A).
 2213
 2214find_val([_T|TT],[_A|TA],T,A):-
 2215  find_val(TT,TA,T,A).
 2216
 2217
 2218get_output_atoms(O,M):-
 2219  findall((A/Ar),M:output((A/Ar)),O).
 2220
 2221
 2222generate_goal([],_M,_H,G,G):-!.
 2223
 2224generate_goal([P/A|T],M,H,G0,G1):-
 2225  functor(Pred,P,A),
 2226  Pred=..[P|Rest],
 2227  Pred1=..[P,H|Rest],
 2228  findall(Pred1,call(M:Pred1),L),
 2229  findall(\+ Pred1,call(M:neg(Pred1)),LN),
 2230  append(G0,L,G2),
 2231  append(G2,LN,G3),
 2232  generate_goal(T,M,H,G3,G1).
 2233
 2234remove_duplicates(L0,L):-
 2235  remove_duplicates(L0,[],L1),
 2236  reverse(L1,L).
 2237
 2238remove_duplicates([],L,L).
 2239
 2240remove_duplicates([H|T],L0,L):-
 2241  member_eq(H,L0),!,
 2242  remove_duplicates(T,L0,L).
 2243
 2244remove_duplicates([H|T],L0,L):-
 2245  remove_duplicates(T,[H|L0],L).
 2246
 2247
 2248/*
 2249
 2250EMBLEM and SLIPCASE
 2251
 2252Copyright (c) 2011, Fabrizio Riguzzi, Nicola di Mauro and Elena Bellodi
 2253
 2254*/
 2255
 2256
 2257
 2258
 2259
 2260specialize_rule(Rule,M,_SpecRule,_Lit):-
 2261  M:local_setting(max_body_length,ML),
 2262  Rule = rule(_ID,_LH,BL,_Lits),
 2263  length(BL,L),
 2264  L=ML,!,
 2265  fail.
 2266
 2267specialize_rule(Rule,M,SpecRule,Lit):-
 2268  M:local_setting(max_body_length,ML),
 2269  Rule = rule(_ID,_LH,BL,_Lits),
 2270  length(BL,L),
 2271  (L=ML->
 2272    !,
 2273    fail
 2274  ;
 2275    specialize_rule_int(Rule,M,SpecRule,Lit),
 2276    (L=:=ML-1->
 2277      range_restricted(SpecRule)
 2278    ;
 2279      true
 2280    )
 2281  ).
 2282    
 2283
 2284%used by cycle_clauses in slipcover.pl
 2285specialize_rule_int(Rule,M,SpecRule,Lit):-
 2286  M:local_setting(specialization,bottom),
 2287  Rule = rule(ID,LH,BL,Lits),
 2288  delete_one(Lits,RLits,Lit),
 2289  \+ M:lookahead_cons(Lit,_),
 2290  \+ M:lookahead_cons_var(Lit,_),
 2291  \+ member_eq(Lit,BL),
 2292  append(BL,[Lit],BL1),
 2293  remove_prob(LH,LH1),
 2294  delete(LH1,'',LH2),
 2295  append(LH2,BL1,ALL2),
 2296  dv(LH2,BL1,M,DList), 	%-DList: list of couples (variable,depth)
 2297  extract_fancy_vars(ALL2,Vars1),
 2298  length(Vars1,NV),
 2299  M:local_setting(max_var,MV),
 2300  NV=<MV,
 2301  linked_clause(BL1,M,LH2),
 2302  M:local_setting(maxdepth_var,MD),
 2303  exceed_depth(DList,MD),
 2304  \+ banned_clause(LH2,BL1),
 2305  SpecRule=rule(ID,LH,BL1,RLits).
 2306
 2307specialize_rule_int(Rule,M,SpecRule,Lit):-
 2308  M:local_setting(specialization,bottom),
 2309  Rule = rule(ID,LH,BL,Lits),
 2310  delete_one(Lits,RLits,Lit),
 2311  \+ member_eq(Lit,BL),
 2312  append(BL,[Lit],BL0),
 2313  \+M:lookahead_cons_var(Lit,_),
 2314  (M:lookahead(Lit,LLit1);M:lookahead_cons(Lit,LLit1)),
 2315  copy_term(LLit1,LLit2),
 2316  specialize_rule_la_bot(LLit2,RLits,RLits1,BL0,BL1),
 2317  remove_prob(LH,LH1),
 2318  delete(LH1,'',LH2),
 2319  append(LH2,BL1,ALL2),
 2320  dv(LH2,BL1,M,DList),
 2321  extract_fancy_vars(ALL2,Vars1),
 2322  length(Vars1,NV),
 2323  M:local_setting(max_var,MV),
 2324  NV=<MV,
 2325  linked_clause(BL1,M,LH2),
 2326  M:local_setting(maxdepth_var,MD),
 2327  exceed_depth(DList,MD),
 2328  \+ banned_clause(LH2,BL1),
 2329  SpecRule=rule(ID,LH,BL1,RLits1).
 2330
 2331specialize_rule_int(Rule,M,SpecRule,Lit):-
 2332  M:local_setting(specialization,bottom),
 2333  Rule = rule(ID,LH,BL,Lits),
 2334  delete_one(Lits,RLits,Lit),
 2335  \+ member_eq(Lit,BL),
 2336  append(BL,[Lit],BL0),
 2337  M:lookahead_cons_var(Lit,LLit2),
 2338  specialize_rule_la_bot(LLit2,RLits,_RLits1,BL0,BL1),
 2339  remove_prob(LH,LH1),
 2340  delete(LH1,'',LH2),
 2341  append(LH2,BL1,ALL2),
 2342  dv(LH2,BL1,M,DList),
 2343  extract_fancy_vars(ALL2,Vars1),
 2344  length(Vars1,NV),
 2345  M:local_setting(max_var,MV),
 2346  NV=<MV,
 2347  linked_clause(BL1,M,LH2),
 2348  M:local_setting(maxdepth_var,MD),
 2349  exceed_depth(DList,MD),
 2350  \+ banned_clause(LH2,BL1),
 2351  SpecRule=rule(ID,LH,BL1,[]).
 2352
 2353specialize_rule_int(Rule,M,SpecRule,Lit):-
 2354  M:local_setting(specialization,mode),%!,
 2355  findall(BL , M:modeb(_,BL), BLS),
 2356  specialize_rule(BLS,Rule,M,SpecRule,Lit).
 2357
 2358
 2359update_head1([],_N,[]):-!.
 2360
 2361update_head1([H:_P|T],N,[H:P|T1]):-
 2362	       P is 1/N,
 2363	       update_head1(T,N,T1).
 2364
 2365
 2366banned_clause(H,B):-
 2367  lift_input_mod(M),
 2368  numbervars((H,B),0,_N),
 2369  M:banned(H2,B2),
 2370  mysublist(H2,H),
 2371  mysublist(B2,B).
 2372
 2373
 2374mysublist([],_).
 2375
 2376mysublist([H|T],L):-
 2377  member(H,L),
 2378  mysublist(T,L).
 2379
 2380
 2381specialize_rule([Lit|_RLit],Rule,M,SpecRul,SLit):-
 2382  Rule = rule(ID,LH,BL,true),
 2383  remove_prob(LH,LH1),
 2384  append(LH1,BL,ALL),
 2385  specialize_rule1(Lit,ALL,SLit),
 2386  append(BL,[SLit],BL1),
 2387  (M:lookahead(SLit,LLit1);M:lookahead_cons(SLit,LLit1)),
 2388  specialize_rule_la(LLit1,LH1,BL1,BL2),
 2389  append(LH1,BL2,ALL2),
 2390  extract_fancy_vars(ALL2,Vars1),
 2391  length(Vars1,NV),
 2392  M:local_setting(max_var,MV),
 2393  NV=<MV,
 2394  SpecRul = rule(ID,LH,BL2,true).
 2395
 2396specialize_rule([Lit|_RLit],Rule,M,SpecRul,SLit):-
 2397  Rule = rule(ID,LH,BL,true),
 2398  remove_prob(LH,LH1),
 2399  append(LH1,BL,ALL),
 2400  specialize_rule1(Lit,ALL,SLit),
 2401  \+ M:lookahead_cons(SLit,_),
 2402  append(BL,[SLit],BL1),
 2403  append(LH1,BL1,ALL1),
 2404  extract_fancy_vars(ALL1,Vars1),
 2405  length(Vars1,NV),
 2406  M:local_setting(max_var,MV),
 2407  NV=<MV,
 2408  SpecRul = rule(ID,LH,BL1,true).
 2409
 2410specialize_rule([_|RLit],Rule,M,SpecRul,Lit):-
 2411  specialize_rule(RLit,Rule,M,SpecRul,Lit).
 2412
 2413
 2414specialize_rule_la([],_LH1,BL1,BL1).
 2415
 2416specialize_rule_la([Lit1|T],LH1,BL1,BL3):-
 2417  copy_term(Lit1,Lit2),
 2418  lift_input_mod(M),
 2419  M:modeb(_,Lit2),
 2420  append(LH1,BL1,ALL1),
 2421  specialize_rule1(Lit2,ALL1,SLit1),
 2422  append(BL1,[SLit1],BL2),
 2423  specialize_rule_la(T,LH1,BL2,BL3).
 2424
 2425
 2426specialize_rule_la_bot([],Bot,Bot,BL,BL).
 2427
 2428specialize_rule_la_bot([Lit|T],Bot0,Bot,BL1,BL3):-
 2429  delete_one(Bot0,Bot1,Lit),
 2430  \+ member_eq(Lit,BL1),
 2431  append(BL1,[Lit],BL2),
 2432  specialize_rule_la_bot(T,Bot1,Bot,BL2,BL3).
 2433
 2434
 2435remove_prob(['':_P],[]):-!.
 2436
 2437remove_prob([X:_|R],[X|R1]):-
 2438  remove_prob(R,R1).
 2439
 2440
 2441specialize_rule1(Lit,Lits,SpecLit):-
 2442  Lit =.. [Pred|Args],
 2443  exctract_type_vars(Lits,TypeVars0),
 2444  remove_duplicates(TypeVars0,TypeVars),
 2445  take_var_args(Args,TypeVars,Args1),
 2446  SpecLit =.. [Pred|Args1],
 2447  \+ member_eq(SpecLit,Lits).
 2448
 2449
 2450convert_to_input_vars([],[]):-!.
 2451
 2452convert_to_input_vars([+T|RT],[+T|RT1]):-
 2453  !,
 2454  convert_to_input_vars(RT,RT1).
 2455
 2456convert_to_input_vars([-T|RT],[+T|RT1]):-
 2457  convert_to_input_vars(RT,RT1).
 2458
 2459
 2460
 2461remove_eq(X,[Y|R],R):-
 2462  X == Y,
 2463  !.
 2464
 2465remove_eq(X,[_|R],R1):-
 2466  remove_eq(X,R,R1).
 2467
 2468linked_clause(BodyLits,M,[Head]):-
 2469  input_head_variables(Head,M,InputHeadVars),
 2470  linked_clause_int(BodyLits,M,InputHeadVars).
 2471
 2472linked_clause_int([],_M,_).
 2473
 2474linked_clause_int([L|R],M,PrevVars):-
 2475  input_variables(L,M,InputVars),
 2476  linked(InputVars,PrevVars),!,
 2477  term_variables(L,LVars),
 2478  append(LVars,PrevVars,PrevVars1),
 2479  linked_clause_int(R,M,PrevVars1).
 2480
 2481
 2482linked([],_).
 2483
 2484linked([X|R],L) :-
 2485  member_eq(X,L),
 2486  !,
 2487  linked(R,L).
 2488
 2489
 2490input_variables(\+ LitM,M,InputVars):-
 2491  !,
 2492  LitM=..[P|Args],
 2493  length(Args,LA),
 2494  length(Args1,LA),
 2495  Lit1=..[P|Args1],
 2496%  copy_term(LitM,Lit0),
 2497  M:modeb(_,Lit1),
 2498  Lit1 =.. [P|Args1],
 2499  convert_to_input_vars(Args1,Args2),
 2500  Lit2 =.. [P|Args2],
 2501  input_vars(LitM,Lit2,InputVars).
 2502
 2503input_variables(LitM,M,InputVars):-
 2504  LitM=..[P|Args],
 2505  length(Args,LA),
 2506  length(Args1,LA),
 2507  Lit1=..[P|Args1],
 2508  M:modeb(_,Lit1),
 2509  input_vars(LitM,Lit1,InputVars).
 2510
 2511input_head_variables(LitM,M,InputVars):-
 2512  LitM=..[P|Args],
 2513  length(Args,LA),
 2514  length(Args1,LA),
 2515  Lit1=..[P|Args1],
 2516  M:modeh(_,Lit1),
 2517  input_vars(LitM,Lit1,InputVars).
 2518
 2519input_vars(Lit,Lit1,InputVars):-
 2520  Lit =.. [_|Vars],
 2521  Lit1 =.. [_|Types],
 2522  input_vars1(Vars,Types,InputVars).
 2523
 2524
 2525input_vars1([],_,[]).
 2526
 2527input_vars1([V|RV],[+_T|RT],[V|RV1]):-
 2528  !,
 2529  input_vars1(RV,RT,RV1).
 2530
 2531input_vars1([_V|RV],[_|RT],RV1):-
 2532  input_vars1(RV,RT,RV1).
 2533
 2534
 2535exctract_type_vars([],[]).
 2536
 2537exctract_type_vars([Lit|RestLit],TypeVars):-
 2538  Lit =.. [Pred|Args],
 2539  length(Args,L),
 2540  length(Args1,L),
 2541  Lit1 =.. [Pred|Args1],
 2542  take_mode(Lit1),
 2543  type_vars(Args,Args1,Types),
 2544  exctract_type_vars(RestLit,TypeVars0),
 2545  !,
 2546  append(Types,TypeVars0,TypeVars).
 2547
 2548
 2549take_mode(Lit):-
 2550  lift_input_mod(M),
 2551  M:modeh(_,Lit),!.
 2552
 2553take_mode(Lit):-
 2554  lift_input_mod(M),
 2555  M:modeb(_,Lit),!.
 2556
 2557take_mode(Lit):-
 2558  lift_input_mod(M),
 2559  M:mode(_,Lit),!.
 2560
 2561
 2562type_vars([],[],[]).
 2563
 2564type_vars([V|RV],[+T|RT],[V=T|RTV]):-
 2565  !,
 2566  type_vars(RV,RT,RTV).
 2567
 2568type_vars([V|RV],[-T|RT],[V=T|RTV]):-atom(T),!,
 2569  type_vars(RV,RT,RTV).
 2570
 2571type_vars([_V|RV],[_T|RT],RTV):-
 2572  type_vars(RV,RT,RTV).
 2573
 2574
 2575take_var_args([],_,[]).
 2576
 2577take_var_args([+T|RT],TypeVars,[V|RV]):-
 2578  !,
 2579  member(V=T,TypeVars),
 2580  take_var_args(RT,TypeVars,RV).
 2581
 2582take_var_args([-T|RT],TypeVars,[_V|RV]):-
 2583  atom(T),
 2584  take_var_args(RT,TypeVars,RV).
 2585
 2586take_var_args([-T|RT],TypeVars,[V|RV]):-
 2587  member(V=T,TypeVars),
 2588  take_var_args(RT,TypeVars,RV).
 2589
 2590take_var_args([T|RT],TypeVars,[T|RV]):-
 2591  T\= + _,(T\= - _; T= - A,number(A)),
 2592  take_var_args(RT,TypeVars,RV).
 2593
 2594
 2595choose_rule(Theory,Rule):-
 2596  member(Rule,Theory).
 2597
 2598
 2599add_rule(Theory,add(rule(ID,H,[],true))):-
 2600  new_id(ID),
 2601  findall(HL , modeh(_,HL), HLS),
 2602  length(HLS,NH),
 2603  P is 1/(NH+1),
 2604  add_probs(HLS,H,P),
 2605  \+ member(rule(_,H,[],true),Theory).
 2606
 2607add_rule(Theory,TheoryGen):-
 2608  findall(HL , modeh(_,HL), HLS),
 2609  add_rule(HLS,Theory,TheoryGen).
 2610
 2611add_rule([X|_R],Theory,TheoryGen) :-
 2612  new_id(ID),
 2613  X =.. [P|A],
 2614  length(A,LA),
 2615  length(A1,LA),
 2616  PH =.. [P|A1],
 2617  TheoryGen = add(rule(ID,[PH:0.5,'':0.5],[],true)),
 2618  \+ member(rule(_,[PH:_,'':_],[],true),Theory).
 2619
 2620add_rule([_X|R],Theory,TheoryGen) :-
 2621  add_rule(R,Theory,TheoryGen).
 2622
 2623
 2624add_probs([],['':P],P):-!.
 2625
 2626add_probs([H|T],[H:P|T1],P):-
 2627  add_probs(T,T1,P).
 2628
 2629
 2630extract_fancy_vars(List,Vars):-
 2631  term_variables(List,Vars0),
 2632  fancy_vars(Vars0,1,Vars).
 2633
 2634
 2635fancy_vars([],_,[]).
 2636
 2637fancy_vars([X|R],N,[NN2=X|R1]):-
 2638  name(N,NN),
 2639  append([86],NN,NN1),
 2640  name(NN2,NN1),
 2641  N1 is N + 1,
 2642  fancy_vars(R,N1,R1).
 2643
 2644
 2645delete_one([X|R],R,X).
 2646
 2647delete_one([X|R],[X|R1],D):-
 2648  delete_one(R,R1,D).
 2649
 2650
 2651remove_last([_X],[]) :-
 2652  !.
 2653
 2654remove_last([X|R],[X|R1]):-
 2655  remove_last(R,R1).
 2656
 2657
 2658delete_matching([],_El,[]).
 2659
 2660delete_matching([El|T],El,T1):-!,
 2661  delete_matching(T,El,T1).
 2662
 2663delete_matching([H|T],El,[H|T1]):-
 2664  delete_matching(T,El,T1).
 2665
 2666
 2667%Computation of the depth of the variables in the clause's head/body
 2668dv(H,B,M,DV1):-			%DV1: returns a list of couples (Variable, Max depth)
 2669	term_variables(H,V),
 2670	head_depth(V,DV0),
 2671	findall((MD-DV),var_depth(B,M,DV0,DV,0,MD),LDs),
 2672        get_max(LDs,-1,-,DV1).
 2673
 2674
 2675input_variables_b(\+ LitM,M,InputVars):-!,
 2676	  LitM=..[P|Args],
 2677	  length(Args,LA),
 2678	  length(Args1,LA),
 2679	  Lit1=..[P|Args1],
 2680	  M:modeb(_,Lit1),
 2681	  all_plus(Lit1),
 2682	  input_vars(LitM,Lit1,InputVars).
 2683
 2684input_variables_b(LitM,M,InputVars):-
 2685	  LitM=..[P|Args],
 2686	  length(Args,LA),
 2687	  length(Args1,LA),
 2688	  Lit1=..[P|Args1],
 2689	  M:modeb(_,Lit1),
 2690	  input_vars(LitM,Lit1,InputVars).
 2691
 2692
 2693
 2694%associates depth 0 to each variable in the clause's head
 2695head_depth([],[]).
 2696head_depth([V|R],[[V,0]|R1]):-
 2697  head_depth(R,R1).
 2698
 2699%associates a depth to each variable in the clause's body
 2700var_depth([],_M,PrevDs1,PrevDs1,MD,MD):-!.
 2701
 2702var_depth([L|R],M,PrevDs,PrevDs1,_MD,MD):-    		%L = a body literal, MD = maximum depth set by the user
 2703  input_variables_b(L,M,InputVars),
 2704  term_variables(L, BodyAtomVars),
 2705  output_vars(BodyAtomVars,InputVars,OutputVars),
 2706  depth_InputVars(InputVars,PrevDs,0,MaxD),   		%MaxD: maximum depth of the input variables in the body literal
 2707  D is MaxD+1,
 2708  compute_depth(OutputVars,D,PrevDs,PrevDs0), 		%Computes the depth for the output variables in the body literal
 2709  var_depth(R,M,PrevDs0,PrevDs1,D,MD).
 2710
 2711get_max([],_,Ds,Ds).
 2712
 2713get_max([(MD-DsH)|T],MD0,_Ds0,Ds):-
 2714  MD>MD0,!,
 2715  get_max(T,MD,DsH,Ds).
 2716
 2717get_max([_H|T],MD,Ds0,Ds):-
 2718	get_max(T,MD,Ds0,Ds).
 2719
 2720delete_eq([],_E,[]).
 2721
 2722delete_eq([H|T],E,T1):-
 2723  H==E,!,
 2724  delete_eq(T,E,T1).
 2725
 2726delete_eq([H|T],E,[H|T1]):-
 2727  delete_eq(T,E,T1).
 2728
 2729output_vars(OutVars,[],OutVars):-!.
 2730output_vars(BodyAtomVars,[I|InputVars],OutVars):-
 2731  delete_eq(BodyAtomVars, I, Residue),
 2732  output_vars(Residue,InputVars, OutVars).
 2733
 2734% returns D as the maximum depth of the variables in the list (first argument)
 2735depth_InputVars([],_,D,D).
 2736depth_InputVars([I|Input],PrevDs,D0,D):-
 2737	 member_l(PrevDs,I,MD),
 2738	 (MD>D0->
 2739		D1=MD
 2740	;
 2741		D1=D0
 2742         ),
 2743	 depth_InputVars(Input,PrevDs,D1,D).
 2744
 2745member_l([[L,D]|_P],I,D):-
 2746     I==L,!.
 2747member_l([_|P],I,D):-
 2748     member_l(P,I,D).
 2749
 2750compute_depth([],_,PD,PD):-!.
 2751compute_depth([O|Output],D,PD,RestO):-
 2752	member_l(PD,O,_),!,
 2753	compute_depth(Output,D,PD,RestO).
 2754
 2755compute_depth([O|Output],D,PD,[[O,D]|RestO]):-
 2756	compute_depth(Output,D,PD,RestO).
 2757
 2758
 2759
 2760%checks if a variable's depth exceeds the setting_lift
 2761exceed_depth([],_):-!.
 2762exceed_depth([H|T],MD):-
 2763	nth1(2,H,Dep),
 2764	Dep<MD, %setting_lift(maxdepth_var,MD),
 2765	exceed_depth(T,MD).
 2766
 2767/*
 2768
 2769EMBLEM and SLIPCASE
 2770
 2771Copyright (c) 2011, Fabrizio Riguzzi and Elena Bellodi
 2772
 2773*/
 2774
 2775
 2776
 2777
 2778%:- yap_flag(single_var_warnings, on).
 2779
 2780
 2781load(FileIn,C1,R):-
 2782  open(FileIn,read,SI),
 2783  read_clauses_dir(SI,C),
 2784  close(SI),
 2785  process_clauses(C,[],C1,[],R).
 2786
 2787
 2788add_inter_cl(CL):-
 2789  %findall(A,(input(A);output(A)),L),
 2790  findall(A,(input(A)),L),
 2791  gen_cl(L,CL).
 2792
 2793
 2794gen_cl([],[]).
 2795
 2796gen_cl([H/A|T],[C|T1]):-
 2797  functor(F,H,A),
 2798  add_mod_arg(F,Module,F1),
 2799  add_bdd_arg(F,BDD,Module,F2),
 2800  C=(F2:-(F1,one(BDD))),
 2801  gen_cl(T,T1).
 2802
 2803
 2804assert_all([],_M,[]).
 2805
 2806assert_all([H|T],M,[HRef|TRef]):-
 2807  assertz(M:H,HRef),
 2808  assert_all(T,M,TRef).
 2809
 2810assert_all([],[]).
 2811
 2812assert_all([H|T],[HRef|TRef]):-
 2813  assertz(slipcover:H,HRef),
 2814  assert_all(T,TRef).
 2815
 2816
 2817retract_all([],_):-!.
 2818
 2819retract_all([H|T],M):-
 2820  erase(M,H),
 2821  retract_all(T,M).
 2822
 2823retract_all([]):-!.
 2824
 2825retract_all([H|T]):-
 2826  erase(H),
 2827  retract_all(T).
 2828
 2829
 2830read_clauses_dir(S,[Cl|Out]):-
 2831  read_term(S,Cl,[]),
 2832  (Cl=end_of_file->
 2833    Out=[]
 2834  ;
 2835    read_clauses_dir(S,Out)
 2836  ).
 2837
 2838
 2839process_clauses([],_M,[]):-!.
 2840
 2841process_clauses([end_of_file],_M,[]):-!.
 2842
 2843process_clauses([H|T],M,[H1|T1]):-
 2844  copy_term(H,H0),
 2845  term_expansion_int(H0,M,(_,[H1])),
 2846  process_clauses(T,M,T1).
 2847
 2848
 2849get_next_rule_number(M,R):-
 2850  retract(M:rule_lift_n(R)),
 2851  R1 is R+1,
 2852  assert(M:rule_lift_n(R1)).
 2853
 2854add_bdd_arg(A,Env,BDD,A1):-
 2855  A=..[P|Args],
 2856  append(Args,[Env,BDD],Args1),
 2857  A1=..[P|Args1].
 2858
 2859
 2860add_bdd_arg_db(A,Env,BDD,DB,A1):-
 2861  A=..[P|Args],
 2862  append(Args,[DB,Env,BDD],Args1),
 2863  A1=..[P|Args1].
 2864
 2865
 2866add_bdd_arg(A,_Env,_BDD,Module,A1):-
 2867  A=..[P|Args],
 2868  A1=..[P,Module|Args].
 2869
 2870
 2871add_bdd_arg_db(A,_Env,_BDD,DB,Module,A1):-
 2872  A=..[P|Args],
 2873  append(Args,[DB],Args1),
 2874  A1=..[P,Module|Args1].
 2875
 2876add_mod_arg(A,Module,A1):-
 2877  A=..[P|Args],
 2878  A1=..[P,Module|Args].
 2879
 2880
 2881generate_rules_fact([],_Env,_VC,_R,_Probs,_N,[],_Module).
 2882
 2883generate_rules_fact([Head:_P1,'':_P2],Env,VC,R,Probs,N,[Clause],Module):-!,
 2884  add_bdd_arg(Head,Env,BDD,Module,Head1),
 2885  Clause=(Head1:-(pita:get_var_n(Env,R,VC,Probs,V),pita:equality(Env,V,N,BDD))).
 2886
 2887generate_rules_fact([Head:_P|T],Env,VC,R,Probs,N,[Clause|Clauses],Module):-
 2888  add_bdd_arg(Head,Env,BDD,Module,Head1),
 2889  Clause=(Head1:-(pita:get_var_n(Env,R,VC,Probs,V),pita:equality(Env,V,N,BDD))),
 2890  N1 is N+1,
 2891  generate_rules_fact(T,Env,VC,R,Probs,N1,Clauses,Module).
 2892
 2893
 2894generate_rules_fact_db([],_Env,_VC,_R,_Probs,_N,[],_Module).
 2895
 2896generate_rules_fact_db([Head:_P1,'':_P2],Env,VC,R,Probs,N,[Clause],Module):-!,
 2897  add_bdd_arg_db(Head,Env,BDD,_DB,Module,Head1),
 2898  Clause=(Head1:-(pita:get_var_n(Env,R,VC,Probs,V),pita:equality(Env,V,N,BDD))).
 2899
 2900generate_rules_fact_db([Head:_P|T],Env,VC,R,Probs,N,[Clause|Clauses],Module):-
 2901  add_bdd_arg_db(Head,Env,BDD,_DB,Module,Head1),
 2902  Clause=(Head1:-(pita:get_var_n(Env,R,VC,Probs,V),pita:equality(Env,V,N,BDD))),
 2903  N1 is N+1,
 2904  generate_rules_fact_db(T,Env,VC,R,Probs,N1,Clauses,Module).
 2905
 2906
 2907generate_clause(Head,Env,Body,_VC,_R,_Probs,_BDDAnd,_N,Clause,Module):-
 2908  add_bdd_arg(Head,Env,_BDD,Module,Head1),
 2909  Clause=(Head1:-Body).
 2910
 2911
 2912generate_clause_db(Head,Env,Body,_VC,_R,_Probs,DB,_BDDAnd,_N,Clause,Module):-
 2913  add_bdd_arg_db(Head,Env,_BDD,DBH,Module,Head1),
 2914  Clause=(Head1:-(DBH>=1,DB is DBH-1,Body)).
 2915
 2916
 2917generate_rules([],_Env,_Body,_VC,_R,_Probs,_BDDAnd,_N,[],_Module).
 2918
 2919generate_rules([Head:_P1,'':_P2],Env,Body,VC,R,Probs,BDDAnd,N,[Clause],Module):-!,
 2920  generate_clause(Head,Env,Body,VC,R,Probs,BDDAnd,N,Clause,Module).
 2921
 2922generate_rules([Head:_P|T],Env,Body,VC,R,Probs,BDDAnd,N,[Clause|Clauses],Module):-
 2923  generate_clause(Head,Env,Body,VC,R,Probs,BDDAnd,N,Clause,Module),
 2924  N1 is N+1,
 2925  generate_rules(T,Env,Body,VC,R,Probs,BDDAnd,N1,Clauses,Module).
 2926
 2927
 2928generate_rules_db([],_Env,_Body,_VC,_R,_Probs,_DB,_BDDAnd,_N,[],_Module):-!.
 2929
 2930generate_rules_db([Head:_P1,'':_P2],Env,Body,VC,R,Probs,DB,BDDAnd,N,[Clause],Module):-!,
 2931  generate_clause_db(Head,Env,Body,VC,R,Probs,DB,BDDAnd,N,Clause,Module).
 2932
 2933generate_rules_db([Head:_P|T],Env,Body,VC,R,Probs,DB,BDDAnd,N,[Clause|Clauses],Module):-
 2934  generate_clause_db(Head,Env,Body,VC,R,Probs,DB,BDDAnd,N,Clause,Module),!,%agg.cut
 2935  N1 is N+1,
 2936  generate_rules_db(T,Env,Body,VC,R,Probs,DB,BDDAnd,N1,Clauses,Module).
 2937
 2938process_body_bg([],[],_Module).
 2939
 2940process_body_bg([\+ H|T],[\+ H|Rest],Module):-
 2941  builtin(H),!,
 2942  process_body_bg(T,Rest,Module).
 2943
 2944process_body_bg([\+ H|T],[\+ H1|Rest],Module):-!,
 2945  add_mod_arg(H,Module,H1),
 2946  process_body_bg(T,Rest,Module).
 2947
 2948process_body_bg([H|T],[H|Rest],Module):-
 2949  builtin(H),!,
 2950  process_body_bg(T,Rest,Module).
 2951
 2952process_body_bg([H|T],[H1|Rest],Module):-!,
 2953  add_mod_arg(H,Module,H1),
 2954  process_body_bg(T,Rest,Module).
 2955
 2956
 2957
 2958process_body([],BDD,BDD,Vars,Vars,[],_Env,_Module).
 2959
 2960process_body([\+ H|T],BDD,BDD1,Vars,Vars1,[\+ H|Rest],Env,Module):-
 2961  builtin(H),!,
 2962  process_body(T,BDD,BDD1,Vars,Vars1,Rest,Env,Module).
 2963
 2964process_body([\+ H|T],BDD,BDD1,Vars,Vars1,[
 2965(\+ H1)|Rest],Env,Module):-
 2966  add_mod_arg(H,Module,H1),
 2967  process_body(T,BDD,BDD1,Vars,Vars1,Rest,Env,Module).
 2968
 2969process_body([H|T],BDD,BDD1,Vars,Vars1,[H|Rest],Env,Module):-
 2970  builtin(H),!,
 2971  process_body(T,BDD,BDD1,Vars,Vars1,Rest,Env,Module).
 2972
 2973process_body([H|T],BDD,BDD1,Vars,Vars1,
 2974[H1|Rest],Env,Module):-
 2975  add_mod_arg(H,Module,H1),
 2976  process_body(T,BDD,BDD1,Vars,Vars1,Rest,Env,Module).
 2977
 2978process_body_db([],BDD,BDD,_DB,Vars,Vars,[],_Env,_Module):-!.
 2979
 2980process_body_db([\+ H|T],BDD,BDD1,DB,Vars,Vars1,[\+ H|Rest],Env,Module):-
 2981  builtin(H),!,
 2982  process_body_db(T,BDD,BDD1,DB,Vars,Vars1,Rest,Env,Module).
 2983
 2984process_body_db([\+ H|T],BDD,BDD1,DB,Vars,Vars1,[
 2985  (\+ H1)|Rest],Env,Module):-!,
 2986  add_mod_arg(H,Module,H1),
 2987  process_body_db(T,BDD,BDD1,DB,Vars,Vars1,Rest,Env,Module).
 2988
 2989process_body_db([H|T],BDD,BDD1,DB,Vars,Vars1,[H|Rest],Env,Module):-
 2990  builtin(H),!,
 2991  process_body_db(T,BDD,BDD1,DB,Vars,Vars1,Rest,Env,Module).
 2992
 2993process_body_db([H|T],BDD,BDD1,DB,Vars,Vars1,
 2994[H1|Rest],Env,Module):-
 2995  add_mod_arg(H,Module,H1),
 2996  process_body_db(T,BDD,BDD1,DB,Vars,Vars1,Rest,Env,Module).
 2997
 2998
 2999
 3000given(H):-
 3001  lift_input_mod(M),
 3002  functor(H,P,Ar),
 3003  (M:input(P/Ar)).
 3004
 3005
 3006given_cw(H):-
 3007  lift_input_mod(M),
 3008  functor(H,P,Ar),
 3009  (M:input_cw(P/Ar)).
 3010
 3011
 3012and_list([],B,B).
 3013
 3014and_list([H|T],B0,B1):-
 3015  and(B0,H,B2),
 3016  and_list(T,B2,B1).
 3017
 3018/*
 3019or_list([H],_Env,H):-!.
 3020
 3021or_list([H|T],Env,B):-
 3022  or_list1(T,Env,H,B).
 3023
 3024
 3025or_list1([],_Env,B,B).
 3026
 3027or_list1([H|T],Env,B0,B1):-
 3028  or(Env,B0,H,B2),
 3029  or_list1(T,Env,B2,B1).
 3030*/
 set_lift(:Parameter:atom, +Value:term) is det
The predicate sets the value of a parameter For a list of parameters see https://friguzzi.github.io/liftcover/ /
 3039set_lift(M:Parameter,Value):-
 3040  retract(M:local_setting(Parameter,_)),
 3041  assert(M:local_setting(Parameter,Value)).
 setting_lift(:Parameter:atom, -Value:term) is det
The predicate returns the value of a parameter For a list of parameters see https://friguzzi.github.io/liftcover/ /
 3050setting_lift(M:P,V):-
 3051  M:local_setting(P,V).
 3052
 3053
 3054difference([],_,[]).
 3055
 3056difference([H|T],L2,L3):-
 3057  member_eq(H,L2),!,
 3058  difference(T,L2,L3).
 3059
 3060difference([H|T],L2,[H|L3]):-
 3061  difference(T,L2,L3).
 3062
 3063
 3064member_eq(E,[H|_T]):-
 3065  E==H,!.
 3066
 3067member_eq(E,[_H|T]):-
 3068  member_eq(E,T).
 3069
 3070
 3071
 3072
 3073
 3074process_head(HeadList,M, GroundHeadList) :-
 3075  ground_prob(HeadList), !,
 3076  process_head_ground(HeadList,M, 0, GroundHeadList).
 3077
 3078process_head(HeadList,_M, HeadList).
 3079
 3080
 3081/* process_head_ground([Head:ProbHead], Prob, [Head:ProbHead|Null])
 3082 * ----------------------------------------------------------------
 3083 */
 3084process_head_ground([Head:ProbHead],M, Prob, [Head:ProbHead1|Null]) :-!,
 3085  ProbHead1 is ProbHead,
 3086  ProbLast is 1 - Prob - ProbHead1,
 3087  M:local_setting(epsilon_parsing, Eps),
 3088  EpsNeg is - Eps,
 3089  ProbLast > EpsNeg,
 3090  (ProbLast > Eps ->
 3091    Null = ['':ProbLast]
 3092  ;
 3093    Null = []
 3094  ).
 3095
 3096process_head_ground([Head:ProbHead|Tail], M, Prob, [Head:ProbHead1|Next]) :-
 3097  ProbHead1 is ProbHead,
 3098  ProbNext is Prob + ProbHead1,
 3099  process_head_ground(Tail, M, ProbNext, Next).
 3100
 3101
 3102ground_prob([]).
 3103
 3104ground_prob([_Head:ProbHead|Tail]) :-
 3105  ground(ProbHead), % Succeeds if there are no free variables in the term ProbHead.
 3106  ground_prob(Tail).
 3107
 3108get_probs([], []).
 3109
 3110get_probs([_H:P|T], [P1|T1]) :-
 3111  P1 is P,
 3112  get_probs(T, T1).
 3113
 3114
 3115
 3116
 3117generate_clauses([],_M,_N,[]):-!.
 3118
 3119generate_clauses([H|T],M,N,[(Head,BA,V,P)|C]):-
 3120  term_variables(H,V),
 3121  gen_clause(H,M,N,N1,rule(_,[_:P|_],_,_),[(Head:-BA)]),!,  %agg.cut
 3122  generate_clauses(T,M,N1,C).
 3123
 3124
 3125gen_clause((H :- Body),_M,N,N,(H :- Body),[(H :- Body)]):-!.
 3126
 3127
 3128
 3129gen_clause(rule(_R,HeadList,BodyList,Lit),_M,N,N1,
 3130  rule(N,HeadList,BodyList,Lit),Clauses):-!,
 3131% disjunctive clause with more than one head atom senza depth_bound
 3132  process_body(BodyList,_BDD,BDDAnd,[],_Vars,BodyList1,Env,Module),
 3133  list2and(BodyList1,Body1),
 3134  get_probs(HeadList,Probs),
 3135  generate_rules(HeadList,Env,Body1,[],N,Probs,BDDAnd,0,Clauses,Module),
 3136  N1 is N+1.
 3137
 3138gen_clause(def_rule(H,BodyList,Lit),_M,N,N,def_rule(H,BodyList,Lit),Clauses) :- !,%agg. cut
 3139% disjunctive clause with a single head atom senza depth_bound con prob =1
 3140  process_body(BodyList,_BDD,BDDAnd,[],_Vars,BodyList2,Env,Module),
 3141  list2and(BodyList2,Body1),
 3142  add_bdd_arg(H,Env,BDDAnd,Module,Head1),
 3143  Clauses=[(Head1 :- Body1)].
 3144
 3145
 3146generate_clauses_bg([],[]):-!.
 3147
 3148generate_clauses_bg([H|T],[CL|T1]):-
 3149  gen_clause_bg(H,CL),  %agg.cut
 3150  generate_clauses_bg(T,T1).
 3151
 3152gen_clause_bg(def_rule(H,BodyList,_Lit),Clauses) :-
 3153% disjunctive clause with a single head atom e depth_bound
 3154  process_body_bg(BodyList,BodyList2,Module),
 3155  list2and(BodyList2,Body1),
 3156  add_mod_arg(H,Module,Head1),
 3157  Clauses=(Head1 :- Body1).
 builtin(+Goal:atom) is det
Succeeds if Goal is an atom whose predicate is defined in Prolog (either builtin or defined in a standard library). /
 3166builtin(G):-
 3167  builtin_int(G),!.
 3168
 3169builtin_int(average(_L,_Av)).
 3170builtin_int(G):-
 3171  predicate_property(G,built_in).
 3172builtin_int(G):-
 3173  predicate_property(G,imported_from(lists)).
 3174builtin_int(G):-
 3175  predicate_property(G,imported_from(apply)).
 3176builtin_int(G):-
 3177  predicate_property(G,imported_from(nf_r)).
 3178builtin_int(G):-
 3179  predicate_property(G,imported_from(matrix)).
 3180builtin_int(G):-
 3181  predicate_property(G,imported_from(clpfd)).
 3182
 3183
 3184
 3185term_expansion_int((Head :- Body),M, (_Clauses,[rule(R,HeadList,BodyList,true)])) :-
 3186% disjunctive clause with a single head atom senza DB, con prob. diversa da 1
 3187  ((Head:-Body) \= ((user:term_expansion(_,_) ):- _ )),
 3188  (Head = ((_H:_);_);Head=(_H:_)), !,
 3189  list2or(HeadListOr, Head),
 3190  get_next_rule_number(M,R),
 3191  process_head(HeadListOr,M, HeadList),
 3192  list2and(BodyList, Body).
 3193
 3194
 3195term_expansion_int((Head :- Body),_M,(Clauses,[def_rule(Head,BodyList,true)])) :-
 3196% definite clause senza DB
 3197  ((Head:-Body) \= ((user:term_expansion(_,_)) :- _ )),!,
 3198  list2and(BodyList, Body),
 3199  process_body(BodyList,BDD,BDDAnd,[],_Vars,BodyList2,Env,Module),
 3200  append([pita:one(Env,BDD)],BodyList2,BodyList3),
 3201  list2and(BodyList3,Body2),
 3202  add_bdd_arg(Head,Env,BDDAnd,Module,Head1),
 3203  Clauses=(Head1 :- Body2).
 3204
 3205
 3206term_expansion_int(Head,M,(_,[rule(R,HeadList,[],true)])) :-
 3207% disjunctive fact with a single head atom e prob. generiche, senza db
 3208  (Head \= ((user:term_expansion(_,_)) :- _ )),
 3209  Head=(_H:_), !,
 3210  list2or(HeadListOr, Head),
 3211  process_head(HeadListOr,M, HeadList),
 3212  get_next_rule_number(M,R).
 3213
 3214term_expansion_int(Head, _M,((Head1:-pita:one(Env,One)),[def_rule(Head,[],true)])) :-
 3215% definite fact without db
 3216  (Head \= ((user:term_expansion(_,_) ):- _ )),
 3217  (Head\= end_of_file),!,
 3218  add_bdd_arg(Head,Env,One,_Module,Head1).
 3219
 3220
 3221test_no_area(TestSet,M,Prog,NPos,NNeg,LL,Results):-
 3222%  S= user_output,
 3223%  SA= user_output,
 3224%  format(SA,"Fold;\tCLL;\t AUCROC;\t AUCPR~n",[]),
 3225  %gtrace,
 3226  test_folds(TestSet,M,Prog,Results,NPos,NNeg,LL).
 3227
 3228
 3229/*
 3230  ROC = c3{data:_{x:x, rows:[x-'ROC'|ROC0]},
 3231    axis:_{x:_{min:0.0,max:1.0,padding:0.0,
 3232        tick:_{values:[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}},
 3233           y:_{min:0.0,max:1.0,padding:_{bottom:0.0,top:0.0},
 3234        tick:_{values:[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}}}},
 3235  PR = c3{data:_{x:x, rows:[x-'PR'|PR0]},
 3236    axis:_{x:_{min:0.0,max:1.0,padding:0.0,
 3237        tick:_{values:[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}},
 3238           y:_{min:0.0,max:1.0,padding:_{bottom:0.0,top:0.0},
 3239        tick:_{values:[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}}}}.
 3240*/
 3241test_folds(F,M,Prog,LG,NPos,NNeg,LL):-
 3242  find_ex(F,M,Pos,Neg,NPos,NNeg),
 3243  M:local_setting(threads,Th),
 3244  current_prolog_flag(cpu_count,Cores),
 3245  ((Th=cpu;Th>Cores)->
 3246    Chunks = Cores
 3247  ;
 3248    Chunks = Th
 3249  ),
 3250  chunks(Pos,Chunks,PosC),
 3251  chunks(Neg,Chunks,NegC),
 3252  concurrent_maplist(compute_prob_ex_pos_list(Prog,M),PosC,LGP),
 3253  append(LGP,LG0),
 3254  concurrent_maplist(compute_prob_ex_neg_list(Prog,M),NegC,LGN),
 3255  append(LGN,LG1),
 3256  append(LG0,LG1,LG2),
 3257  keysort(LG2,LG),
 3258  foldl(ll(M),LG,0,LL).
 3259
 3260compute_prob_ex_pos_list(Prog,M,Pos,LGP):-
 3261  maplist(compute_prob_ex_pos(Prog,M),Pos,LGP).
 3262
 3263compute_prob_ex_neg_list(Prog,M,Neg,LGN):-
 3264  maplist(compute_prob_ex_neg(Prog,M),Neg,LGN).
 3265
 3266ll(M,P- (\+ _),LL0,LL):-!,
 3267  (P=:=1.0->
 3268    M:local_setting(logzero,LZ),
 3269    LL is LL0+LZ
 3270  ;
 3271    LL is LL0+ log(1-P)
 3272  ).
 3273
 3274ll(M,P- _,LL0,LL):-
 3275  (P=:=0.0->
 3276    M:local_setting(logzero,LZ),
 3277    LL is LL0+LZ
 3278  ;
 3279    LL is LL0+ log(P)
 3280  ).
 3281 
 3282
 3283
 3284
 3285
 3286find_ex(DB,M,Pos,Neg,NPos,NNeg):-
 3287  M:local_setting(neg_ex,given),!,
 3288  M:output(P/A),!,
 3289  find_ex_pred([P/A],M,DB,[],Pos,[],Neg),
 3290  length(Pos,NPos),
 3291  length(Neg,NNeg).
 3292
 3293find_ex(DB,M,Pos,Neg,NPos,NNeg):-
 3294  M:local_setting(neg_ex,cw),
 3295  M:output(P/A),!,
 3296  find_ex_pred_cw([P/A],M,DB,[],Pos,[],Neg),
 3297  length(Pos,NPos),
 3298  length(Neg,NNeg).
 3299
 3300
 3301find_ex_pred([],_M,_DB,Pos,Pos,Neg,Neg).
 3302
 3303find_ex_pred([P/A|T],M,DB,Pos0,Pos,Neg0,Neg):-
 3304  functor(At,P,A),
 3305  find_ex_db(DB,M,At,Pos0,Pos1,Neg0,Neg1),
 3306  find_ex_pred(T,M,DB,Pos1,Pos,Neg1,Neg).
 3307
 3308find_ex_db([],_M,_At,Pos,Pos,Neg,Neg).
 3309
 3310find_ex_db([H|T],M,At,Pos0,Pos,Neg0,Neg):-
 3311  At=..[P|L],
 3312  At1=..[P,H|L],
 3313  findall(At1,M:At1,LP),
 3314  findall(At1,M:neg(At1),LN),
 3315  append([Pos0,LP],Pos1),
 3316  append([Neg0,LN],Neg1),
 3317  find_ex_db(T,M,At,Pos1,Pos,Neg1,Neg).
 3318
 3319
 3320find_ex_pred_cw([],_M,_DB,Pos,Pos,Neg,Neg).
 3321
 3322find_ex_pred_cw([P/A|T],M,DB,Pos0,Pos,Neg0,Neg):-
 3323  functor(At,P,A),
 3324  findall(Types,get_types(At,M,Types),LT),
 3325  append(LT,LLT),
 3326  remove_duplicates(LLT,Types1),
 3327  find_ex_db_cw(DB,M,At,Types1,Pos0,Pos1,Neg0,Neg1),
 3328  find_ex_pred_cw(T,M,DB,Pos1,Pos,Neg1,Neg).
 3329
 3330get_types(At,_M,[]):-
 3331  At=..[_],!.
 3332
 3333get_types(At,M,Types):-
 3334  M:modeh(_,At),
 3335  At=..[_|Args],
 3336  get_args(Args,Types).
 3337
 3338get_types(At,M,Types):-
 3339  M:modeh(_,HT,_,_),
 3340  member(At,HT),
 3341  At=..[_|Args],
 3342  get_args(Args,Types).
 3343
 3344
 3345get_args([],[]).
 3346
 3347get_args([+H|T],[H|T1]):-!,
 3348  get_args(T,T1).
 3349
 3350get_args([-H|T],[H|T1]):-!,
 3351  get_args(T,T1).
 3352
 3353get_args([#H|T],[H|T1]):-!,
 3354  get_args(T,T1).
 3355
 3356get_args([-#H|T],[H|T1]):-!,
 3357  get_args(T,T1).
 3358
 3359get_args([H|T],[H|T1]):-
 3360  get_args(T,T1).
 3361
 3362
 3363
 3364
 3365get_constants([],_Mod,_M,[]).
 3366
 3367get_constants([Type|T],Mod,M,[(Type,Co)|C]):-
 3368  find_pred_using_type(Type,Mod,LP),
 3369  find_constants(LP,Mod,M,[],Co),
 3370  get_constants(T,Mod,M,C).
 3371
 3372find_pred_using_type(T,M,L):-
 3373  (setof((P,Ar,A),pred_type(T,M,P,Ar,A),L)->
 3374    true
 3375  ;
 3376    L=[]
 3377  ).
 3378
 3379pred_type(T,M,P,Ar,A):-
 3380  M:modeh(_,S),
 3381  S=..[P|Args],
 3382  length(Args,Ar),
 3383  scan_args(Args,T,1,A).
 3384
 3385pred_type(T,M,P,Ar,A):-
 3386  M:modeb(_,S),
 3387  S=..[P|Args],
 3388  length(Args,Ar),
 3389  scan_args(Args,T,1,A).
 3390
 3391scan_args([+T|_],T,A,A):-!.
 3392
 3393scan_args([-T|_],T,A,A):-!.
 3394
 3395scan_args([#T|_],T,A,A):-!.
 3396
 3397scan_args([-#T|_],T,A,A):-!.
 3398
 3399scan_args([_|Tail],T,A0,A):-
 3400  A1 is A0+1,
 3401  scan_args(Tail,T,A1,A).
 3402
 3403find_constants([],_Mod,_M,C,C).
 3404
 3405find_constants([(P,Ar,A)|T],Mod,M,C0,C):-
 3406  gen_goal(1,Ar,A,Args,ArgsNoV,V),
 3407  G=..[P,M|Args],
 3408  (setof(V,ArgsNoV^call_goal(Mod,G),LC)->
 3409    true
 3410  ;
 3411    LC=[]
 3412  ),
 3413  append(C0,LC,C1),
 3414  remove_duplicates(C1,C2),
 3415  find_constants(T,Mod,M,C2,C).
 3416
 3417call_goal(M,G):-
 3418  M:G.
 3419
 3420gen_goal(Arg,Ar,_A,[],[],_):-
 3421  Arg =:= Ar+1,!.
 3422
 3423gen_goal(A,Ar,A,[V|Args],ArgsNoV,V):-!,
 3424  Arg1 is A+1,
 3425  gen_goal(Arg1,Ar,A,Args,ArgsNoV,V).
 3426
 3427gen_goal(Arg,Ar,A,[ArgV|Args],[ArgV|ArgsNoV],V):-
 3428  Arg1 is Arg+1,
 3429  gen_goal(Arg1,Ar,A,Args,ArgsNoV,V).
 3430
 3431
 3432
 3433find_ex_db_cw([],_M,_At,_Ty,Pos,Pos,Neg,Neg).
 3434
 3435find_ex_db_cw([H|T],M,At,Types,Pos0,Pos,Neg0,Neg):-
 3436  get_constants(Types,M,H,C),
 3437  At=..[P|L],
 3438  get_types(At,M,TypesA),!,
 3439  length(L,N),
 3440  length(LN,N),
 3441  At1=..[P,H|LN],
 3442  findall(At1,M:At1,LP),
 3443  (setof(At1,neg_ex(LN,TypesA,M,At1,C),LNeg)->true;LNeg=[]),
 3444  append([Pos0,LP],Pos1),
 3445  append([Neg0,LNeg],Neg1),
 3446  find_ex_db_cw(T,M,At,Types,Pos1,Pos,Neg1,Neg).
 3447
 3448neg_ex([],[],M,At1,_C):-
 3449  \+ M:At1.
 3450
 3451neg_ex([H|T],[HT|TT],M,At1,C):-
 3452  member((HT,Co),C),
 3453  member(H,Co),
 3454  neg_ex(T,TT,M,At1,C).
 explain_lift(:At:atom, -Exp:list) is multi
The predicate returns the explanation of atom At given by the input program. The first argument of At should be the model name. The explanation is a list of pairs (P-Ex) where P is the probability in the head of a rule H:P:-B and Ex is a true grounding of B. /
 3466explain_lift(M:H,Expl):-
 3467  M:in(R00),
 3468  explain_lift(M:H,R00,Expl).
 explain_lift(:At:atom, +Program:probabilistic_program, -Exp:list) is multi
The predicate returns the explanation of atom At given by Program. /
 3475explain_lift(M:H,R00,Expl):-
 3476  process_clauses(R00,M,R0),
 3477  generate_clauses(R0,M,0,Prog),
 3478  maplist(explain_rule(M,H),Prog,Expls),
 3479  append(Expls,Expl).
 3480
 3481
 3482explain_rule(M,H,(H,B,_V,P),Expl):-!,
 3483  findall((P-B),M:B,Expl).
 3484
 3485explain_rule(_,_,_,[]).
 hits_at_k(:Folds:list_of_atoms, +TargetPred:predicate, +Arg:int, +K:int, -HitsAtK:float, -FilteredHitsAtK:float) is det
Returns the Hits@K and filtered Hits@K of the target predicate TargetPred on the list of folds Folds for the argument in position Arg. /
 3492hits_at_k(M:Folds,TargetPred,Arg,K,HitsAtK,FilteredHitsAtK):-
 3493  M:in(P),
 3494  hits_at_k(M:Folds,TargetPred,Arg,K,P,HitsAtK,FilteredHitsAtK).
 hits_at_k(:Folds:list_of_atoms, +TargetPred:predicate, +Arg:int, +Prog:probabilistic_program, +K:int, -Hits:float, -FilteredHits:float) is det
Returns the Hits@K and filtered Hits@K of the target predicate TargetPred on the list of folds Folds for the argument in position Arg computed over Prog. /
 3502hits_at_k(M:Folds,TargetPred,Arg,K,R00,HitsAtK,FilteredHitsAtK):-
 3503  process_clauses(R00,M,R0),
 3504  generate_clauses(R0,M,0,Prog),
 3505  findall(IDs,(member(F,Folds),M:fold(F,IDs)),L),
 3506  append(L,DB),
 3507  find_ex_pred([TargetPred],M,DB,[],Exs,[],_),
 3508  M:local_setting(threads,Th),
 3509  current_prolog_flag(cpu_count,Cores),
 3510  ((Th=cpu;Th>Cores)->
 3511    Chunks = Cores
 3512  ;
 3513    Chunks = Th
 3514  ),
 3515  chunks(Exs,Chunks,ExsC),
 3516  Arg1 is Arg+1,
 3517  concurrent_maplist(hits(Prog,M,Arg1,K),ExsC,LHits0,LFHits0),
 3518  append(LHits0,LHits),
 3519  average(LHits,HitsAtK),
 3520  append(LFHits0,LFHits),
 3521  average(LFHits,FilteredHitsAtK).
 3522
 3523hits(Prog,M,Arg,K,Exs,Hits,FilteredHits):-
 3524  maplist(hit(Prog,M,Arg,K),Exs,Hits,FilteredHits).
 3525
 3526hit(Prog,M,Arg,K,Ex,Hit,FilteredHit):-
 3527  arg(Arg,Ex,Ent),
 3528  rank_answer_int(Ex,M,Arg,Prog,Rank,FRank),
 3529  write_canonical(rank(Ex,Ent,Rank,FRank)),nl,
 3530  (Rank=<K->
 3531    Hit = 1.0
 3532  ;
 3533    Hit = 0.0
 3534  ),
 3535  (FRank=<K->
 3536    FilteredHit = 1.0
 3537  ;
 3538    FilteredHit = 0.0
 3539  ).
 inst_exs(:Folds:list, +TargetPred:PredSpec, +Arg:int, +ProbabilisticProgram:list_of_probabilistic_clauses) is det
The predicate prints the list of answers for all the triples in Folds for predicate TaragetPredwhere argument in position Arg has been replaced by a variable. /
 3547inst_exs(M:Folds,TargetPred,Arg,R00):-
 3548  process_clauses(R00,M,R0),
 3549  generate_clauses(R0,M,0,Prog),
 3550  findall(IDs,(member(F,Folds),M:fold(F,IDs)),L),
 3551  append(L,DB),
 3552  find_ex_pred([TargetPred],M,DB,[],Exs,[],_),
 3553  M:local_setting(threads,Th),
 3554  current_prolog_flag(cpu_count,Cores),
 3555  ((Th=cpu;Th>Cores)->
 3556    Chunks = Cores
 3557  ;
 3558    Chunks = Th
 3559  ),
 3560  chunks(Exs,Chunks,ExsC),
 3561  Arg1 is Arg+1,
 3562  concurrent_maplist(inst_list(Prog,M,Arg1),ExsC).
 3563
 3564inst_list(Prog,M,Arg,Exs):-
 3565  maplist(inst_ex(Prog,M,Arg),Exs).
 3566
 3567inst_ex(Prog,M,Arg,Ex):-
 3568  arg(Arg,Ex,Ent),
 3569  setarg(Arg,Ex,_Var),
 3570  find_instantions(Ex,Prog,M,Inst),
 3571  maplist(extract_arg(Arg),Inst,InstV),
 3572  write_canonical(inst(Ex,Ent,InstV)),writeln('.').
 3573
 3574extract_arg(Arg,G,V):-
 3575  arg(Arg,G,V).
 rank_exs(:Folds:list, +TargetPred:PredSpec, +Arg:int, +ProbabilisticProgram:list_of_probabilistic_clauses) is det
The predicate prints the list of answers for all the triples in Folds for predicate TaragetPredwhere argument in position Arg has been replaced by a variable. /
 3583rank_exs(M:Folds,TargetPred,Arg,R00):-
 3584  process_clauses(R00,M,R0),
 3585  generate_clauses(R0,M,0,Prog),
 3586  findall(IDs,(member(F,Folds),M:fold(F,IDs)),L),
 3587  append(L,DB),
 3588  find_ex_pred([TargetPred],M,DB,[],Exs,[],_),
 3589  M:local_setting(threads,Th),
 3590  current_prolog_flag(cpu_count,Cores),
 3591  ((Th=cpu;Th>Cores)->
 3592    Chunks = Cores
 3593  ;
 3594    Chunks = Th
 3595  ),
 3596  chunks(Exs,Chunks,ExsC),
 3597  Arg1 is Arg+1,
 3598  concurrent_maplist(rank_list(Prog,M,Arg1),ExsC).
 3599
 3600rank_list(Prog,M,Arg,Exs):-
 3601  maplist(rank_ex(Prog,M,Arg),Exs).
 rank_ex(:At:atom, +ProbabilisticProgram:list_of_probabilistic_clauses, +Arg:int) is det
The predicate prints the list of answers for the query At where argument in position Arg has been replaced by a variable. The first argument of At should be the model name. /
 3609rank_ex(M:Ex,R00,Arg):-
 3610  process_clauses(R00,M,R0),
 3611  generate_clauses(R0,M,0,Prog),
 3612  rank_ex(Prog,M,Arg,Ex).
 3613
 3614rank_ex(Prog,M,Arg,Ex):-
 3615  arg(Arg,Ex,Ent),
 3616  setarg(Arg,Ex,_Var),
 3617  find_instantions(Ex,Prog,M,Inst),
 3618  maplist(compute_prob(Prog,M,Arg),Inst,Answers),
 3619  sort(0,@>=,Answers,RankedAnswers),
 3620  write_canonical(rank(Ex,Ent,RankedAnswers)),writeln('.').
 3621
 3622compute_prob(Prog,M,Arg,G,(P-V)):-
 3623  prob_lift_int(G,M,Prog,P),
 3624  arg(Arg,G,V).
 3625
 3626find_instantions(Ex,Prog,M,Inst):-
 3627  setof(Ex,Prog^find_inst(Prog,M,Ex),Inst),!.
 3628
 3629find_instantions(_Ex,_Prog,_M,[]).
 3630
 3631find_inst(Prog,M,Ex):-
 3632  member((H,B,_V,_P),Prog),
 3633  H=Ex,M:B.
 3634
 3635average(L,Average):-
 3636  sum_list(L,Sum),
 3637  length(L,N),
 3638  (N>0->
 3639    Average is Sum/N
 3640  ;
 3641    Average is 0.0
 3642  ).
 rank_answer(:At:atom, +Arg:integer, -Rank:float) is det
The predicate returns the rank of the constant in argument Arg of At in the list of answers for the query At. /
 3649rank_answer(M:H,Arg,Rank):-
 3650  M:in(R00),
 3651  rank_answer(M:H,Arg,R00,Rank).
 rank_answer(:At:atom, +Arg:integer, +Prog:probabilistic_program, -Rank:float) is det
The predicate returns the rank of the constant in argument Arg of At in the list of answers for the query At asked using the program Prog. /
 3659rank_answer(M:H,Arg,Prog,Rank):-
 3660  arg(Arg,H,A),
 3661  setarg(Arg,H,Var),
 3662  ranked_answers(M:H,Var,Prog,RankedAnswers),
 3663  rank(A,RankedAnswers,Rank).
 3664
 3665rank_answer_int(H,M,Arg,Prog,Rank,FRank):-
 3666  arg(Arg,H,A),
 3667  setarg(Arg,H,Var),
 3668  ranked_answers_int(H,M,Var,Prog,RankedAnswers),
 3669  rank(A,RankedAnswers,Rank),
 3670  filter(RankedAnswers,FilteredRankedAnswers,H,Var),
 3671  rank(A,FilteredRankedAnswers,FRank).
 3672
 3673filter([],[],_H,_Var).
 3674
 3675filter([P-A|T],[P-A|T1],H,V):-
 3676  copy_term((H,V),(H1,V1)),
 3677  H1=..[_|Args],
 3678  H2=..[t|Args],
 3679  V1=A,
 3680  (H1;H2),!,
 3681  filter(T,T1,H,V).
 3682
 3683filter([_P-_A|T],T1,H,V):-
 3684  filter(T,T1,H,V).
 ranked_answers(:At:atom, +Var:var, -RankedAnswers:list) is multi
The predicate returns a list of answers for the query At. Var should be a variable in At. RankedAnswers is a list of pairs (P-A) where P is the probability of the answer At{Var/A}. The list is sorted in decreasing order of probability. The first argument of At should be the model name. The query is asked to the input program. /
 3695ranked_answers(M:H,Var,RankedNaswers):-
 3696  M:in(P),
 3697  ranked_answers(M:H,Var,P,RankedNaswers).
 ranked_answers(:At:atom, +Var:var, +Prog:probabilistic_program, -RankedAnswers:list) is multi
As ranked_answers/3 but the query is asked to the program Prog. /
 3705ranked_answers(M:H,Var,Prog,RankedNaswers):-
 3706  findall((P-Var),prob_lift(M:H,Prog,P),Answers),
 3707  sort(0,@>=,Answers,RankedNaswers).
 3708
 3709ranked_answers_int(H,M,Var,Prog,RankedNaswers):-
 3710  findall((P-Var),prob_lift_int(H,M,Prog,P),Answers),
 3711  sort(0,@>=,Answers,RankedNaswers).
 rank(:Element:term, +OrderedList:list, -Rank:float) is det
The predicate returns the rank of Element in the list OrderedList. Group of records with the same value are assigned the average of the ranks. OrderedList is a list of pairs (S - E) where S is the score and E is the element.

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rank.html /

 3722rank(E,L,R):-
 3723    rank_group(L,E,+inf,0.0,1.0,R).
 rank_group(+OrderedList:list, :Element:term, +CurrentScore:float, +LengthOfCurrentGroup:float, +CurrentPosition:float, -Rank:float) is det
CurrentScore is the score of the current group. LengthOfCurrentGroup is the number of elements in the current group. CurrentPosition is the position of the first element in the list. /
 3731rank_group([],_E,_S,_NG,_N,+inf).
 3732
 3733rank_group([(S1 - E1)|T],E,S,NG,N,R):-
 3734  N1 is N+1.0,
 3735  (E1==E->
 3736    (S1<S->
 3737      rank_group_found(T,S1,1.0,N1,R)
 3738    ;
 3739      NG1 is NG+1.0,
 3740      rank_group_found(T,S1,NG1,N1,R)
 3741    )
 3742  ;
 3743    (S1<S->
 3744      rank_group(T,E,S1,1.0,N1,R)
 3745    ;
 3746      NG1 is NG+1.0,
 3747      rank_group(T,E,S1,NG1,N1,R)
 3748    )
 3749  ).
 rank_group_found(+OrderedList:list, +CurrentScore:float, +LengthOfCurrentGroup:float, +CurrentPosition:float, -Rank:float) is det
CurrentScore is the score of the current group. LengthOfCurrentGroup is the number of elements in the current group. CurrentPosition is the position of the first element in the list. The group contains the element to be ranked. /
 3757rank_group_found([],_S,NG,N,R):-
 3758  R is N-(NG+1.0)/2.
 3759
 3760rank_group_found([(S1 - _E1)|T],S,NG,N,R):-
 3761  (S1<S->
 3762    R is N-(NG+1.0)/2
 3763  ;
 3764    N1 is N+1.0,
 3765    NG1 is NG+1.0,
 3766    rank_group_found(T,S1,NG1,N1,R)
 3767  ).
 prob_lift(:At:atom, -P:float) is multi
The predicate computes the probability of atom At given by the input program. The first argument of At should be the model name. If At contains variables, the predicate returns all the instantiaions of At with their probabilities in backtracking. /
 3782prob_lift(M:H,P):-
 3783  M:in(R00),
 3784  prob_lift(M:H,R00,P).
 prob_lift(:At:atom, +Program:probabilistic_program, -P:float) is multi
The predicate computes the probability of atom At given by Program. The first argument of At should be the model name. If At contains variables, the predicate returns all the instantiaions of At with their probabilities in backtracking. /
 3794prob_lift(M:H,R00,P):-
 3795  process_clauses(R00,M,R0),
 3796  generate_clauses(R0,M,0,Prog),
 3797  prob_lift_int(H,M,Prog,P).
 3798
 3799prob_lift_int(H,M,Prog,P):-
 3800  (M:local_setting(single_var,true)->
 3801    theory_counts_sv(Prog,M,H,MI)
 3802  ;
 3803    theory_counts(Prog,M,H,MI)
 3804  ),
 3805  compute_prob_ex(Prog,MI,1,PG0),
 3806  P is 1-PG0.
 3807
 3808theory_counts([],_M,_H,[]).
 3809
 3810theory_counts([(H,B,_V,_P)|Rest],M,E,[MI|RestMI]):-
 3811  test_rule(H,B,M,E,MI),
 3812  theory_counts(Rest,M,E,RestMI).
 3813
 3814
 3815test_rule(H,B,M,E,N):-
 3816 findall(1,(H=E,M:B),L),
 3817 length(L,N).
 3818/*
 3819  term_variables(B,Vars),
 3820  term_variables(H,V),
 3821  subtract_eq(Vars,V,VB),
 3822  aggregate(count,VB^(H=E,M:B),N),!.
 3823 
 3824
 3825test_rule(_H,_B,_M,_E,0).
 3826*/
 3827theory_counts_sv([],_M,_H,[]).
 3828
 3829theory_counts_sv([(H,B,_V,_P)|Rest],M,E,[MI|RestMI]):-
 3830  copy_term((H,B),(H1,B1)),
 3831  test_rule_sv(H1,B1,M,E,MI),
 3832  theory_counts_sv(Rest,M,E,RestMI).
 3833
 3834test_rule_sv(H,B,M,E,N):-
 3835  H=E,M:B,!,
 3836  N=1.
 3837
 3838test_rule_sv(_H,_B,_M,_E,0).
 3839/*    term_variables(B,Vars),
 3840    term_variables(H,V),
 3841    subtract_eq(Vars,V,VB),
 3842    \+ aggregate(count,VB^(H=E,M:B),_),
 3843    %  (H=E,M:(\+ B);H\=E),*/
 3844    % N=0.
 3845 
 3846subtract_eq([], _, R) =>
 3847  R = [].
 3848subtract_eq([E|T], D, R) =>
 3849  (   member_eq(E, D)
 3850  ->  subtract_eq(T, D, R)
 3851  ;   R = [E|R1],
 3852      subtract_eq(T, D, R1)
 3853  ).
 3854
 3855
 3856compute_prob_ex_neg(Prog,M,H,PG- (\+ H)):-
 3857  length(Prog,N),
 3858  gen_initial_counts(N,MI0),
 3859  test_theory_neg_prob([H],M,Prog,MI0,MI),
 3860  compute_prob_ex(Prog,MI,1,PG0),
 3861  PG is 1-PG0.
 3862
 3863compute_prob_ex_pos(Prog,M,H,PG- H):-
 3864  length(Prog,N),
 3865  gen_initial_counts(N,MI0),
 3866  test_theory_neg_prob([H],M,Prog,MI0,MI),
 3867  compute_prob_ex(Prog,MI,1,PG0),
 3868  PG is 1-PG0.
 3869
 3870compute_prob_ex([],[],PG,PG).
 3871
 3872compute_prob_ex([(_,_,_,P)|R],[MIH|MIT],PG0,PG):-
 3873  PG1 is PG0*(1-P)^MIH,
 3874  compute_prob_ex(R,MIT,PG1,PG).
 3875
 3876writes([H-H1],S):-
 3877  format(S,"~f - (~q)]).~n~n",[H,H1]).
 3878
 3879writes([H-H1|T],S):-
 3880  format(S,"~f - (~q),~n",[H,H1]),
 3881  writes(T,S).
 3882
 3883
 3884write_p(P,S):-
 3885  get_xy(P,PX,PY),
 3886  format(S,"x=[",[]),
 3887  writesf(PX,S),
 3888  format(S,"y=[",[]),
 3889  writesf(PY,S),
 3890  format(S,"
 3891figure('Name','roc','NumberTitle','off')
 3892set(gca,'XLim',[0.0 1.0])
 3893set(gca,'YLim',[0.0 1.0])
 3894x=[x 1.0]
 3895y=[y 0.0]
 3896k=convhull(x,y)
 3897plot(x(k),y(k),'r-',x,y,'--b+')
 3898%A = polyarea(x,y)~n~n
 3899%save area_roc.csv  A -ascii -append
 3900",
 3901  []).
 3902
 3903get_xy([],[],[]).
 3904
 3905get_xy([X-Y|T],[X|TX],[Y|TY]):-
 3906  get_xy(T,TX,TY).
 3907
 3908
 3909writesf([H],S):-
 3910  format(S,"~f]~n",[H]).
 3911
 3912writesf([H|T],S):-
 3913  format(S,"~f ",[H]),
 3914  writesf(T,S).
 3915
 3916write_ppr(P,S):-
 3917  get_xy(P,PX,PY),
 3918  format(S,"rec=[",[A]),
 3919  writesf(PX,S),
 3920  format(S,"prec=[",[A]),
 3921  writesf(PY,S),
 3922  format(S,"
 3923figure('Name','pr','NumberTitle','off')
 3924set(gca,'XLim',[0.0 1.0])
 3925set(gca,'YLim',[0.0 1.0])
 3926rec=[0.0  rec 1.0];
 3927prec=[0.0 prec 0.0];
 3928plot(rec,prec,'--*k')
 3929%A=polyarea(rec,prec)
 3930%save area_pr.csv  A -ascii -append
 3931~n~n",
 3932  []).
 write2(+Module:atom, +Message:term) is det
The predicate calls write(Message) if the verbosity is at least 2. Module is used to get the verbosity setting /
 3940write2(M,A):-
 3941  M:local_setting(verbosity,Ver),
 3942  (Ver>1->
 3943    write(A)
 3944  ;
 3945    true
 3946  ).
 write3(+Module:atom, +Message:term) is det
The predicate calls write(Message) if the verbosity is at least 3. Module is used to get the verbosity setting. /
 3953write3(M,A):-
 3954  M:local_setting(verbosity,Ver),
 3955  (Ver>2->
 3956    write(A)
 3957  ;
 3958    true
 3959  ).
 write4(+Module:atom, +Message:term) is det
The predicate calls write(Message) if the verbosity is at least 4. Module is used to get the verbosity setting. /
 3967write4(M,A):-
 3968  M:local_setting(verbosity,Ver),
 3969  (Ver>3->
 3970    write(A)
 3971  ;
 3972    true
 3973  ).
 nl2(+Module:atom) is det
The predicate prints a newline if the verbosity is at least 2. Module is used to get the verbosity setting. /
 3980nl2(M):-
 3981  M:local_setting(verbosity,Ver),
 3982  (Ver>1->
 3983    nl
 3984  ;
 3985    true
 3986  ).
 nl3(+Module:atom) is det
The predicate prints a newline if the verbosity is at least 3. Module is used to get the verbosity setting. /
 3993nl3(M):-
 3994  M:local_setting(verbosity,Ver),
 3995  (Ver>2->
 3996    nl
 3997  ;
 3998    true
 3999  ).
 nl4(+Module:atom) is det
The predicate prints a newline if the verbosity is at least 4. Module is used to get the verbosity setting. /
 4007nl4(M):-
 4008  M:local_setting(verbosity,Ver),
 4009  (Ver>3->
 4010    nl
 4011  ;
 4012    true
 4013  ).
 format2(+Module:atom, +Format, :Arguments) is det
The predicate calls format(Format,Arguments) if the verbosity is at least 2. Module is used to get the verbosity setting. /
 4020format2(M,A,B):-
 4021  M:local_setting(verbosity,Ver),
 4022  (Ver>1->
 4023    format(A,B)
 4024  ;
 4025    true
 4026  ).
 format3(+Module:atom, +Format, :Arguments) is det
The predicate calls format(Format,Arguments) if the verbosity is at least 3. Module is used to get the verbosity setting. /
 4033format3(M,A,B):-
 4034  M:local_setting(verbosity,Ver),
 4035  (Ver>2->
 4036    format(A,B)
 4037  ;
 4038    true
 4039  ).
 format4(+Module:atom, +Format, :Arguments) is det
The predicate calls format(Format,Arguments) if the verbosity is at least 4. Module is used to get the verbosity setting. /
 4046format4(M,A,B):-
 4047  M:local_setting(verbosity,Ver),
 4048  (Ver>3->
 4049    format(A,B)
 4050  ;
 4051    true
 4052  ).
 write_rules2(+Module:atom, +Rules:list, +Stream:atom) is det
The predicate write the rules in Rules on stream Stream if the verbosity is at least 2. Module is used to get the verbosity setting. /
 4059write_rules2(M,A,B):-
 4060  M:local_setting(verbosity,Ver),
 4061  (Ver>1->
 4062    write_rules(A,B)
 4063  ;
 4064    true
 4065  ).
 write_rules3(+Module:atom, +Rules:list, +Stream:atom) is det
The predicate write the rules in Rules on stream Stream if the verbosity is at least 3. Module is used to get the verbosity setting. /
 4072write_rules3(M,A,B):-
 4073  M:local_setting(verbosity,Ver),
 4074  (Ver>2->
 4075    write_rules(A,B)
 4076  ;
 4077    true
 4078  ).
 4079
 4080
 4081write_disj_clause2(M,A,B):-
 4082  M:local_setting(verbosity,Ver),
 4083  (Ver>1->
 4084    write_disj_clause(A,B)
 4085  ;
 4086    true
 4087  ).
 4088
 4089write_disj_clause3(M,A,B):-
 4090  M:local_setting(verbosity,Ver),
 4091  (Ver>2->
 4092    write_disj_clause(A,B)
 4093  ;
 4094    true
 4095  ).
 4096
 4097write_body2(M,A,B):-
 4098  M:local_setting(verbosity,Ver),
 4099  (Ver>1->
 4100    write_body(A,B)
 4101  ;
 4102    true
 4103  ).
 4104
 4105write_body3(M,A,B):-
 4106  M:local_setting(verbosity,Ver),
 4107  (Ver>2->
 4108    write_body(A,B)
 4109  ;
 4110    true
 4111  ).
 4112
 4113
 4114
 4115
 4116lift_expansion((:- begin_bg), []) :-
 4117  prolog_load_context(module, M),
 4118  lift_input_mod(M),!,
 4119  assert(M:bg_on).
 4120
 4121lift_expansion(C, M:bgc(C)) :-
 4122  prolog_load_context(module, M),
 4123  C\= (:- end_bg),
 4124  lift_input_mod(M),
 4125  M:bg_on,!.
 4126
 4127lift_expansion((:- end_bg), []) :-
 4128  prolog_load_context(module, M),
 4129  lift_input_mod(M),!,
 4130  retractall(M:bg_on),
 4131  findall(C,M:bgc(C),L),
 4132  retractall(M:bgc(_)),
 4133  (M:bg(BG0)->
 4134    retract(M:bg(BG0)),
 4135    append(BG0,L,BG),
 4136    assert(M:bg(BG))
 4137  ;
 4138    assert(M:bg(L))
 4139  ).
 4140
 4141
 4142
 4143
 4144
 4145
 4146lift_expansion((:- begin_in), []) :-
 4147  prolog_load_context(module, M),
 4148  lift_input_mod(M),!,
 4149  assert(M:in_on).
 4150
 4151lift_expansion(C, M:inc(C)) :-
 4152  prolog_load_context(module, M),
 4153  C\= (:- end_in),
 4154  lift_input_mod(M),
 4155  M:in_on,!.
 4156
 4157lift_expansion((:- end_in), []) :-
 4158  prolog_load_context(module, M),
 4159  lift_input_mod(M),!,
 4160  retractall(M:in_on),
 4161  findall(C,M:inc(C),L),
 4162  retractall(M:inc(_)),
 4163  (M:in(IN0)->
 4164    retract(M:in(IN0)),
 4165    append(IN0,L,IN),
 4166    assert(M:in(IN))
 4167  ;
 4168    assert(M:in(L))
 4169  ).
 4170
 4171lift_expansion(begin(model(I)), []) :-
 4172  prolog_load_context(module, M),
 4173  lift_input_mod(M),!,
 4174  retractall(M:model(_)),
 4175  assert(M:model(I)),
 4176  assert(M:int(I)).
 4177
 4178lift_expansion(end(model(_I)), []) :-
 4179  prolog_load_context(module, M),
 4180  lift_input_mod(M),!,
 4181  retractall(M:model(_)).
 4182
 4183lift_expansion(At, A) :-
 4184  prolog_load_context(module, M),
 4185  lift_input_mod(M),
 4186  M:model(Name),
 4187  At \= (_ :- _),
 4188  At \= end_of_file,
 4189  (At=neg(Atom)->
 4190    Atom=..[Pred|Args],
 4191    Atom1=..[Pred,Name|Args],
 4192    A=neg(Atom1)
 4193  ;
 4194    (At=prob(Pr)->
 4195      A='$prob'(Name,Pr)
 4196    ;
 4197      At=..[Pred|Args],
 4198      Atom1=..[Pred,Name|Args],
 4199      A=Atom1
 4200    )
 4201  ).
 4202
 4203:- multifile sandbox:safe_meta/2. 4204
 4205sandbox:safe_meta(liftcover:induce_par_lift(_,_) ,[]).
 4206sandbox:safe_meta(liftcover:induce_lift(_,_), []).
 4207sandbox:safe_meta(liftcover:test_prob_lift(_,_,_,_,_,_), []).
 4208sandbox:safe_meta(liftcover:test_lift(_,_,_,_,_,_,_), []).
 4209sandbox:safe_meta(liftcover:prob_lift(_,_), []).
 4210sandbox:safe_meta(liftcover:prob_lift(_,_,_), []).
 4211sandbox:safe_meta(liftcover:explain_lift(_,_), []).
 4212sandbox:safe_meta(liftcover:explain_lift(_,_,_), []).
 4213sandbox:safe_meta(liftcover:ranked_answers(_,_,_), []).
 4214sandbox:safe_meta(liftcover:ranked_answers(_,_,_,_), []).
 4215sandbox:safe_meta(liftcover:rank_answer(_,_,_), []).
 4216sandbox:safe_meta(liftcover:rank_answer(_,_,_,_), []).
 4217sandbox:safe_meta(liftcover:hits_at_k(_,_,_,_,_,_), []).
 4218sandbox:safe_meta(liftcover:hits_at_k(_,_,_,_,_,_,_), []).
 4219sandbox:safe_meta(liftcover:set_lift(_,_), []).
 4220sandbox:safe_meta(liftcover:setting_lift(_,_), []).
 4221sandbox:safe_meta(liftcover:filter_rules(_,_), []).
 4222
 4223:- multifile sandbox:safe_primitive/1. 4224sandbox:safe_primitive(liftcover:filter_rules(_,_,_), []).
 4225sandbox:safe_primitive(liftcover:sort_rules(_,_,_), []).
 4226sandbox:safe_primitive(liftcover:remove_zero(_,_), []).
 4227sandbox:safe_primitive(liftcover:rank(_,_,_), []).
 4228
 4229
 4230
 4231:- thread_local lift_file/1. 4232
 4233
 4234user:term_expansion((:- lift), []) :-!,
 4235  prolog_load_context(module, M),
 4236  prolog_load_context(source, Source),
 4237  asserta(lift_file(Source)),  
 4238%  retractall(input_mod(_)),
 4239%  M:dynamic(model/1),
 4240%  M:set_prolog_flag(unkonw,fail),
 4241  retractall(M:local_setting(_,_)),
 4242  findall(local_setting(P,V),default_setting_lift(P,V),L),
 4243  assert_all(L,M,_),
 4244  assert(lift_input_mod(M)),
 4245  retractall(M:rule_lift_n(_)),
 4246  assert(M:rule_lift_n(0)),
 4247  M:dynamic((modeh/2,modeh/4,fixed_rule/3,banned/2,lookahead/2,
 4248    lookahead_cons/2,lookahead_cons_var/2,prob/2,output/1,input/1,input_cw/1,
 4249    ref_clause/1,ref/1,model/1,neg/1,rule/4,determination/2,
 4250    bg_on/0,bg/1,bgc/1,in_on/0,in/1,inc/1,int/1)),
 4251  style_check(-discontiguous).
 4252
 4253user:term_expansion(end_of_file, C) :-
 4254  lift_file(Source),
 4255  prolog_load_context(source, Source),
 4256  retractall(lift_file(Source)),
 4257  prolog_load_context(module, M),
 4258  lift_input_mod(M),!,
 4259  retractall(lift_input_mod(M)),
 4260  make_dynamic(M),
 4261%  retractall(M:tabled(_)),
 4262  %retractall(lift_input_mod(M)),
 4263  C=[(:- style_check(+discontiguous)),end_of_file].
 4264
 4265user:term_expansion(In, Out) :-
 4266  \+ current_prolog_flag(xref, true),
 4267  lift_file(Source),
 4268  prolog_load_context(source, Source),
 4269  lift_expansion(In, Out).
 4270
 4271
 4272
 4273
 4274
 4275
 4276%