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

 3776rank(E,L,R):-
 3777    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. /
 3785rank_group([],_E,_S,_NG,_N,+inf).
 3786
 3787rank_group([(S1 - E1)|T],E,S,NG,N,R):-
 3788  N1 is N+1.0,
 3789  (E1==E->
 3790    (S1<S->
 3791      rank_group_found(T,S1,1.0,N1,R)
 3792    ;
 3793      NG1 is NG+1.0,
 3794      rank_group_found(T,S1,NG1,N1,R)
 3795    )
 3796  ;
 3797    (S1<S->
 3798      rank_group(T,E,S1,1.0,N1,R)
 3799    ;
 3800      NG1 is NG+1.0,
 3801      rank_group(T,E,S1,NG1,N1,R)
 3802    )
 3803  ).
 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. /
 3811rank_group_found([],_S,NG,N,R):-
 3812  R is N-(NG+1.0)/2.
 3813
 3814rank_group_found([(S1 - _E1)|T],S,NG,N,R):-
 3815  (S1<S->
 3816    R is N-(NG+1.0)/2
 3817  ;
 3818    N1 is N+1.0,
 3819    NG1 is NG+1.0,
 3820    rank_group_found(T,S1,NG1,N1,R)
 3821  ).
 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. /
 3836prob_lift(M:H,P):-
 3837  M:in(R00),
 3838  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. /
 3848prob_lift(M:H,R00,P):-
 3849  process_clauses(R00,M,R0),
 3850  generate_clauses(R0,M,0,Prog),
 3851  prob_lift_int(H,M,Prog,P).
 3852
 3853prob_lift_int(H,M,Prog,P):-
 3854  (M:local_setting(single_var,true)->
 3855    theory_counts_sv(Prog,M,H,MI)
 3856  ;
 3857    theory_counts(Prog,M,H,MI)
 3858  ),
 3859  compute_prob_ex(Prog,MI,1,PG0),
 3860  P is 1-PG0.
 3861
 3862theory_counts([],_M,_H,[]).
 3863
 3864theory_counts([(H,B,_V,_P)|Rest],M,E,[MI|RestMI]):-
 3865  test_rule(H,B,M,E,MI),
 3866  theory_counts(Rest,M,E,RestMI).
 3867
 3868
 3869test_rule(H,B,M,E,N):-
 3870 findall(1,(H=E,M:B),L),
 3871 length(L,N).
 3872/*
 3873  term_variables(B,Vars),
 3874  term_variables(H,V),
 3875  subtract_eq(Vars,V,VB),
 3876  aggregate(count,VB^(H=E,M:B),N),!.
 3877 
 3878
 3879test_rule(_H,_B,_M,_E,0).
 3880*/
 3881theory_counts_sv([],_M,_H,[]).
 3882
 3883theory_counts_sv([(H,B,_V,_P)|Rest],M,E,[MI|RestMI]):-
 3884  copy_term((H,B),(H1,B1)),
 3885  test_rule_sv(H1,B1,M,E,MI),
 3886  theory_counts_sv(Rest,M,E,RestMI).
 3887
 3888test_rule_sv(H,B,M,E,N):-
 3889  H=E,M:B,!,
 3890  N=1.
 3891
 3892test_rule_sv(_H,_B,_M,_E,0).
 3893/*    term_variables(B,Vars),
 3894    term_variables(H,V),
 3895    subtract_eq(Vars,V,VB),
 3896    \+ aggregate(count,VB^(H=E,M:B),_),
 3897    %  (H=E,M:(\+ B);H\=E),*/
 3898    % N=0.
 3899 
 3900subtract_eq([], _, R) =>
 3901  R = [].
 3902subtract_eq([E|T], D, R) =>
 3903  (   member_eq(E, D)
 3904  ->  subtract_eq(T, D, R)
 3905  ;   R = [E|R1],
 3906      subtract_eq(T, D, R1)
 3907  ).
 3908
 3909
 3910compute_prob_ex_neg(Prog,M,H,PG- (\+ H)):-
 3911  length(Prog,N),
 3912  gen_initial_counts(N,MI0),
 3913  test_theory_neg_prob([H],M,Prog,MI0,MI),
 3914  compute_prob_ex(Prog,MI,1,PG0),
 3915  PG is 1-PG0.
 3916
 3917compute_prob_ex_pos(Prog,M,H,PG- H):-
 3918  length(Prog,N),
 3919  gen_initial_counts(N,MI0),
 3920  test_theory_neg_prob([H],M,Prog,MI0,MI),
 3921  compute_prob_ex(Prog,MI,1,PG0),
 3922  PG is 1-PG0.
 3923
 3924compute_prob_ex([],[],PG,PG).
 3925
 3926compute_prob_ex([(_,_,_,P)|R],[MIH|MIT],PG0,PG):-
 3927  PG1 is PG0*(1-P)^MIH,
 3928  compute_prob_ex(R,MIT,PG1,PG).
 3929
 3930writes([H-H1],S):-
 3931  format(S,"~f - (~q)]).~n~n",[H,H1]).
 3932
 3933writes([H-H1|T],S):-
 3934  format(S,"~f - (~q),~n",[H,H1]),
 3935  writes(T,S).
 3936
 3937
 3938write_p(P,S):-
 3939  get_xy(P,PX,PY),
 3940  format(S,"x=[",[]),
 3941  writesf(PX,S),
 3942  format(S,"y=[",[]),
 3943  writesf(PY,S),
 3944  format(S,"
 3945figure('Name','roc','NumberTitle','off')
 3946set(gca,'XLim',[0.0 1.0])
 3947set(gca,'YLim',[0.0 1.0])
 3948x=[x 1.0]
 3949y=[y 0.0]
 3950k=convhull(x,y)
 3951plot(x(k),y(k),'r-',x,y,'--b+')
 3952%A = polyarea(x,y)~n~n
 3953%save area_roc.csv  A -ascii -append
 3954",
 3955  []).
 3956
 3957get_xy([],[],[]).
 3958
 3959get_xy([X-Y|T],[X|TX],[Y|TY]):-
 3960  get_xy(T,TX,TY).
 3961
 3962
 3963writesf([H],S):-
 3964  format(S,"~f]~n",[H]).
 3965
 3966writesf([H|T],S):-
 3967  format(S,"~f ",[H]),
 3968  writesf(T,S).
 3969
 3970write_ppr(P,S):-
 3971  get_xy(P,PX,PY),
 3972  format(S,"rec=[",[A]),
 3973  writesf(PX,S),
 3974  format(S,"prec=[",[A]),
 3975  writesf(PY,S),
 3976  format(S,"
 3977figure('Name','pr','NumberTitle','off')
 3978set(gca,'XLim',[0.0 1.0])
 3979set(gca,'YLim',[0.0 1.0])
 3980rec=[0.0  rec 1.0];
 3981prec=[0.0 prec 0.0];
 3982plot(rec,prec,'--*k')
 3983%A=polyarea(rec,prec)
 3984%save area_pr.csv  A -ascii -append
 3985~n~n",
 3986  []).
 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 /
 3994write2(M,A):-
 3995  M:local_setting(verbosity,Ver),
 3996  (Ver>1->
 3997    write(A)
 3998  ;
 3999    true
 4000  ).
 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. /
 4007write3(M,A):-
 4008  M:local_setting(verbosity,Ver),
 4009  (Ver>2->
 4010    write(A)
 4011  ;
 4012    true
 4013  ).
 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. /
 4021write4(M,A):-
 4022  M:local_setting(verbosity,Ver),
 4023  (Ver>3->
 4024    write(A)
 4025  ;
 4026    true
 4027  ).
 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. /
 4034nl2(M):-
 4035  M:local_setting(verbosity,Ver),
 4036  (Ver>1->
 4037    nl
 4038  ;
 4039    true
 4040  ).
 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. /
 4047nl3(M):-
 4048  M:local_setting(verbosity,Ver),
 4049  (Ver>2->
 4050    nl
 4051  ;
 4052    true
 4053  ).
 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. /
 4061nl4(M):-
 4062  M:local_setting(verbosity,Ver),
 4063  (Ver>3->
 4064    nl
 4065  ;
 4066    true
 4067  ).
 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. /
 4074format2(M,A,B):-
 4075  M:local_setting(verbosity,Ver),
 4076  (Ver>1->
 4077    format(A,B)
 4078  ;
 4079    true
 4080  ).
 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. /
 4087format3(M,A,B):-
 4088  M:local_setting(verbosity,Ver),
 4089  (Ver>2->
 4090    format(A,B)
 4091  ;
 4092    true
 4093  ).
 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. /
 4100format4(M,A,B):-
 4101  M:local_setting(verbosity,Ver),
 4102  (Ver>3->
 4103    format(A,B)
 4104  ;
 4105    true
 4106  ).
 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. /
 4113write_rules2(M,A,B):-
 4114  M:local_setting(verbosity,Ver),
 4115  (Ver>1->
 4116    write_rules(A,B)
 4117  ;
 4118    true
 4119  ).
 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. /
 4126write_rules3(M,A,B):-
 4127  M:local_setting(verbosity,Ver),
 4128  (Ver>2->
 4129    write_rules(A,B)
 4130  ;
 4131    true
 4132  ).
 4133
 4134
 4135write_disj_clause2(M,A,B):-
 4136  M:local_setting(verbosity,Ver),
 4137  (Ver>1->
 4138    write_disj_clause(A,B)
 4139  ;
 4140    true
 4141  ).
 4142
 4143write_disj_clause3(M,A,B):-
 4144  M:local_setting(verbosity,Ver),
 4145  (Ver>2->
 4146    write_disj_clause(A,B)
 4147  ;
 4148    true
 4149  ).
 4150
 4151write_body2(M,A,B):-
 4152  M:local_setting(verbosity,Ver),
 4153  (Ver>1->
 4154    write_body(A,B)
 4155  ;
 4156    true
 4157  ).
 4158
 4159write_body3(M,A,B):-
 4160  M:local_setting(verbosity,Ver),
 4161  (Ver>2->
 4162    write_body(A,B)
 4163  ;
 4164    true
 4165  ).
 4166
 4167
 4168
 4169
 4170lift_expansion((:- begin_bg), []) :-
 4171  prolog_load_context(module, M),
 4172  lift_input_mod(M),!,
 4173  assert(M:bg_on).
 4174
 4175lift_expansion(C, M:bgc(C)) :-
 4176  prolog_load_context(module, M),
 4177  C\= (:- end_bg),
 4178  lift_input_mod(M),
 4179  M:bg_on,!.
 4180
 4181lift_expansion((:- end_bg), []) :-
 4182  prolog_load_context(module, M),
 4183  lift_input_mod(M),!,
 4184  retractall(M:bg_on),
 4185  findall(C,M:bgc(C),L),
 4186  retractall(M:bgc(_)),
 4187  (M:bg(BG0)->
 4188    retract(M:bg(BG0)),
 4189    append(BG0,L,BG),
 4190    assert(M:bg(BG))
 4191  ;
 4192    assert(M:bg(L))
 4193  ).
 4194
 4195
 4196
 4197
 4198
 4199
 4200lift_expansion((:- begin_in), []) :-
 4201  prolog_load_context(module, M),
 4202  lift_input_mod(M),!,
 4203  assert(M:in_on).
 4204
 4205lift_expansion(C, M:inc(C)) :-
 4206  prolog_load_context(module, M),
 4207  C\= (:- end_in),
 4208  lift_input_mod(M),
 4209  M:in_on,!.
 4210
 4211lift_expansion((:- end_in), []) :-
 4212  prolog_load_context(module, M),
 4213  lift_input_mod(M),!,
 4214  retractall(M:in_on),
 4215  findall(C,M:inc(C),L),
 4216  retractall(M:inc(_)),
 4217  (M:in(IN0)->
 4218    retract(M:in(IN0)),
 4219    append(IN0,L,IN),
 4220    assert(M:in(IN))
 4221  ;
 4222    assert(M:in(L))
 4223  ).
 4224
 4225lift_expansion(begin(model(I)), []) :-
 4226  prolog_load_context(module, M),
 4227  lift_input_mod(M),!,
 4228  retractall(M:model(_)),
 4229  assert(M:model(I)),
 4230  assert(M:int(I)).
 4231
 4232lift_expansion(end(model(_I)), []) :-
 4233  prolog_load_context(module, M),
 4234  lift_input_mod(M),!,
 4235  retractall(M:model(_)).
 4236
 4237lift_expansion(At, A) :-
 4238  prolog_load_context(module, M),
 4239  lift_input_mod(M),
 4240  M:model(Name),
 4241  At \= (_ :- _),
 4242  At \= end_of_file,
 4243  (At=neg(Atom)->
 4244    Atom=..[Pred|Args],
 4245    Atom1=..[Pred,Name|Args],
 4246    A=neg(Atom1)
 4247  ;
 4248    (At=prob(Pr)->
 4249      A='$prob'(Name,Pr)
 4250    ;
 4251      At=..[Pred|Args],
 4252      Atom1=..[Pred,Name|Args],
 4253      A=Atom1
 4254    )
 4255  ).
 4256
 4257:- multifile sandbox:safe_meta/2. 4258
 4259sandbox:safe_meta(liftcover:induce_par_lift(_,_) ,[]).
 4260sandbox:safe_meta(liftcover:induce_lift(_,_), []).
 4261sandbox:safe_meta(liftcover:test_prob_lift(_,_,_,_,_,_), []).
 4262sandbox:safe_meta(liftcover:test_lift(_,_,_,_,_,_,_), []).
 4263sandbox:safe_meta(liftcover:prob_lift(_,_), []).
 4264sandbox:safe_meta(liftcover:prob_lift(_,_,_), []).
 4265sandbox:safe_meta(liftcover:explain_lift(_,_), []).
 4266sandbox:safe_meta(liftcover:explain_lift(_,_,_), []).
 4267sandbox:safe_meta(liftcover:ranked_answers(_,_,_), []).
 4268sandbox:safe_meta(liftcover:ranked_answers(_,_,_,_), []).
 4269sandbox:safe_meta(liftcover:rank_answer(_,_,_), []).
 4270sandbox:safe_meta(liftcover:rank_answer(_,_,_,_), []).
 4271sandbox:safe_meta(liftcover:hits_at_k(_,_,_,_,_,_), []).
 4272sandbox:safe_meta(liftcover:hits_at_k(_,_,_,_,_,_,_), []).
 4273sandbox:safe_meta(liftcover:set_lift(_,_), []).
 4274sandbox:safe_meta(liftcover:setting_lift(_,_), []).
 4275sandbox:safe_meta(liftcover:filter_rules(_,_), []).
 4276
 4277:- multifile sandbox:safe_primitive/1. 4278sandbox:safe_primitive(liftcover:filter_rules(_,_,_), []).
 4279sandbox:safe_primitive(liftcover:sort_rules(_,_,_), []).
 4280sandbox:safe_primitive(liftcover:remove_zero(_,_), []).
 4281sandbox:safe_primitive(liftcover:rank(_,_,_), []).
 4282
 4283
 4284
 4285:- thread_local lift_file/1. 4286
 4287
 4288user:term_expansion((:- lift), []) :-!,
 4289  prolog_load_context(module, M),
 4290  prolog_load_context(source, Source),
 4291  asserta(lift_file(Source)),  
 4292%  retractall(input_mod(_)),
 4293%  M:dynamic(model/1),
 4294%  M:set_prolog_flag(unkonw,fail),
 4295  retractall(M:local_setting(_,_)),
 4296  findall(local_setting(P,V),default_setting_lift(P,V),L),
 4297  assert_all(L,M,_),
 4298  assert(lift_input_mod(M)),
 4299  retractall(M:rule_lift_n(_)),
 4300  assert(M:rule_lift_n(0)),
 4301  M:dynamic((modeh/2,modeh/4,fixed_rule/3,banned/2,lookahead/2,
 4302    lookahead_cons/2,lookahead_cons_var/2,prob/2,output/1,input/1,input_cw/1,
 4303    ref_clause/1,ref/1,model/1,neg/1,rule/4,determination/2,
 4304    bg_on/0,bg/1,bgc/1,in_on/0,in/1,inc/1,int/1)),
 4305  style_check(-discontiguous).
 4306
 4307user:term_expansion(end_of_file, C) :-
 4308  lift_file(Source),
 4309  prolog_load_context(source, Source),
 4310  retractall(lift_file(Source)),
 4311  prolog_load_context(module, M),
 4312  lift_input_mod(M),!,
 4313  retractall(lift_input_mod(M)),
 4314  make_dynamic(M),
 4315%  retractall(M:tabled(_)),
 4316  %retractall(lift_input_mod(M)),
 4317  C=[(:- style_check(+discontiguous)),end_of_file].
 4318
 4319user:term_expansion(In, Out) :-
 4320  \+ current_prolog_flag(xref, true),
 4321  lift_file(Source),
 4322  prolog_load_context(source, Source),
 4323  lift_expansion(In, Out).
 4324
 4325
 4326
 4327
 4328
 4329
 4330%