1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2% A Learning Engine for Proposing Hypotheses % 3% % 4% A L E P H % 5% Version 5 (last modified: Sun Mar 11 03:25:37 UTC 2007) % 6% % 7% This is the source for Aleph written and maintained % 8% by Ashwin Srinivasan (ashwin@comlab.ox.ac.uk) % 9% % 10% % 11% It was originally written to run with the Yap Prolog Compiler % 12% Yap can be found at: http://sourceforge.net/projects/yap/ % 13% Yap must be compiled with -DDEPTH_LIMIT=1 % 14% % 15% It should also run with SWI Prolog, although performance may be % 16% sub-optimal. % 17% % 18% If you obtain this version of Aleph and have not already done so % 19% please subscribe to the Aleph mailing list. You can do this by % 20% mailing majordomo@comlab.ox.ac.uk with the following command in the % 21% body of the mail message: subscribe aleph % 22% % 23% Aleph is freely available for academic purposes. % 24% If you intend to use it for commercial purposes then % 25% please contact Ashwin Srinivasan first. % 26% % 27% A simple on-line manual is available on the Web at % 28% www.comlab.ox.ac.uk/oucl/research/areas/machlearn/Aleph/index.html % 29% % 30% % 31%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 32 33:- module(aleph, 34 [ 35 induce/1, 36 induce_tree/1, 37 induce_max/1, 38 induce_cover/1, 39 induce_incremental/1, 40 induce_clauses/1, 41 induce_theory/1, 42 induce_modes/1, 43 induce_features/1, 44 induce_constraints/1, 45 sat/1, 46 aleph_set/2, 47 aleph_setting/2, 48 goals_to_list/2, 49 clause_to_list/2, 50 aleph_subsumes/2, 51 aleph_delete/3, 52 hypothesis/3, 53 hypothesis/4, 54 var_types/3, 55 show/1, 56 rdhyp/1, 57 addhyp_i/1, 58 sphyp_i/1, 59 covers/1, 60 coversn/1, 61 reduce/1, 62 abducible/1, 63 bottom/1, 64 commutative/1, 65 man/1, 66 symmetric/1, 67 lazy_evaluate/1, 68 model/1, 69 positive_only/1, 70 example_saturated/1, 71 addgcws_i/1, 72 rmhyp_i/1, 73 random/2, 74 aleph_random/1, 75 mode/2, modeh/2, modeb/2, good_clauses/1, op(500,fy,#), op(500,fy,*), op(900,xfy,because) ]).
105:- use_module(library(arithmetic)). 106:-use_module(library(broadcast)). 107:-use_module(library(time)). 108:- arithmetic_function(inf/0). 109inf(1e10). 110:-set_prolog_flag(unknown,warning). 111:- dynamic aleph_input_mod/1. 112 113:- meta_predicate induce( ). 114:- meta_predicate induce_tree( ). 115:- meta_predicate induce_max( ). 116:- meta_predicate induce_cover( ). 117:- meta_predicate induce_incremental( ). 118:- meta_predicate induce_clauses( ). 119:- meta_predicate induce_theory( ). 120:- meta_predicate induce_modes( ). 121:- meta_predicate induce_features( ). 122:- meta_predicate induce_constraints( ). 123:- meta_predicate sat( ). 124:- meta_predicate aleph_set( , ). 125:- meta_predicate aleph_setting( , ). 126:- meta_predicate noset( ). 127:- meta_predicate model( ). 128:- meta_predicate mode( , ). 129:- meta_predicate modeh( , ). 130:- meta_predicate modeb( , ). 131:- meta_predicate show( ). 132:- meta_predicate hypothesis( , , ). 133:- meta_predicate rdhyp( ). 134:- meta_predicate addhyp_i( ). 135:- meta_predicate sphyp_i( ). 136:- meta_predicate covers( ). 137:- meta_predicate coversn( ). 138:- meta_predicate reduce( ). 139:- meta_predicate abducible( ). 140:- meta_predicate bottom( ). 141:- meta_predicate commutative( ). 142:- meta_predicate symmetric( ). 143:- meta_predicate lazy_evaluate( ). 144:- meta_predicate positive_only( ). 145:- meta_predicate example_saturated( ). 146 147 148 149:- meta_predicate addgcws_i( ). 150:- meta_predicate rmhyp_i( ). 151:- meta_predicate good_clauses( ). 152 153 154/* INIT ALEPH */ 155 156systemterm_expansion((:- aleph), []) :- 157 prolog_load_context(module, M), 158 assert(aleph_input_mod(M)),!, 159 initialize(M). 160 161initialize(M):- 162 % nl, nl, 163 % write('A L E P H'), nl, 164 % aleph:aleph_version(Version), write('Version '), write(Version), nl, 165 % aleph:aleph_version_date(Date), write('Last modified: '), write(Date), nl, nl, 166 % aleph:aleph_manual(Man), 167 % write('Manual: '), 168 % write(Man), nl, nl, 169 aleph:aleph_version(V), aleph:set(version,V,M), aleph:reset(M), 170 %findall(local_setting(P,V),default_setting_sc(P,V),L), 171 %assert_all(L,M,_), 172 M:dynamic((pos_on/0,neg_on/0,bg_on/0,incneg/1,incpos/1,in/1,bgc/1,bg/1)), 173 M:dynamic(('$aleph_feature'/2, 174 '$aleph_global'/2, 175 '$aleph_good'/3, 176 '$aleph_local'/2, 177 '$aleph_sat'/2, 178 '$aleph_sat_atom'/2, 179 '$aleph_sat_ovars'/2, 180 '$aleph_sat_ivars'/2, 181 '$aleph_sat_varsequiv'/2, 182 '$aleph_sat_varscopy'/3, 183 '$aleph_sat_terms'/4, 184 '$aleph_sat_vars'/4, 185 '$aleph_sat_litinfo'/6, 186 '$aleph_search_cache'/1, 187 '$aleph_search_prunecache'/1, 188 '$aleph_search'/2, 189 '$aleph_search_seen'/2, 190 '$aleph_search_expansion'/4, 191 '$aleph_search_gain'/4, 192 '$aleph_search_node'/8, 193 '$aleph_link_vars'/2, 194 '$aleph_has_vars'/3, 195 '$aleph_has_ovar'/4, 196 '$aleph_has_ivar'/4, 197 '$aleph_determination'/2, 198 '$aleph_search_seen'/2)), 199 M:dynamic((prune/1,cost/3,example/3,aleph_portray/1)), 200 style_check(-discontiguous), 201 aleph:init(swi,M), 202 assert(M:(reduce:-reduce(_))), 203 assert(M:(induce_constraints:-induce_constraints(_))), 204 assert(M:(induce_modes:-induce_modes(_))), 205 assert(M:(induce_incremental:-induce_incremental(_))), 206 assert(M:(induce_clauses:-induce_clauses(_))), 207 assert(M:(induce:-induce(_))), 208 assert(M:(induce_tree:-induce_tree(_))), 209 assert(M:(induce_max:-induce_max(_))), 210 assert(M:(induce_cover:-induce_cover(_))), 211 assert(M:(induce_theory:-induce_theory(_))), 212 assert(M:(induce_features:-induce_features(_))), 213 assert(M:(rdhyp:-rdhyp(_))), 214 assert(M:(sphyp:-sphyp_i(_))), 215 assert(M:(addgcws:-addgcws_i(_))), 216 assert(M:(rmhyp:-rmhyp_i(_))), 217 assert(M:(addhyp:-addhyp_i(_))), 218 assert(M:(covers:-covers(_))), 219 assert(M:(coversn:-coversn(_))), 220 221 aleph:clean_up(M), 222 retractall(M:example(_,_,_)), 223 aleph:reset(M). 224 225 226systemterm_expansion((:- begin_bg), []) :- 227 prolog_load_context(module, M), 228 aleph_input_mod(M),!, 229 assert(M:bg_on). 230 231systemterm_expansion(C, C) :- 232 C\= (:- end_bg), 233 prolog_load_context(module, M), 234 aleph_input_mod(M), 235 M:bg_on,!. 236 237systemterm_expansion((:- end_bg), []) :- 238 prolog_load_context(module, M), 239 aleph_input_mod(M),!, 240 retractall(M:bg_on). 241 %findall(C,M:bgc(C),L), 242 %retractall(M:bgc(_)), 243 % (M:bg(BG0)-> 244 % retract(M:bg(BG0)), 245 % append(BG0,L,BG), 246 % assert(M:bg(BG)) 247 % ; 248 % assert_all(L,M,_) 249 % ). 250systemterm_expansion((:- begin_in_pos), []) :- 251 prolog_load_context(module, M), 252 aleph_input_mod(M),!, 253 assert(M:pos_on), 254 clean_up_examples(pos,M), 255 asserta(M:'$aleph_global'(size,size(pos,0))). 256 257 258systemterm_expansion(C, []) :- 259 C\= (:- end_in_pos), 260 prolog_load_context(module, M), 261 aleph_input_mod(M), 262 M:pos_on,!,aleph:record_example(nocheck,pos,C,_,M). 263 264systemterm_expansion((:- end_in_pos), []) :- 265 prolog_load_context(module, M), 266 aleph_input_mod(M),!, 267 retractall(M:pos_on). 268 %findall(C,M:incpos(C),L), 269 %retractall(M:incpos(_)), 270% (M:in(IN0)-> 271% retract(M:in(IN0)),% 272% 273% append(IN0,L,IN), 274% assert(M:in(IN)) 275% ; 276% assert(M:in(L)) 277% ). 278 279%%%%%% 280 281systemterm_expansion((:- begin_in_neg), []) :- 282 prolog_load_context(module, M), 283 aleph_input_mod(M),!, 284 assert(M:neg_on), 285 aleph:clean_up_examples(neg,M), 286 asserta(M:'$aleph_global'(size,size(neg,0))). 287 288systemterm_expansion(C, []) :- 289 C\= (:- end_in_neg), 290 prolog_load_context(module, M), 291 aleph_input_mod(M), 292 M:neg_on,!,aleph:record_example(nocheck,neg,C,_,M). 293 294systemterm_expansion(:- mode(A,B), []) :- 295 prolog_load_context(module, M), 296 aleph_input_mod(M),!, 297 aleph:mode(A,B,M). 298 299systemterm_expansion(:- modeh(A,B), []) :- 300 prolog_load_context(module, M), 301 aleph_input_mod(M),!, 302 aleph:modeh(A,B,M). 303 304systemterm_expansion(:- modeb(A,B), []) :- 305 prolog_load_context(module, M), 306 aleph_input_mod(M),!, 307 aleph:modeb(A,B,M). 308 309systemterm_expansion(:- aleph_set(A,B), []) :- 310 prolog_load_context(module, M), 311 aleph_input_mod(M),!, 312 aleph:set(A,B,M). 313 314systemterm_expansion(:- determination(A,B), []) :- 315 prolog_load_context(module, M), 316 aleph_input_mod(M),!, 317 aleph:determination(A,B,M). 318 319systemterm_expansion((:- end_in_neg), []) :- 320 prolog_load_context(module, M), 321 aleph_input_mod(M),!, 322 retractall(M:neg_on). 323 %findall(C,M:incneg(C),L), 324 %retractall(M:incneg(_)), 325% 326% (M:in(IN0)-> 327% retract(M:in(IN0)), 328 329% append(IN0,L,IN), 330% assert(M:in(IN)) 331% ; 332% assert(M:in(L)) 333% ). 334 systemterm_expansion((:- aleph_read_all), []) :- 335 prolog_load_context(module, M), 336 aleph_input_mod(M),!. 337 338systemterm_expansion(end_of_file, end_of_file) :- 339 prolog_load_context(module, M), 340 aleph_input_mod(M),!, 341 retractall(pita_input_mod(M)), 342 aleph:record_targetpred(M), 343 aleph:check_recursive_calls(M), 344 aleph:check_prune_defs(M), 345 aleph:check_user_search(M), 346 aleph:check_posonly(M), 347 aleph:check_auto_refine(M), 348 aleph:check_abducibles(M), 349 %Aggiunti alla fine 350 aleph:reset_counts(M), 351 asserta(M:'$aleph_global'(last_clause,last_clause(0))), 352 broadcast(examples(loaded)), 353 (M:'$aleph_global'(size,size(pos,NP))-> true;NP=0), 354 (NP > 0 -> ExP = [1-NP]; ExP = []), 355 asserta(M:'$aleph_global'(atoms,atoms(pos,ExP))), 356 asserta(M:'$aleph_global'(atoms_left,atoms_left(pos,ExP))), 357 asserta(M:'$aleph_global'(last_example,last_example(pos,NP))), 358 (M:'$aleph_global'(size,size(neg,NN))->true;NN=0), 359 (NN > 0 -> ExN = [1-NN]; ExN = []), 360 asserta(M:'$aleph_global'(atoms,atoms(neg,ExN))), 361 asserta(M:'$aleph_global'(atoms_left,atoms_left(neg,ExN))), 362 asserta(M:'$aleph_global'(last_example,last_example(neg,NN))), 363 set_lazy_recalls(M), 364 (setting(prior,_,M) -> true; 365 normalise_distribution([NP-pos,NN-neg],Prior), 366 set(prior,Prior,M) 367 ). 368 369assert_all([],_M,[]). 370 371assert_all([H|T],M,[HRef|TRef]):- 372 assertz(M:,HRef), 373 assert_all(T,M,TRef). 374 375assert_all([],[]). 376 377assert_all([H|T],[HRef|TRef]):- 378 assertz(H,HRef), 379 assert_all(T,TRef). 380 381print_arr([]). 382print_arr([H|T]):- 383 write(H),print_arr(T),nl. 384 385 386 387/* 388theory_induce(Theory):- 389 aleph_input_mod(M), 390 induce, 391 show(Theory). 392*/ 393%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 394% C O M P I L E R S P E C I F I C 395 396 397prolog_type(yap):- 398 predicate_property(yap_flag(_,_),built_in), !. 399prolog_type(swi). 400 401init(yap):- 402 source, 403 system_predicate(false,false), hide(false), 404 style_check(single_var), 405 % yap_flag(profiling,on), 406 assert_static((aleph_random(X):- X is random)), 407 (predicate_property(alarm(_,_,_),built_in) -> 408 assert_static((remove_alarm(X):- alarm(0,_,_))); 409 assert_static(alarm(_,_,_)), 410 assert_static(remove_alarm(_))), 411 assert_static((aleph_consult(F):- consult(F))), 412 assert_static((aleph_reconsult(F):- reconsult(F))), 413 (predicate_property(thread_local(_),built_in) -> true; 414 assert_static(thread_local(_))), 415 assert_static(broadcast(_)), 416 assert_static((aleph_background_predicate(Lit):- 417 predicate_property(Lit,P), 418 ((P = static); (P = dynamic); (P = built_in)), !)), 419 (predicate_property(delete_file(_),built_in) -> true; 420 assert_static(delete_file(_))). 421 422init(swi,M):- 423 %redefine_system_predicate(false), 424 style_check(+singleton), 425 style_check(-discontiguous), 426 M:dynamic(aleph_false/0), 427 M:dynamic(example/3), 428 assert((depth_bound_call(G,L,M):- 429 call_with_depth_limit(M:G,L,R), 430 R \= depth_limit_exceeded)), 431 (predicate_property(numbervars(_,_,_),built_in) -> true; 432 assert((numbervars(A,B,C):- numbervars(A,'$VAR',B,C)))), 433 assert((system(X):- shell(X))), 434 assert((exists(X):- exists_file(X))), 435 assert((aleph_reconsult(F):- consult(F))), 436 %assert((aleph_random(X):- I = 1000000, X is float(random(I-1))/float(I))), 437 (predicate_property(thread_local(_),built_in) -> true; 438 assert(thread_local(_))), 439 440 (predicate_property(delete_file(_),built_in) -> true; 441 assert(delete_file(_))). 442 443aleph_background_predicate(Lit,M):- 444 predicate_property(M:Lit,P), 445 ((P=interpreted);(P=built_in)), !. 446 447aleph_consult(X,M):- aleph_open(X,read,S), repeat, 448 read(S,F), (F = end_of_file -> close(S), !; 449 assertz(M:),fail).
455aleph_random(X):- I = 1000000, X is float(random(I-1))/float(I). 456 457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 458% A L E P H 459 460 461aleph_version(5). 462aleph_version_date('Sun Mar 11 03:25:37 UTC 2007'). 463aleph_manual('http://www.comlab.ox.ac.uk/oucl/groups/machlearn/Aleph/index.html'). 464 465 466 467:- thread_local aleph_input_mod/1. 468 469 470 471:- multifile prune/1. 472:- multifile refine/2. 473:- multifile cost/3. 474:- multifile prove/2. 475:- multifile redundant/2. 476:- multifile text/2. 477 478 479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 480% C O N S T R U C T B O T T O M 481 482% get_atoms(+Preds,+Depth,+MaxDepth,+Last,-LastLit) 483% layered generation of ground atoms to add to bottom clause 484% Preds is list of PName/Arity entries obtained from the determinations 485% Depth is current variable-chain depth 486% MaxDepth is maximum allowed variable chain depth (i setting) 487% Last is last atom number so far 488% Lastlit is atom number after all atoms to MaxDepth have been generated 489 490% get_atoms(L,1,Ival,Last1,Last) che diventa 491% get_atoms([short/1,...],1,2,1,-LastLit). 492 493get_atoms([],_,_,Last,Last,_M):- !. 494get_atoms(Preds,Depth,MaxDepth,Last,LastLit,M):- 495 Depth =< MaxDepth, 496 Depth0 is Depth - 1, 497 M:'$aleph_sat_terms'(_,Depth0,_,_), % new terms generated ? 498 !, 499 get_atoms1(Preds,Depth,MaxDepth,Last,Last1,M), 500 Depth1 is Depth + 1, 501 get_atoms(Preds,Depth1,MaxDepth,Last1,LastLit,M). 502get_atoms(_,_,_,Last,Last,_M). 503 504% auxiliary predicate used by get_atoms/5 505get_atoms1([],_,_,Last,Last,_M). 506% get_atoms1([short/1|...],1,2,1,-LastLit,M). 507get_atoms1([Pred|Preds],Depth,MaxDepth,Last,LastLit,M):- 508 gen_layer(Pred,Depth,M), 509 flatten(Depth,MaxDepth,Last,Last1,M), 510 get_atoms1(Preds,Depth,MaxDepth,Last1,LastLit,M). 511 512% flatten(+Depth,+MaxDepth,+Last,-LastLit) 513% flatten a set of ground atoms by replacing all in/out terms with variables 514% constants are wrapped in a special term called aleph_const(...) 515% eg suppose p/3 had modes p(+char,+char,#int) 516% then p(a,a,3) becomes p(X,X,aleph_const(3)) 517% ground atoms to be flattened are assumed to be in the i.d.b atoms 518% vars and terms are actually integers which are stored in vars/terms databases 519% so eg above actually becomes p(1,1,aleph_const(3)). 520% where variable 1 stands for term 2 (say) which in turn stands for a 521% Depth is current variable-chain depth 522% MaxDepth is maximum allowed variable chain depth (i setting) 523% Last is last atom number so far 524% Lastlit is atom number after ground atoms here have been flattened 525% If permute_bottom is set to true, then the order of ground atoms is 526% shuffled. The empirical utility of doing this has been investigated by 527% P. Schorn in "Random Local Bottom Clause Permutations for Better Search Space 528% Exploration in Progol-like ILP Systems.", 16th International Conference on 529% ILP (ILP 2006). 530flatten(Depth,MaxDepth,Last,Last1,M):- 531 retractall(M:'$aleph_local'(flatten_num,_)), 532 asserta(M:'$aleph_local'(flatten_num,Last)), 533 M:'$aleph_sat_atom'(_,_),!, 534 (setting(permute_bottom,Permute,M) -> true; Permute = false), 535 flatten_atoms(Permute,Depth,MaxDepth,Last1,M). 536flatten(_,_,_,Last,M):- 537 retract(M:'$aleph_local'(flatten_num,Last)), !. 538 539flatten_atoms(true,Depth,MaxDepth,Last1,M):- 540 findall(L-Mod,retract(M:'$aleph_sat_atom'(L,Mod)),LitModes), 541 aleph_rpermute(LitModes,PLitModes), 542 aleph_member(Lit1-Mode,PLitModes), 543 retract(M:'$aleph_local'(flatten_num,LastSoFar)), 544 (Lit1 = not(Lit) -> Negated = true; Lit = Lit1, Negated = false), 545 flatten_atom(Depth,MaxDepth,Lit,Negated,Mode,LastSoFar,Last1,M), 546 asserta(M:'$aleph_local'(flatten_num,Last1)), 547 fail. 548flatten_atoms(false,Depth,MaxDepth,Last1,M):- 549 repeat, 550 retract(M:'$aleph_sat_atom'(Lit1,Mode)), 551 retract(M:'$aleph_local'(flatten_num,LastSoFar)), 552 (Lit1 = not(Lit) -> Negated = true; Lit = Lit1, Negated = false), 553 flatten_atom(Depth,MaxDepth,Lit,Negated,Mode,LastSoFar,Last1,M), 554 asserta(M:'$aleph_local'(flatten_num,Last1)), 555 (M:'$aleph_sat_atom'(_,_) -> 556 fail; 557 retract(M:'$aleph_local'(flatten_num,Last1))), !. 558flatten_atoms(_,_,_,Last,M):- 559 retract(M:'$aleph_local'(flatten_num,Last)), !. 560 561 562% flatten_atom(+Depth,+Depth1,+Lit,+Negated,+Mode,+Last,-Last1) 563% update lits database by adding ``flattened atoms''. This involves: 564% replacing ground terms at +/- positions in Lit with variables 565% and wrapping # positions in Lit within a special term stucture 566% Mode contains actual mode and term-place numbers and types for +/-/# 567% Last is the last literal number in the lits database at present 568% Last1 is the last literal number after the update 569flatten_atom(Depth,Depth1,Lit,Negated,Mode,Last,Last1,M):- 570 arg(3,Mode,O), arg(4,Mode,C), 571 integrate_args(Depth,Lit,O,M), 572 integrate_args(Depth,Lit,C,M), 573 (Depth = Depth1 -> CheckOArgs = true; CheckOArgs = false), 574 flatten_lits(Lit,CheckOArgs,Depth,Negated,Mode,Last,Last1,M). 575 576% variabilise literals by replacing terms with variables 577% if var splitting is on then new equalities are introduced into bottom clause 578% if at final i-layer, then literals with o/p args that do not contain at least 579% one output var from head are discarded 580flatten_lits(Lit,CheckOArgs,Depth,Negated,Mode,Last,_,M):- 581 functor(Lit,Name,Arity), 582 asserta(M:'$aleph_local'(flatten_lits,Last)), 583 Depth1 is Depth - 1, 584 functor(OldFAtom,Name,Arity), 585 flatten_lit(Lit,Mode,OldFAtom,_,_,M), 586 functor(FAtom,Name,Arity), 587 apply_equivs(Depth1,Arity,OldFAtom,FAtom,M), 588 retract(M:'$aleph_local'(flatten_lits,OldLast)), 589 (CheckOArgs = true -> 590 arg(3,Mode,Out), 591 get_vars(FAtom,Out,OVars), 592 (in_path(OVars,M) -> 593 add_new_lit(Depth,FAtom,Mode,OldLast,Negated,NewLast,M); 594 NewLast = OldLast) ; 595 add_new_lit(Depth,FAtom,Mode,OldLast,Negated,NewLast,M)), 596 asserta(M:'$aleph_local'(flatten_lits,NewLast)), 597 fail. 598flatten_lits(_,_,_,_,_,_,Last1,M):- 599 retract(M:'$aleph_local'(flatten_lits,Last1)). 600 601 602% flatten_lit(+Lit,+Mode,+FAtom,-IVars,-OVars) 603% variabilise Lit as FAtom 604% Mode contains actual mode and 605% In, Out, Const positions as term-place numbers with types 606% replace ground terms with integers denoting variables 607% or special terms denoting constants 608% variable numbers arising from variable splits are disallowed 609% returns Input and Output variable numbers 610flatten_lit(Lit,mode(Mode,In,Out,Const),FAtom,IVars,OVars,M):- 611 functor(Mode,_,Arity), 612 once(copy_modeterms(Mode,FAtom,Arity)), 613 flatten_vars(In,Lit,FAtom,IVars,M), 614 flatten_vars(Out,Lit,FAtom,OVars,M), 615 flatten_consts(Const,Lit,FAtom). 616 617% flatten_vars(+TPList,+Lit,+FAtom,-Vars):- 618% FAtom is Lit with terms-places in TPList replaced by variables 619flatten_vars([],_,_,[],_M). 620flatten_vars([Pos/Type|Rest],Lit,FAtom,[Var|Vars],M):- 621 tparg(Pos,Lit,Term), 622 M:'$aleph_sat_terms'(TNo,_,Term,Type), 623 M:'$aleph_sat_vars'(Var,TNo,_,_), 624 \+(M:'$aleph_sat_varscopy'(Var,_,_)), 625 tparg(Pos,FAtom,Var), 626 flatten_vars(Rest,Lit,FAtom,Vars,M). 627 628% replace a list of terms at places marked by # in the modes 629% with a special term structure denoting a constant 630flatten_consts([],_,_). 631flatten_consts([Pos/_|Rest],Lit,FAtom):- 632 tparg(Pos,Lit,Term), 633 tparg(Pos,FAtom,aleph_const(Term)), 634 flatten_consts(Rest,Lit,FAtom). 635 636% in_path(+ListOfOutputVars) 637% check to avoid generating useless literals in the last i layer 638in_path(OVars,M):- 639 M:'$aleph_sat'(hovars,Vars), !, 640 (Vars=[];OVars=[];intersects(Vars,OVars)). 641in_path(_,_M). 642 643% update_equivs(+VariableEquivalences,+IDepth) 644% update variable equivalences created at a particular i-depth 645% is non-empty only if variable splitting is allowed 646update_equivs([],_,_M):- !. 647update_equivs(Equivs,Depth,M):- 648 retract(M:'$aleph_sat_varsequiv'(Depth,Eq1)), !, 649 update_equiv_lists(Equivs,Eq1,Eq2), 650 asserta(M:'$aleph_sat_varsequiv'(Depth,Eq2)). 651update_equivs(Equivs,Depth,M):- 652 Depth1 is Depth - 1, 653 get_equivs(Depth1,Eq1,M), 654 update_equiv_lists(Equivs,Eq1,Eq2,M), 655 asserta(M:'$aleph_sat_varsequiv'(Depth,Eq2)). 656 657update_equiv_lists([],E,E):- !. 658update_equiv_lists([Var/E1|Equivs],ESoFar,E):- 659 aleph_delete(Var/E2,ESoFar,ELeft), !, 660 update_list(E1,E2,E3), 661 update_equiv_lists(Equivs,[Var/E3|ELeft],E). 662update_equiv_lists([Equiv|Equivs],ESoFar,E):- 663 update_equiv_lists(Equivs,[Equiv|ESoFar],E). 664 665% get variable equivalences at a particular depth 666% recursively descend to greatest depth below this for which equivs exist 667% also returns the database reference of entry 668get_equivs(Depth,[],_M):- 669 Depth < 0, !. 670get_equivs(Depth,Equivs,M):- 671 M:'$aleph_sat_varsequiv'(Depth,Equivs), !. 672get_equivs(Depth,E,M):- 673 Depth1 is Depth - 1, 674 get_equivs(Depth1,E,M). 675 676% apply equivalences inherited from Depth to a flattened literal 677% if no variable splitting, then succeeds only once 678apply_equivs(Depth,Arity,Old,New,M):- 679 get_equivs(Depth,Equivs,M), 680 rename(Arity,Equivs,[],Old,New). 681 682% rename args using list of Var/Equivalences 683rename(_,[],_,L,L):- !. 684rename(0,_,_,_,_):- !. 685rename(Pos,Equivs,Subst0,Old,New):- 686 arg(Pos,Old,OldVar), 687 aleph_member(OldVar/Equiv,Equivs), !, 688 aleph_member(NewVar,Equiv), 689 arg(Pos,New,NewVar), 690 Pos1 is Pos - 1, 691 rename(Pos1,Equivs,[OldVar/NewVar|Subst0],Old,New). 692rename(Pos,Equivs,Subst0,Old,New):- 693 arg(Pos,Old,OldVar), 694 (aleph_member(OldVar/NewVar,Subst0) -> 695 arg(Pos,New,NewVar); 696 arg(Pos,New,OldVar)), 697 Pos1 is Pos - 1, 698 rename(Pos1,Equivs,Subst0,Old,New). 699 700 701% add a new literal to lits database 702% performs variable splitting if splitvars is set to true 703add_new_lit(Depth,FAtom,Mode,OldLast,Negated,NewLast,M):- 704 arg(1,Mode,M1), 705 functor(FAtom,Name,Arity), 706 functor(SplitAtom,Name,Arity), 707 once(copy_modeterms(M1,SplitAtom,Arity)), 708 arg(2,Mode,In), arg(3,Mode,Out), arg(4,Mode,Const), 709 split_vars(Depth,FAtom,In,Out,Const,SplitAtom,IVars,OVars,Equivs,M), 710 update_equivs(Equivs,Depth,M), 711 add_lit(OldLast,Negated,SplitAtom,In,Out,IVars,OVars,LitNum,M), 712 insert_eqs(Equivs,Depth,LitNum,NewLast,M), !. 713 714% modify the literal database: check if performing lazy evaluation 715% of bottom clause, and update input and output terms in literal 716add_lit(Last,Negated,FAtom,I,O,_,_,Last,M):- 717 setting(construct_bottom,CBot,M), 718 (CBot = false ; CBot = reduction), 719 (Negated = true -> Lit = not(FAtom); Lit = FAtom), 720 M:'$aleph_sat_litinfo'(_,0,Lit,I,O,_), !. 721add_lit(Last,Negated,FAtom,In,Out,IVars,OVars,LitNum,M):- 722 LitNum is Last + 1, 723 update_iterms(LitNum,IVars,M), 724 update_oterms(LitNum,OVars,[],Dependents,M), 725 add_litinfo(LitNum,Negated,FAtom,In,Out,Dependents,M), 726 assertz(M:'$aleph_sat_ivars'(LitNum,IVars)), 727 assertz(M:'$aleph_sat_ovars'(LitNum,OVars)), !. 728 729 730% update lits database after checking that the atom does not exist 731% used during updates of lit database by lazy evaluation 732update_lit(LitNum,true,FAtom,I,O,D,M):- 733 M:'$aleph_sat_litinfo'(LitNum,0,not(FAtom),I,O,D), !. 734update_lit(LitNum,false,FAtom,I,O,D,M):- 735 M:'$aleph_sat_litinfo'(LitNum,0,FAtom,I,O,D), !. 736update_lit(LitNum,Negated,FAtom,I,O,D,M):- 737 gen_nlitnum(LitNum,M), 738 add_litinfo(LitNum,Negated,FAtom,I,O,D,M), 739 get_vars(FAtom,I,IVars), 740 get_vars(FAtom,O,OVars), 741 assertz(M:'$aleph_sat_ivars'(LitNum,K,IVars)), 742 assertz(M:'$aleph_sat_ovars'(LitNum,K,OVars)), !. 743 744% add a literal to lits database without checking 745add_litinfo(LitNum,true,FAtom,I,O,D,M):- 746 !, 747 assertz(M:'$aleph_sat_litinfo'(LitNum,0,not(FAtom),I,O,D)). 748add_litinfo(LitNum,_,FAtom,I,O,D,M):- 749 assertz(M:'$aleph_sat_litinfo'(LitNum,0,FAtom,I,O,D)). 750 751% update database with input terms of literal 752update_iterms(_,[],_M). 753update_iterms(LitNum,[VarNum|Vars],M):- 754 retract(M:'$aleph_sat_vars'(VarNum,TNo,I,O)), 755 update(I,LitNum,NewI), 756 asserta(M:'$aleph_sat_vars'(VarNum,TNo,NewI,O)), 757 update_dependents(LitNum,O,M), 758 update_iterms(LitNum,Vars,M). 759 760% update database with output terms of literal 761% return list of dependent literals 762update_oterms(_,[],Dependents,Dependents,_M). 763update_oterms(LitNum,[VarNum|Vars],DSoFar,Dependents,M):- 764 retract(M:'$aleph_sat_vars'(VarNum,TNo,I,O)), 765 update(O,LitNum,NewO), 766 asserta(M:'$aleph_sat_vars'(VarNum,TNo,I,NewO)), 767 update_list(I,DSoFar,D1), 768 update_oterms(LitNum,Vars,D1,Dependents,M). 769 770% update Dependent list of literals with LitNum 771update_dependents(_,[],_M). 772update_dependents(LitNum,[Lit|Lits],M):- 773 retract(M:'$aleph_sat_litinfo'(Lit,Depth,Atom,ITerms,OTerms,Dependents)), 774 update(Dependents,LitNum,NewD), 775 asserta(M:'$aleph_sat_litinfo'(Lit,Depth,Atom,ITerms,OTerms,NewD)), 776 update_dependents(LitNum,Lits,M). 777 778% update dependents of head with literals that are simply generators 779% that is, literals that require no input args 780update_generators(M):- 781 findall(L,(M:'$aleph_sat_litinfo'(L,_,_,[],_,_),L>1),GList), 782 GList \= [], !, 783 retract(M:'$aleph_sat_litinfo'(1,Depth,Lit,I,O,D)), 784 aleph_append(D,GList,D1), 785 asserta(M:'$aleph_sat_litinfo'(1,Depth,Lit,I,O,D1)). 786update_generators(_M). 787 788% mark literals 789mark_lits(Lits,M):- 790 aleph_member(Lit,Lits), 791 asserta(M:'$aleph_local'(marked,Lit/0)), 792 fail. 793mark_lits(_,_M). 794 795% recursively mark literals with minimum depth to bind output vars in head 796mark_lits([],_,_,_M). 797mark_lits(Lits,OldVars,Depth,M):- 798 mark_lits(Lits,Depth,true,[],Predecessors,OldVars,NewVars,M), 799 aleph_delete_list(Lits,Predecessors,P1), 800 Depth1 is Depth + 1, 801 mark_lits(P1,NewVars,Depth1,M). 802 803mark_lits([],_,_,P,P,V,V,_M). 804mark_lits([Lit|Lits],Depth,GetPreds,PSoFar,P,VSoFar,V,M):- 805 retract(M:'$aleph_local'(marked,Lit/Depth0)), !, 806 (Depth < Depth0 -> 807 mark_lit(Lit,Depth,GetPreds,VSoFar,P1,V2,M), 808 update_list(P1,PSoFar,P2), 809 mark_lits(Lits,Depth,GetPreds,P2,P,V2,V,M); 810 asserta(M:'$aleph_local'(marked,Lit/Depth0)), 811 mark_lits(Lits,Depth,GetPreds,PSoFar,P,VSoFar,V,M)). 812mark_lits([Lit|Lits],Depth,GetPreds,PSoFar,P,VSoFar,V,M):- 813 mark_lit(Lit,Depth,GetPreds,VSoFar,P1,V2,M), !, 814 update_list(P1,PSoFar,P2), 815 mark_lits(Lits,Depth,GetPreds,P2,P,V2,V,M). 816mark_lits([_|Lits],Depth,GetPreds,PSoFar,P,VSoFar,V,M):- 817 mark_lits(Lits,Depth,GetPreds,PSoFar,P,VSoFar,V,M). 818 819mark_lit(Lit,Depth,GetPreds,VSoFar,P1,V1,M):- 820 retract(M:'$aleph_sat_litinfo'(Lit,_,Atom,I,O,D)), 821 asserta(M:'$aleph_local'(marked,Lit/Depth)), 822 asserta(M:'$aleph_sat_litinfo'(Lit,Depth,Atom,I,O,D)), 823 (GetPreds = false -> 824 P1 = [], 825 V1 = VSoFar; 826 get_vars(Atom,O,OVars), 827 update_list(OVars,VSoFar,V1), 828 get_predicates(D,V1,D1,M), 829 mark_lits(D1,Depth,false,[],_,VSoFar,_,M), 830 get_vars(Atom,I,IVars), 831 get_predecessors(IVars,[],P1,M)). 832 833% mark lits that produce outputs that are not used by any other literal 834mark_floating_lits(Lit,Last,_M):- 835 Lit > Last, !. 836mark_floating_lits(Lit,Last,M):- 837 M:'$aleph_sat_litinfo'(Lit,_,_,_,O,D), 838 O \= [], 839 (D = []; D = [Lit]), !, 840 asserta(M:'$aleph_local'(marked,Lit/0)), 841 Lit1 is Lit + 1, 842 mark_floating_lits(Lit1,Last,M). 843mark_floating_lits(Lit,Last,M):- 844 Lit1 is Lit + 1, 845 mark_floating_lits(Lit1,Last,M). 846 847% mark lits in bottom clause that are specified redundant by user 848% requires definition of redundant/2 that have distinguished first arg ``bottom'' 849mark_redundant_lits(Lit,Last,_M):- 850 Lit > Last, !. 851mark_redundant_lits(Lit,Last,M):- 852 get_pclause([Lit],[],Atom,_,_,_,M), 853 redundant(bottom,Atom,M), !, 854 asserta(M:'$aleph_local'(marked,Lit/0)), 855 Lit1 is Lit + 1, 856 mark_redundant_lits(Lit1,Last,M). 857mark_redundant_lits(Lit,Last,M):- 858 Lit1 is Lit + 1, 859 mark_redundant_lits(Lit1,Last,M). 860 861% get literals that are linked and do not link to any others (ie predicates) 862get_predicates([],_,[],_M). 863get_predicates([Lit|Lits],Vars,[Lit|T],M):- 864 M:'$aleph_sat_litinfo'(Lit,_,Atom,I,_,[]), 865 get_vars(Atom,I,IVars), 866 aleph_subset1(IVars,Vars), !, 867 get_predicates(Lits,Vars,T,M). 868get_predicates([_|Lits],Vars,T,M):- 869 get_predicates(Lits,Vars,T,M). 870 871% get all predecessors in the bottom clause of a set of literals 872get_predecessors([],[],_M). 873get_predecessors([Lit|Lits],P,M):- 874 (Lit = 1 -> Pred = []; 875 get_ivars1(false,Lit,IVars,M), 876 get_predecessors(IVars,[],Pred,M)), 877 get_predecessors(Pred,PPred,M), 878 update_list(Pred,PPred,P1), 879 get_predecessors(Lits,P2,M), 880 update_list(P2,P1,P). 881 882% get list of literals in the bottom clause that produce a set of vars 883get_predecessors([],P,P,_M). 884get_predecessors([Var|Vars],PSoFar,P,M):- 885 M:'$aleph_sat_vars'(Var,_,_,O), 886 update_list(O,PSoFar,P1), 887 get_predecessors(Vars,P1,P,M). 888 889% removal of literals in bottom clause by negative-based reduction. 890% A greedy strategy is employed, as implemented within the ILP system 891% Golem (see Muggleton and Feng, "Efficient induction 892% of logic programs", Inductive Logic Programming, S. Muggleton (ed.), 893% AFP Press). In this, given a clause H:- B1, B2,...Bn, let Bi be the 894% first literal s.t. H:-B1,...,Bi covers no more than the allowable number 895% of negatives. The clause H:- Bi,B1,...,Bi-1 is then reduced. The 896% process continues until there is no change in the length of a clause 897% within an iteration. The algorithm is O(n^2). 898rm_nreduce(Last,N,M):- 899 setting(nreduce_bottom,true,M), !, 900 get_litnums(1,Last,BottomLits,M), 901 M:'$aleph_global'(atoms,atoms(neg,Neg)), 902 setting(depth,Depth,M), 903 setting(prooftime,Time,M), 904 setting(proof_strategy,Proof,M), 905 setting(noise,Noise,M), 906 neg_reduce(BottomLits,Neg,Last,Depth/Time/Proof,Noise,M), 907 get_marked(1,Last,Lits,M), 908 length(Lits,N), 909 p1_message('negative-based removal'), p_message(N/Last). 910rm_nreduce(_,0,_M). 911 912neg_reduce([Head|Body],Neg,Last,DepthTime,Noise,M):- 913 get_pclause([Head],[],Clause,TV,_,_,M), 914 neg_reduce(Body,Clause,TV,2,Neg,DepthTime,Noise,NewLast,M), 915 NewLast \= Last, !, 916 NewLast1 is NewLast - 1, 917 aleph_remove_n(NewLast1,[Head|Body],Prefix,[LastLit|Rest]), 918 mark_lits(Rest,M), 919 insert_lastlit(LastLit,Prefix,Lits1), 920 neg_reduce(Lits1,Neg,NewLast,DepthTime,Noise,M). 921neg_reduce(_,_,_,_,_,_M). 922 923neg_reduce([],_,_,N,_,_,_,N). 924neg_reduce([L1|Lits],C,TV,N,Neg,ProofFlags,Noise,LastLit,M):- 925 get_pclause([L1],TV,Lit1,TV1,_,_,M), 926 extend_clause(C,Lit1,Clause,M), 927 prove(ProofFlags,neg,Clause,Neg,NegCover,Count,M), 928 Count > Noise, !, 929 N1 is N + 1, 930 neg_reduce(Lits,Clause,TV1,N1,NegCover,ProofFlags,Noise,LastLit,M). 931neg_reduce(_,_,_,N,_,_,_,N,_M). 932 933% insert_lastlit(LastLit,[1|Lits],Lits1):- 934 % find_last_ancestor(Lits,LastLit,1,2,Last), 935 % aleph_remove_n(Last,[1|Lits],Prefix,Suffix), 936 % aleph_append([LastLit|Suffix],Prefix,Lits1). 937 938insert_lastlit(LastLit,Lits,Lits1,M):- 939 get_predecessors([LastLit],Prefix,M), 940 aleph_delete_list(Prefix,Lits,Suffix), 941 aleph_append([LastLit|Suffix],Prefix,Lits1). 942 943 944find_last_ancestor([],_,Last,_,Last,_M):- !. 945find_last_ancestor([Lit|Lits],L,_,LitNum,Last,M):- 946 M:'$aleph_sat_litinfo'(Lit,_,_,_,_,D), 947 aleph_member1(L,D), !, 948 NextLit is LitNum + 1, 949 find_last_ancestor(Lits,L,LitNum,NextLit,Last,M). 950find_last_ancestor([_|Lits],L,Last0,LitNum,Last,M):- 951 NextLit is LitNum + 1, 952 find_last_ancestor(Lits,L,Last0,NextLit,Last,M). 953 954% removal of literals that are repeated because of mode differences 955rm_moderepeats(_,_,M):- 956 M:'$aleph_sat_litinfo'(Lit1,_,Pred1,_,_,_), 957 M:'$aleph_sat_litinfo'(Lit2,_,Pred1,_,_,_), 958 Lit1 >= 1, Lit2 > Lit1, 959 retract(M:'$aleph_sat_litinfo'(Lit2,_,Pred1,_,_,_)), 960 asserta(M:'$aleph_local'(marked,Lit2/0)), 961 fail. 962rm_moderepeats(Last,N,M):- 963 M:'$aleph_local'(marked,_), !, 964 get_marked(1,Last,Lits,M), 965 length(Lits,N), 966 p1_message('repeated literals'), p_message(N/Last), 967 remove_lits(Lits,M). 968rm_moderepeats(_,0,_M). 969 970% removal of symmetric literals 971rm_symmetric(_,_,M):- 972 M:'$aleph_global'(symmetric,_), 973 M:'$aleph_sat_litinfo'(Lit1,_,Pred1,[I1|T1],_,_), 974 is_symmetric(Pred1,Name,Arity,M), 975 get_vars(Pred1,[I1|T1],S1), 976 M:'$aleph_sat_litinfo'(Lit2,_,Pred2,[I2|T2],_,_), 977 Lit1 \= Lit2, 978 is_symmetric(Pred2,Name,Arity,M), 979 Pred1 =.. [_|Args1], 980 Pred2 =.. [_|Args2], 981 symmetric_match(Args1,Args2), 982 get_vars(Pred2,[I2|T2],S2), 983 equal_set(S1,S2), 984 asserta(M:'$aleph_local'(marked,Lit2/0)), 985 retract(M:'$aleph_sat_litinfo'(Lit2,_,Pred2,[I2|T2],_,_)), 986 fail. 987rm_symmetric(Last,N,M):- 988 M:'$aleph_local'(marked,_), !, 989 get_marked(1,Last,Lits,M), 990 length(Lits,N), 991 p1_message('symmetric literals'), p_message(N/Last), 992 remove_lits(Lits,M). 993rm_symmetric(_,0,_M). 994 995is_symmetric(not(Pred),not(Name),Arity,M):- 996 !, 997 functor(Pred,Name,Arity), 998 M:'$aleph_global'(symmetric,symmetric(Name/Arity)). 999is_symmetric(Pred,Name,Arity,M):- 1000 functor(Pred,Name,Arity), 1001 M:'$aleph_global'(symmetric,symmetric(Name/Arity)). 1002 1003symmetric_match([],[]). 1004symmetric_match([aleph_const(Term)|Terms1],[aleph_const(Term)|Terms2]):- 1005 !, 1006 symmetric_match(Terms1,Terms2). 1007symmetric_match([Term1|Terms1],[Term2|Terms2]):- 1008 integer(Term1), integer(Term2), 1009 symmetric_match(Terms1,Terms2). 1010 1011% removal of literals that are repeated because of commutativity 1012rm_commutative(_,_,M):- 1013 M:'$aleph_global'(commutative,commutative(Name/Arity)), 1014 p1_message('checking commutative literals'), p_message(Name/Arity), 1015 functor(Pred,Name,Arity), functor(Pred1,Name,Arity), 1016 M:'$aleph_sat_litinfo'(Lit1,_,Pred,[I1|T1],O1,_), 1017 % check for marked literals 1018 % (SWI-Prolog specific: suggested by Vasili Vrubleuski) 1019 \+(M:'$aleph_local'(marked,Lit1/0)), 1020 get_vars(Pred,[I1|T1],S1), 1021 M:'$aleph_sat_litinfo'(Lit2,_,Pred1,[I2|T2],O2,_), 1022 Lit1 \= Lit2 , 1023 O1 = O2, 1024 get_vars(Pred1,[I2|T2],S2), 1025 equal_set(S1,S2), 1026 asserta(M:'$aleph_local'(marked,Lit2/0)), 1027 retract(M:'$aleph_sat_litinfo'(Lit2,_,Pred1,[I2|T2],_,_)), 1028 fail. 1029rm_commutative(Last,N,M):- 1030 M:'$aleph_local'(marked,_), !, 1031 get_marked(1,Last,Lits), 1032 length(Lits,N), 1033 p1_message('commutative literals'), p_message(N/Last), 1034 remove_lits(Lits). 1035rm_commutative(_,0,_M). 1036 1037% recursive marking of literals that do not contribute to establishing 1038% variable chains to output vars in the head 1039% or produce outputs that are not used by any literal 1040% controlled by setting flag check_useless 1041rm_uselesslits(_,0,M):- 1042 setting(check_useless,false,M), !. 1043rm_uselesslits(Last,N,M):- 1044 M:'$aleph_sat'(hovars,OVars), 1045 OVars \= [], !, 1046 get_predecessors(OVars,[],P,M), 1047 M:'$aleph_sat'(hivars,IVars), 1048 mark_lits(P,IVars,0,M), 1049 get_unmarked(1,Last,Lits,M), 1050 length(Lits,N), 1051 p1_message('useless literals'), p_message(N/Last), 1052 remove_lits(Lits,M). 1053rm_uselesslits(_,0,_M). 1054 1055% call user-defined predicate redundant/2 to remove redundant 1056% literals from bottom clause. Redundancy checking only done on request 1057rm_redundant(_,0,M):- 1058 setting(check_redundant,false,M), !. 1059rm_redundant(Last,N,M):- 1060 mark_redundant_lits(1,Last,M), 1061 get_marked(1,Last,Lits,M), 1062 length(Lits,N), 1063 p1_message('redundant literals'), p_message(N/Last), 1064 remove_lits(Lits,M). 1065 1066% get a list of unmarked literals 1067get_unmarked(Lit,Last,[],_M):- 1068 Lit > Last, !. 1069get_unmarked(Lit,Last,Lits,M):- 1070 retract(M:'$aleph_local'(marked,Lit/_)), !, 1071 Next is Lit + 1, 1072 get_unmarked(Next,Last,Lits,M). 1073get_unmarked(Lit,Last,[Lit|Lits],M):- 1074 retract(M:'$aleph_sat_litinfo'(Lit,_,_,_,_,_)), !, 1075 Next is Lit + 1, 1076 get_unmarked(Next,Last,Lits,M). 1077get_unmarked(Lit,Last,Lits,M):- 1078 Next is Lit + 1, 1079 get_unmarked(Next,Last,Lits,M). 1080 1081% get a list of marked literals 1082get_marked(Lit,Last,[],_M):- 1083 Lit > Last, !. 1084get_marked(Lit,Last,[Lit|Lits],M):- 1085 retract(M:'$aleph_local'(marked,Lit/_)), !, 1086 (retract(M:'$aleph_sat_litinfo'(Lit,_,_,_,_,_)) -> 1087 true; 1088 true), 1089 Next is Lit + 1, 1090 get_marked(Next,Last,Lits,M). 1091get_marked(Lit,Last,Lits,M):- 1092 Next is Lit + 1, 1093 get_marked(Next,Last,Lits,M). 1094 1095% update descendent lists of literals by removing useless literals 1096remove_lits(L,M):- 1097 retract(M:'$aleph_sat_litinfo'(Lit,Depth,A,I,O,D)), 1098 aleph_delete_list(L,D,D1), 1099 asserta(M:'$aleph_sat_litinfo'(Lit,Depth,A,I,O,D1)), 1100 fail. 1101remove_lits(_,_M). 1102 1103% generate a new literal at depth Depth: forced backtracking will give all lits 1104gen_layer(Name/Arity,Depth,M):- 1105 (Name/Arity = (not)/1 -> 1106 M:'$aleph_global'(modeb,modeb(NSucc,not(Mode))), 1107 functor(Mode,Name1,Arity1), 1108 functor(Lit1,Name1,Arity1), 1109 once(copy_modeterms(Mode,Lit1,Arity1)), 1110 Lit = not(Lit1); 1111 functor(Mode,Name,Arity), 1112 functor(Lit,Name,Arity), 1113 M:'$aleph_global'(modeb,modeb(NSucc,Mode)), 1114 once(copy_modeterms(Mode,Lit,Arity))), 1115 split_args(Mode,Mode,Input,Output,Constants,M), 1116 (Input = [] -> Call1 = true, Call2 = true; 1117 aleph_delete(Arg/Type,Input,OtherInputs), 1118 Depth1 is Depth - 1, 1119 construct_incall(Lit,Depth1,[Arg/Type],Call1,M), 1120 construct_call(Lit,Depth,OtherInputs,Call2,M)), 1121 , 1122 , 1123 aleph_background_predicate(Lit,M), 1124 get_successes(Lit,NSucc,mode(Mode,Input,Output,Constants),M), 1125 fail. 1126gen_layer(_,_,_M). 1127 1128get_successes(Literal,1,Mo,M):- 1129 depth_bound_call(Literal,M), 1130 update_atoms(Literal,Mo,M), !. 1131get_successes(Literal,*,Mo,M):- 1132 depth_bound_call(Literal,M), 1133 update_atoms(Literal,Mo,M). 1134get_successes(Literal,N,Mo,M):- 1135 integer(N), 1136 N > 1, 1137 reset_succ(M), 1138 get_nsuccesses(Literal,N,Mo,M). 1139 1140% get at most N matches for a literal 1141get_nsuccesses(Literal,N,Mo,M):- 1142 depth_bound_call(Literal,M), 1143 retract(M:'$aleph_local'(last_success,Succ0)), 1144 Succ0 < N, 1145 Succ1 is Succ0 + 1, 1146 update_atoms(Literal,Mo,M), 1147 asserta(M:'$aleph_local'(last_success,Succ1)), 1148 (Succ1 >= N -> !; true). 1149 1150update_atoms(Atom,Mo,M):- 1151 M:'$aleph_sat_atom'(Atom,Mo), !. 1152update_atoms(Atom,Mo,M):- 1153 assertz(M:'$aleph_sat_atom'(Atom,Mo)). 1154 1155% call with input term that is an ouput of a previous literal 1156construct_incall(_,_,[],true,_M):- !. 1157construct_incall(not(Lit),Depth,Args,Call,M):- 1158 !, 1159 construct_incall(Lit,Depth,Args,Call,M). 1160construct_incall(Lit,Depth,[Pos/Type],Call,M):- 1161 !, 1162 Call = legal_term(exact,Depth,Type,Term,M), 1163 tparg(Pos,Lit,Term). 1164construct_incall(Lit,Depth,[Pos/Type|Args],(Call,Calls),M):- 1165 tparg(Pos,Lit,Term), 1166 Call = legal_term(exact,Depth,Type,Term,M), 1167 (var(Depth)-> construct_incall(Lit,_,Args,Calls,M); 1168 construct_incall(Lit,Depth,Args,Calls,M)). 1169 1170construct_call(_,_,[],true,_M):- !. 1171construct_call(not(Lit),Depth,Args,Call,M):- 1172 !, 1173 construct_call(Lit,Depth,Args,Call,M). 1174construct_call(Lit,Depth,[Pos/Type],Call,M):- 1175 !, 1176 Call = legal_term(upper,Depth,Type,Term,M), 1177 tparg(Pos,Lit,Term). 1178construct_call(Lit,Depth,[Pos/Type|Args],(Call,Calls),M):- 1179 tparg(Pos,Lit,Term), 1180 Call = legal_term(upper,Depth,Type,Term,M), 1181 construct_call(Lit,Depth,Args,Calls,M). 1182 1183% generator of legal terms seen so far 1184legal_term(exact,Depth,Type,Term,M):- 1185 M:'$aleph_sat_terms'(TNo,Depth,Term,Type), 1186 once(M:'$aleph_sat_vars'(_,TNo,_,[_|_])). 1187% legal_term(exact,Depth,Type,Term):- 1188 % M:'$aleph_sat_varscopy'(NewVar,OldVar,Depth), 1189 % once(M:'$aleph_sat_vars'(NewVar,TNo,_,_)), 1190 % M:'$aleph_sat_terms'(TNo,_,Term,Type),_). 1191legal_term(upper,Depth,Type,Term,M):- 1192 M:'$aleph_sat_terms'(TNo,Depth1,Term,Type), 1193 Depth1 \= unknown, 1194 Depth1 < Depth, 1195 once(M:'$aleph_sat_vars'(_,TNo,_,[_|_])). 1196% legal_term(upper,Depth,Type,Term):- 1197 % M:'$aleph_sat_varscopy'(NewVar,OldVar,Depth), 1198 % once(M:'$aleph_sat_vars'(NewVar,TNo,_,_)), 1199 % M:'$aleph_sat_terms'(TNo,Depth1,Term,Type), 1200 % Depth1 \= unknown. 1201 1202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1203% V A R I A B L E -- S P L I T T I N G 1204 1205 1206split_vars(Depth,FAtom,I,O,C,SplitAtom,IVars,OVars,Equivs,M):- 1207 setting(splitvars,true,M), !, 1208 get_args(FAtom,I,[],IVarList), 1209 get_args(FAtom,O,[],OVarList), 1210 get_var_equivs(Depth,IVarList,OVarList,IVars,OVars0,Equivs0), 1211 (Equivs0 = [] -> 1212 OVars = OVars0, SplitAtom = FAtom, Equivs = Equivs0; 1213 functor(FAtom,Name,Arity), 1214 functor(SplitAtom,Name,Arity), 1215 copy_args(FAtom,SplitAtom,I), 1216 copy_args(FAtom,SplitAtom,C), 1217 rename_ovars(O,Depth,FAtom,SplitAtom,Equivs0,Equivs), 1218 get_argterms(SplitAtom,O,[],OVars)). 1219 % write('splitting: '), write(FAtom), write(' to: '), write(SplitAtom), nl. 1220split_vars(_,FAtom,I,O,_,FAtom,IVars,OVars,[],_M):- 1221 get_vars(FAtom,I,IVars), 1222 get_vars(FAtom,O,OVars). 1223 1224% get equivalent classes of variables from co-references 1225get_var_equivs(Depth,IVarList,OVarList,IVars,OVars,Equivs):- 1226 sort(IVarList,IVars), 1227 sort(OVarList,OVars), 1228 (Depth = 0 -> 1229 intersect1(IVars,OVarList,IOCoRefs,_), 1230 get_repeats(IVarList,IOCoRefs,ICoRefs); 1231 intersect1(IVars,OVarList,ICoRefs,_)), 1232 get_repeats(OVarList,ICoRefs,CoRefs), 1233 add_equivalences(CoRefs,Depth,Equivs). 1234 1235add_equivalences([],_,[]). 1236add_equivalences([Var|Vars],Depth,[Var/E|Rest]):- 1237 % (Depth = 0 -> E = []; E = [Var]), 1238 E = [Var], 1239 add_equivalences(Vars,Depth,Rest). 1240 1241 1242get_repeats([],L,L). 1243get_repeats([Var|Vars],Ref1,L):- 1244 aleph_member1(Var,Vars), !, 1245 update(Ref1,Var,Ref2), 1246 get_repeats(Vars,Ref2,L). 1247get_repeats([_|Vars],Ref,L):- 1248 get_repeats(Vars,Ref,L). 1249 1250% rename all output vars that are co-references 1251% updates vars database and return equivalent class of variables 1252rename_ovars([],_,_,_,L,L). 1253rename_ovars([ArgNo|Args],Depth,Old,New,CoRefs,Equivalences):- 1254 (ArgNo = Pos/_ -> true; Pos = ArgNo), 1255 tparg(Pos,Old,OldVar), 1256 aleph_delete(OldVar/Equiv,CoRefs,Rest), !, 1257 copy_var(OldVar,NewVar,Depth), 1258 tparg(Pos,New,NewVar), 1259 rename_ovars(Args,Depth,Old,New,[OldVar/[NewVar|Equiv]|Rest],Equivalences). 1260rename_ovars([ArgNo|Args],Depth,Old,New,CoRefs,Equivalences):- 1261 (ArgNo = Pos/_ -> true; Pos = ArgNo), 1262 tparg(Pos,Old,OldVar), 1263 tparg(Pos,New,OldVar), 1264 rename_ovars(Args,Depth,Old,New,CoRefs,Equivalences). 1265 1266% create new equalities to allow co-references to re-appear in search 1267insert_eqs([],_,L,L,_M). 1268insert_eqs([OldVar/Equivs|Rest],Depth,Last,NewLast,M):- 1269 M:'$aleph_sat_vars'(OldVar,TNo,_,_), 1270 M:'$aleph_sat_terms'(TNo,_,_,Type), 1271 add_eqs(Equivs,Depth,Type,Last,Last1,M), 1272 insert_eqs(Rest,Depth,Last1,NewLast,M). 1273 1274add_eqs([],_,_,L,L,_M). 1275add_eqs([V1|Rest],Depth,Type,Last,NewLast,M):- 1276 add_eqs(Rest,Depth,V1,Type,Last,Last1,M), 1277 add_eqs(Rest,Depth,Type,Last1,NewLast,M). 1278 1279add_eqs([],_,_,_,L,L,_M). 1280add_eqs([Var2|Rest],Depth,Var1,Type,Last,NewLast,M):- 1281 (Depth = 0 -> 1282 add_lit(Last,false,(Var1=Var2),[1/Type],[2/Type],[Var1],[Var2],Last1,M); 1283 add_lit(Last,false,(Var1=Var2),[1/Type,2/Type],[],[Var1,Var2],[],Last1),), 1284 add_eqs(Rest,Depth,Var1,Type,Last1,NewLast,M). 1285 1286 1287 1288%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1289% utilities for updating mappings between terms and variables 1290 1291% integrate terms specified by a list of arguments 1292% integrating a term means: 1293% updating 2 databases: terms and vars 1294% terms contains the term along with a term-id 1295% vars contains a var-id <-> term-id mapping 1296% var and term-ids are integers 1297integrate_args(_,_,[],_M):-!. 1298integrate_args(Depth,Literal,[Pos/Type|T],M):- 1299 tparg(Pos,Literal,Term), 1300 integrate_term(Depth,Term/Type,M), 1301 (retract(M:'$aleph_sat_terms'(TNo,Depth,Term,unknown)) -> 1302 asserta(M:'$aleph_sat_terms'(TNo,Depth,Term,Type)); 1303 true), 1304 integrate_args(Depth,Literal,T,M). 1305 1306 1307% integrate a term 1308integrate_term(Depth,Term/Type,M):- 1309 M:'$aleph_sat_terms'(TNo,Depth,Term,Type), 1310 M:'$aleph_sat_vars'(_,TNo,_,[_|_]), !. 1311integrate_term(Depth,Term/Type,M):- 1312 M:'$aleph_sat_terms'(TNo,Depth1,Term,Type), 1313 (Type = unknown ; M:'$aleph_sat_vars'(_,TNo,_,[])), !, 1314 (Depth1 = unknown -> 1315 retract(M:'$aleph_sat_terms'(TNo,Depth1,Term,Type)), 1316 asserta(M:'$aleph_sat_terms'(TNo,Depth,Term,Type)); 1317 true). 1318integrate_term(_,Term/Type,M):- 1319 M:'$aleph_sat_terms'(_,_,Term,Type), 1320 Type \= unknown, 1321 !. 1322integrate_term(Depth,Term/Type,M):- 1323 retract(M:'$aleph_sat'(lastterm,Num)), 1324 retract(M:'$aleph_sat'(lastvar,Var0)), 1325 TNo is Num + 1, 1326 Var is Var0 + 1, 1327 asserta(M:'$aleph_sat'(lastterm,TNo)), 1328 asserta(M:'$aleph_sat'(lastvar,Var)), 1329 asserta(M:'$aleph_sat_vars'(Var,TNo,[],[])), 1330 asserta(M:'$aleph_sat_terms'(TNo,Depth,Term,Type)). 1331 1332 1333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1334 1335% split_args(+Lit,?Mode,-Input,-Output,-Constants) 1336% return term-places and types of +,-, and # args in Lit 1337% by finding a matching mode declaration if Mode is given 1338% otherwise first mode that matches is used 1339split_args(Lit,Mode,Input,Output,Constants,M):- 1340 functor(Lit,Psym,Arity), 1341 find_mode(mode,Psym/Arity,Mode,M), 1342 functor(Template,Psym,Arity), 1343 copy_modeterms(Mode,Template,Arity), 1344 Template = Lit, 1345 tp(Mode,TPList), 1346 split_tp(TPList,Input,Output,Constants). 1347 1348% split_tp(+TPList,-Input,-Output,-Constants) 1349% split term-place/type list into +,-,# 1350split_tp([],[],[],[]). 1351split_tp([(+Type)/Place|TP],[Place/Type|Input],Output,Constants):- 1352 !, 1353 split_tp(TP,Input,Output,Constants). 1354split_tp([(-Type)/Place|TP],Input,[Place/Type|Output],Constants):- 1355 !, 1356 split_tp(TP,Input,Output,Constants). 1357split_tp([(#Type)/Place|TP],Input,Output,[Place/Type|Constants]):- 1358 !, 1359 split_tp(TP,Input,Output,Constants). 1360split_tp([_|TP],Input,Output,Constants):- 1361 split_tp(TP,Input,Output,Constants). 1362 1363% tp(+Literal,-TPList) 1364% return terms and places in Literal 1365tp(Literal,TPList):- 1366 functor(Literal,_,Arity), 1367 tp_list(Literal,Arity,[],[],TPList). 1368 1369tp_list(_,0,_,L,L):- !. 1370tp_list(Term,Pos,PlaceList,TpSoFar,TpList):- 1371 arg(Pos,Term,Arg), 1372 aleph_append([Pos],PlaceList,Places), 1373 unwrap_term(Arg,Places,[Arg/Places|TpSoFar],L1), 1374 Pos1 is Pos - 1, 1375 tp_list(Term,Pos1,PlaceList,L1,TpList). 1376 1377unwrap_term(Term,_,L,L):- 1378 var(Term), !. 1379unwrap_term(Term,Place,TpSoFar,TpList):- 1380 functor(Term,_,Arity), 1381 tp_list(Term,Arity,Place,TpSoFar,TpList). 1382 1383get_determs(PSym/Arity,L,M):- 1384 findall(Pred,M:'$aleph_global'(determination,determination(PSym/Arity,Pred)),L). 1385 1386get_modes(PSym/Arity,L,M):- 1387 functor(Lit,PSym,Arity), 1388 findall(Lit,M:'$aleph_global'(mode,mode(_,Lit)),L). 1389 1390 1391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1392% S E A R C H 1393 1394% basic search engine for single clause search 1395search(S,Nodes,M):- 1396 arg(36,S,Time), 1397 Inf is inf, 1398 Time =\= Inf, 1399 SearchTime is integer(Time), 1400 SearchTime > 0, !, 1401 catch(time_bound_call(SearchTime,searchlimit,graphsearch(S,_),M), 1402 searchlimit,p_message('Time limit reached')), 1403 M:'$aleph_search'(current,current(_,Nodes,_)). 1404search(S,Nodes,M):- 1405 graphsearch(S,Nodes,M). 1406 1407% basic search engine for theory-based search 1408tsearch(S,Nodes,M):- 1409 arg(36,S,Time), 1410 Inf is inf, 1411 Time =\= Inf, 1412 SearchTime is integer(Time), 1413 SearchTime > 0, !, 1414 alarm(SearchTime,throw(searchlimit),Id), 1415 catch(theorysearch(S,Nodes,M),searchlimit,p_message('Time limit reached')), 1416 remove_alarm(Id). 1417tsearch(S,Nodes,M):- 1418 theorysearch(S,Nodes,M). 1419 1420graphsearch(S,Nodes,M):- 1421 next_node(_,M), !, 1422 arg(3,S,RefineOp), 1423 arg(23,S,LazyPreds), 1424 repeat, 1425 next_node(NodeRef,M), 1426 once(retract(M:'$aleph_search'(current,current(LastE,Last,BestSoFar)))), 1427 expand(RefineOp,S,NodeRef,Node,Path,MinLength,Succ,PosCover,NegCover,OVars, 1428 PrefixClause,PrefixTV,PrefixLength,M), 1429 ((LazyPreds = []; RefineOp \= false) -> Succ1 = Succ; 1430 lazy_evaluate(Succ,LazyPreds,Path,PosCover,NegCover,Succ1,M)), 1431 NextE is LastE + 1, 1432 get_gains(S,Last,BestSoFar,Path,PrefixClause,PrefixTV,PrefixLength, 1433 MinLength,Succ1,PosCover,NegCover,OVars,NextE,Last0,NextBest0,M), 1434 (RefineOp = false -> 1435 get_sibgains(S,Node,Last0,NextBest0,Path,PrefixClause, 1436 PrefixTV,PrefixLength,MinLength,PosCover,NegCover, 1437 OVars,NextE,Last1,NextBest,M); 1438 Last1 = Last0, NextBest = NextBest0), 1439 asserta(M:'$aleph_search'(current,current(NextE,Last1,NextBest))), 1440 NextL is Last + 1, 1441 asserta(M:'$aleph_search_expansion'(NextE,Node,NextL,Last1)), 1442 (discontinue_search(S,NextBest,Last1,M) -> 1443 M:'$aleph_search'(current,current(_,Nodes,_)); 1444 prune_open(S,BestSoFar,NextBest,M), 1445 get_nextbest(S,Next,M), 1446 Next = none, 1447 M:'$aleph_search'(current,current(_,Nodes,_))), 1448 !. 1449graphsearch(_,Nodes,M):- 1450 M:'$aleph_search'(current,current(_,Nodes,_)). 1451 1452theorysearch(S,Nodes,M):- 1453 next_node(_,M), !, 1454 M:'$aleph_global'(atoms,atoms(pos,Pos)), 1455 M:'$aleph_global'(atoms,atoms(neg,Neg)), 1456 interval_count(Pos,P,M), 1457 interval_count(Neg,N,M), 1458 repeat, 1459 next_node(NodeRef,M), 1460 M:'$aleph_search_node'(NodeRef,Theory,_,_,_,_,_,_), 1461 once(retract(M:'$aleph_search'(current,current(_,Last,BestSoFar)))), 1462 get_theory_gain(S,Last,BestSoFar,Theory,Pos,Neg,P,N,NextBest,Last1,M), 1463 asserta(M:'$aleph_search'(current,current(0,Last1,NextBest))), 1464 (discontinue_search(S,NextBest,Last1,M) -> 1465 M:'$aleph_search'(current,current(_,Nodes,_)); 1466 prune_open(S,BestSoFar,NextBest,M), 1467 get_nextbest(S,Next,M), 1468 Next = none, 1469 M:'$aleph_search'(current,current(_,Nodes,_))), 1470 !. 1471theorysearch(_,Nodes,M):- 1472 M:'$aleph_search'(current,current(_,Nodes,_)). 1473 1474next_node(NodeRef,M):- 1475 once(M:'$aleph_search'(nextnode,NodeRef)), !. 1476 1477get_search_settings(S,M):- 1478 functor(S,set,47), 1479 setting(nodes,MaxNodes,M), arg(1,S,MaxNodes), 1480 setting(explore,Explore,M), arg(2,S,Explore), 1481 setting(refineop,RefineOp,M), arg(3,S,RefineOp), 1482 setting(searchstrat,SearchStrat,M), setting(evalfn,EvalFn,M), 1483 arg(4,S,SearchStrat/EvalFn), 1484 (setting(greedy,Greedy,M)-> arg(5,S,Greedy); arg(5,S,false)), 1485 setting(verbosity,Verbose,M), arg(6,S,Verbose), 1486 setting(clauselength,CLength,M), arg(7,S,CLength), 1487 setting(caching,Cache,M), arg(8,S,Cache), 1488 (setting(prune_defs,Prune,M)-> arg(9,S,Prune); arg(9,S,false)), 1489 setting(lazy_on_cost,LCost,M), arg(10,S,LCost), 1490 setting(lazy_on_contradiction,LContra,M), arg(11,S,LContra), 1491 setting(lazy_negs,LNegs,M), arg(12,S,LNegs), 1492 setting(minpos,MinPos,M), arg(13,S,MinPos), 1493 setting(depth,Depth,M), arg(14,S,Depth), 1494 setting(cache_clauselength,CCLim,M), arg(15,S,CCLim), 1495 (M:'$aleph_global'(size,size(pos,PSize))-> arg(16,S,PSize); arg(16,S,0)), 1496 setting(noise,Noise,M), arg(17,S,Noise), 1497 setting(minacc,MinAcc,M), arg(18,S,MinAcc), 1498 setting(minscore,MinScore,M), arg(19,S,MinScore), 1499 (M:'$aleph_global'(size,size(rand,RSize))-> arg(20,S,RSize); arg(20,S,0)), 1500 setting(mingain,MinGain,M), arg(21,S,MinGain), 1501 setting(search,Search,M), arg(22,S,Search), 1502 findall(PN/PA,M:'$aleph_global'(lazy_evaluate,lazy_evaluate(PN/PA)),LazyPreds), 1503 arg(23,S,LazyPreds), 1504 (M:'$aleph_global'(size,size(neg,NSize))-> arg(24,S,NSize); arg(24,S,0)), 1505 setting(openlist,OSize,M), arg(25,S,OSize), 1506 setting(check_redundant,RCheck,M), arg(26,S,RCheck), 1507 (M:'$aleph_sat'(eq,Eq) -> arg(27,S,Eq); arg(27,S,false)), 1508 (M:'$aleph_sat'(hovars,HOVars) -> arg(28,S,HOVars); arg(28,S,_HOVars)), 1509 setting(prooftime,PTime,M), arg(29,S,PTime), 1510 setting(construct_bottom,CBott,M), arg(30,S,CBott), 1511 (get_ovars1(false,1,HIVars,M) -> arg(31,S,HIVars); arg(31,S,[])), 1512 setting(language,Lang,M), arg(32,S,Lang), 1513 setting(splitvars,Split,M), arg(33,S,Split), 1514 setting(proof_strategy,Proof,M), arg(34,S,Proof), 1515 setting(portray_search,VSearch,M), arg(35,S,VSearch), 1516 setting(searchtime,Time,M), arg(36,S,Time), 1517 setting(optimise_clauses,Optim,M), arg(37,S,Optim), 1518 setting(newvars,NewV,M), arg(38,S,NewV), 1519 (setting(rls_type,RlsType,M) -> arg(39,S,RlsType);arg(39,S,false,M)), 1520 setting(minposfrac,MinPosFrac,M), arg(40,S,MinPosFrac), 1521 (setting(recursion,_Recursion,M) -> true; _Recursion = false), 1522 prolog_type(Prolog), arg(41,S,Prolog), 1523 setting(interactive,Interactive,M), arg(42,S,Interactive), 1524 setting(lookahead,LookAhead,M), arg(43,S,LookAhead), 1525 (setting(construct_features,Features,M)-> arg(44,S,Features); arg(44,S,false)), 1526 setting(max_features,FMax,M), arg(45,S,FMax), 1527 setting(subsample,SS,M), arg(46,S,SS), 1528 setting(subsamplesize,SSize,M), arg(47,S,SSize). 1529 1530% stop search from proceeding if certain 1531% conditions are reached. These are: 1532% . minacc and minpos values reached in rrr search 1533% . best hypothesis has accuracy 1.0 if evalfn=accuracy 1534% . best hypothesis covers all positive examples 1535discontinue_search(S,[P,_,_,F|_]/_,_,_M):- 1536 arg(39,S,RlsType), 1537 RlsType = rrr, 1538 arg(13,S,MinPos), 1539 P >= MinPos, 1540 arg(19,S,MinScore), 1541 F >= MinScore, !. 1542discontinue_search(S,_,Nodes,_M):- 1543 arg(1,S,MaxNodes), 1544 Nodes >= MaxNodes, !, 1545 p_message('node limit reached'). 1546discontinue_search(S,_,_,M):- 1547 arg(44,S,Features), 1548 Features = true, 1549 arg(45,S,FMax), 1550 M:'$aleph_search'(last_good,LastGood), 1551 LastGood >= FMax, !, 1552 p_message('feature limit reached'). 1553discontinue_search(S,[_,_,_,F|_]/_,_,_M):- 1554 arg(4,S,_/Evalfn), 1555 Evalfn = accuracy, 1556 F = 1.0, !. 1557discontinue_search(S,Best,_,_M):- 1558 arg(2,S,Explore), 1559 Explore = false, 1560 arg(4,S,_/Evalfn), 1561 Evalfn \= user, 1562 Evalfn \= posonly, 1563 arg(22,S,Search), 1564 Search \= ic, 1565 Best = [P|_]/_, 1566 arg(16,S,P). 1567 1568update_max_head_count(N,0,M):- 1569 retractall(M:'$aleph_local'(max_head_count,_)), 1570 asserta(M:'$aleph_local'(max_head_count,N)), !. 1571update_max_head_count(Count,Last,M):- 1572 M:'$aleph_search_node'(Last,LitNum,_,_,PosCover,_,_,_), !, 1573 asserta(M:'$aleph_local'(head_lit,LitNum)), 1574 interval_count(PosCover,N), 1575 Next is Last - 1, 1576 (N > Count -> update_max_head_count(N,Next,M); 1577 update_max_head_count(Count,Next,M)). 1578update_max_head_count(Count,Last,M):- 1579 Next is Last - 1, 1580 update_max_head_count(Count,Next,M). 1581 1582expand(false,S,NodeRef,NodeRef,Path1,Length,Descendents,PosCover,NegCover,OVars,C,TV,CL,M):- 1583 !, 1584 M:'$aleph_search_node'(NodeRef,LitNum,Path,Length/_,PCover,NCover,OVars,_), 1585 arg(46,S,SSample), 1586 (SSample = false -> PosCover = PCover, NegCover = NCover; 1587 get_sample_cover(S,PosCover,NegCover,M)), 1588 aleph_append([LitNum],Path,Path1), 1589 get_pclause(Path1,[],C,TV,CL,_,M), 1590 M:'$aleph_sat_litinfo'(LitNum,_,_,_,_,Dependents), 1591 intersect1(Dependents,Path1,_,Succ), 1592 check_parents(Succ,OVars,Descendents,_,M). 1593expand(_,S,NodeRef,NodeRef,Path1,Length,[_],PosCover,NegCover,OVars,_,_,_,M):- 1594 retract(M:'$aleph_search_node'(NodeRef,_,Path1,Length/_,_,_,OVars,_)), 1595 get_sample_cover(S,PosCover,NegCover,M). 1596 1597get_sample_cover(S,PosCover,NegCover,M):- 1598 arg(5,S,Greedy), 1599 (Greedy = true -> 1600 M:'$aleph_global'(atoms_left,atoms_left(pos,PCover)); 1601 arg(16,S,PSize), 1602 PCover = [1-PSize]), 1603 arg(4,S,_/Evalfn), 1604 (Evalfn = posonly -> 1605 M:'$aleph_global'(atoms_left,atoms_left(rand,NCover)); 1606 arg(24,S,NSize), 1607 NCover = [1-NSize]), 1608 arg(46,S,SSample), 1609 (SSample = false -> PosCover = PCover, NegCover = NCover; 1610 arg(47,S,SampleSize), 1611 interval_sample(SampleSize,PCover,PosCover,M), 1612 interval_sample(SampleSize,NCover,NegCover,M)). 1613 1614get_ovars([],_,V,V,_M). 1615get_ovars([LitNum|Lits],K,VarsSoFar,Vars,M):- 1616 get_ovars1(K,LitNum,OVars,M), 1617 aleph_append(VarsSoFar,OVars,Vars1), 1618 get_ovars(Lits,K,Vars1,Vars,M). 1619 1620get_ovars1(false,LitNum,OVars,M):- 1621 M:'$aleph_sat_ovars'(LitNum,OVars), !. 1622get_ovars1(false,LitNum,OVars,M):- 1623 !, 1624 M:'$aleph_sat_litinfo'(LitNum,_,Atom,_,O,_), 1625 get_vars(Atom,O,OVars). 1626get_ovars1(K,LitNum,OVars,M):- 1627 M:'$aleph_sat_ovars'(LitNum,K,OVars), !. 1628get_ovars1(K,LitNum,OVars,M):- 1629 M:'$aleph_sat_litinfo'(LitNum,K,_,Atom,_,O,_), 1630 get_vars(Atom,O,OVars). 1631 1632% get set of vars at term-places specified 1633get_vars(not(Literal),Args,Vars):- 1634 !, 1635 get_vars(Literal,Args,Vars). 1636get_vars(_,[],[]). 1637get_vars(Literal,[ArgNo|Args],Vars):- 1638 (ArgNo = Pos/_ -> true; Pos = ArgNo), 1639 tparg(Pos,Literal,Term), 1640 get_vars_in_term([Term],TV1), 1641 get_vars(Literal,Args,TV2), 1642 update_list(TV2,TV1,Vars). 1643 1644get_vars_in_term([],[]). 1645get_vars_in_term([Var|Terms],[Var|TVars]):- 1646 integer(Var), !, 1647 get_vars_in_term(Terms,TVars). 1648get_vars_in_term([Term|Terms],TVars):- 1649 Term =.. [_|Terms1], 1650 get_vars_in_term(Terms1,TV1), 1651 get_vars_in_term(Terms,TV2), 1652 update_list(TV2,TV1,TVars). 1653 1654% get terms at term-places specified 1655% need not be variables 1656get_argterms(not(Literal),Args,TermsSoFar,Terms):- 1657 !, 1658 get_argterms(Literal,Args,TermsSoFar,Terms). 1659get_argterms(_,[],Terms,Terms). 1660get_argterms(Literal,[ArgNo|Args],TermsSoFar,Terms):- 1661 (ArgNo = Pos/_ -> true; Pos = ArgNo), 1662 tparg(Pos,Literal,Term), 1663 update(TermsSoFar,Term,T1), 1664 get_argterms(Literal,Args,T1,Terms). 1665 1666% get list of terms at arg positions specified 1667get_args(not(Literal),Args,TermsSoFar,Terms):- 1668 !, 1669 get_args(Literal,Args,TermsSoFar,Terms). 1670get_args(_,[],Terms,Terms). 1671get_args(Literal,[ArgNo|Args],TermsSoFar,Terms):- 1672 (ArgNo = Pos/_ -> true; Pos = ArgNo), 1673 tparg(Pos,Literal,Term), 1674 get_args(Literal,Args,[Term|TermsSoFar],Terms). 1675 1676 1677get_ivars([],_,V,V,_M). 1678get_ivars([LitNum|Lits],K,VarsSoFar,Vars,M):- 1679 get_ivars1(K,LitNum,IVars,M), 1680 aleph_append(VarsSoFar,IVars,Vars1), 1681 get_ivars(Lits,K,Vars1,Vars,M). 1682 1683get_ivars1(false,LitNum,IVars,M):- 1684 M:'$aleph_sat_ivars'(LitNum,IVars), !. 1685get_ivars1(false,LitNum,IVars,M):- 1686 !, 1687 M:'$aleph_sat_litinfo'(LitNum,_,Atom,I,_,_), 1688 get_vars(Atom,I,IVars). 1689get_ivars1(K,LitNum,IVars,M):- 1690 M:'$aleph_sat_ivars'(LitNum,K,IVars), !. 1691get_ivars1(K,LitNum,IVars,M):- 1692 M:'$aleph_sat_litinfo'(LitNum,K,_,Atom,I,_,_), 1693 get_vars(Atom,I,IVars). 1694 1695check_parents([],_,[],[],_M). 1696check_parents([LitNum|Lits],OutputVars,[LitNum|DLits],Rest,M):- 1697 get_ivars1(false,LitNum,IVars,M), 1698 aleph_subset1(IVars,OutputVars), !, 1699 check_parents(Lits,OutputVars,DLits,Rest,M). 1700check_parents([LitNum|Lits],OutputVars,DLits,[LitNum|Rest],M):- 1701 check_parents(Lits,OutputVars,DLits,Rest,M), !. 1702 1703get_gains(S,Last,Best,_,_,_,_,_,_,_,_,_,_,Last,Best,M):- 1704 discontinue_search(S,Best,Last,M), !. 1705get_gains(_,Last,Best,_,_,_,_,_,[],_,_,_,_,Last,Best,_M):- !. 1706get_gains(S,Last,Best,Path,C,TV,L,Min,[L1|Succ],Pos,Neg,OVars,E,Last1,NextBest,M):- 1707 get_gain(S,upper,Last,Best,Path,C,TV,L,Min,L1,Pos,Neg,OVars,E,Best1,Node1,M), !, 1708 get_gains(S,Node1,Best1,Path,C,TV,L,Min,Succ,Pos,Neg,OVars,E,Last1,NextBest,M). 1709get_gains(S,Last,BestSoFar,Path,C,TV,L,Min,[_|Succ],Pos,Neg,OVars,E,Last1,NextBest,M):- 1710 get_gains(S,Last,BestSoFar,Path,C,TV,L,Min,Succ,Pos,Neg,OVars,E,Last1,NextBest,M), 1711 !. 1712 1713get_sibgains(S,Node,Last,Best,Path,C,TV,L,Min,Pos,Neg,OVars,E,Last1,NextBest,M):- 1714 M:'$aleph_search_node'(Node,LitNum,_,_,_,_,_,OldE), 1715 M:'$aleph_search_expansion'(OldE,_,_,LastSib), 1716 M:'$aleph_sat_litinfo'(LitNum,_,_,_,_,Desc), 1717 Node1 is Node + 1, 1718 arg(31,S,HIVars), 1719 aleph_delete_list(HIVars,OVars,LVars), 1720 get_sibgain(S,LVars,LitNum,Desc,Node1,LastSib,Last, 1721 Best,Path,C,TV,L,Min,Pos,Neg,OVars,E,NextBest,Last1,M), !. 1722 1723get_sibgain(S,_,_,_,Node,Node1,Last,Best,_,_,_,_,_,_,_,_,_,Best,Last,M):- 1724 (Node > Node1; 1725 discontinue_search(S,Best,Last,M)), !. 1726get_sibgain(S,LVars,LitNum,Desc,Node,LastSib,Last,Best,Path,C,TV,L,Min,Pos,Neg,OVars,E,LBest,LNode,M):- 1727 arg(23,S,Lazy), 1728 get_sibpncover(Lazy,Node,Desc,Pos,Neg,Sib1,PC,NC,M), 1729 lazy_evaluate([Sib1],Lazy,Path,PC,NC,[Sib],M), 1730 get_ivars1(false,Sib,SibIVars,M), 1731 (intersects(SibIVars,LVars) -> Flag = upper; 1732 get_ovars1(false,Sib,SibOVars,M), 1733 (intersects(SibOVars,LVars) -> Flag = upper; Flag = exact)), 1734 get_gain(S,Flag,Last,Best,Path,C,TV,L,Min,Sib,PC,NC,OVars,E,Best1,Node1,M), !, 1735 NextNode is Node + 1, 1736 get_sibgain(S,LVars,LitNum,Desc,NextNode,LastSib,Node1,Best1,Path,C,TV,L, 1737 Min,Pos,Neg,OVars,E,LBest,LNode,M), !. 1738get_sibgain(S,LVars,LitNum,Desc,Node,LastSib,Last,Best,Path,C,TV,L,Min,Pos,Neg,OVars,E,Best1,Node1,M):- 1739 NextNode is Node + 1, 1740 get_sibgain(S,LVars,LitNum,Desc,NextNode,LastSib,Last,Best,Path,C,TV,L, 1741 Min,Pos,Neg,OVars,E,Best1,Node1,M), !. 1742 1743 1744get_sibgain(S,LVars,LitNum,Node,LastSib,Last,Best,Path,C,TV,L,Min,Pos,Neg,OVars,E,Best1,Node1,M):- 1745 NextNode is Node + 1, 1746 get_sibgain(S,LVars,LitNum,NextNode,LastSib,Last,Best,Path,C,TV,L,Min,Pos,Neg, 1747 OVars,E,Best1,Node1,M), !. 1748 1749get_sibpncover(Lazy,NodeNum,Desc,Pos,Neg,Sib,PC,NC,M):- 1750 M:'$aleph_search_node'(NodeNum,Sib,_,_,Pos1,Neg1,_,_), 1751 M:'$aleph_sat_litinfo'(Sib,_,Atom,_,_,_), 1752 \+(aleph_member1(Sib,Desc)), 1753 functor(Atom,Name,Arity), 1754 (aleph_member1(Name/Arity,Lazy) -> 1755 PC = Pos, NC = Neg; 1756 calc_intersection(Pos,Pos1,PC), 1757 calc_intersection(Neg,Neg1,NC)). 1758 1759% in some cases, it is possible to simply use the intersection of 1760% covers cached. The conditions under which this is possible was developed 1761% in discussions with James Cussens 1762calc_intersection(A1/[B1-L1],A2/[B2-L2],A/[B-L]):- 1763 !, 1764 intervals_intersection(A1,A2,A), 1765 B3 is max(B1,B2), 1766 (intervals_intersects(A1,[B2-L2],X3-_) -> true; X3 = B3), 1767 (intervals_intersects(A2,[B1-L1],X4-_) -> true; X4 = B3), 1768 B4 is min(X3,B3), 1769 B is min(X4,B4), 1770 L is max(L1,L2). 1771calc_intersection(A1/_,A2,A):- 1772 !, 1773 intervals_intersection(A1,A2,A). 1774calc_intersection(A1,A2/_,A):- 1775 !, 1776 intervals_intersection(A1,A2,A). 1777calc_intersection(A1,A2,A):- 1778 intervals_intersection(A1,A2,A). 1779 1780get_gain(S,_,Last,Best,Path,_,_,_,MinLength,_,Pos,Neg,OVars,E,Best1,NewLast,M):- 1781 arg(3,S,RefineOp), 1782 RefineOp \= false , !, 1783 get_refine_gain(S,Last,Best,Path,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M). 1784get_gain(S,Flag,Last,Best/Node,Path,C,TV,Len1,MinLen,L1,Pos,Neg,OVars,E,Best1,Last1,M):- 1785 arg(26,S,RCheck), 1786 arg(33,S,SplitVars), 1787 retractall(M:'$aleph_search'(covers,_)), 1788 retractall(M:'$aleph_search'(coversn,_)), 1789 get_pclause([L1],TV,Lit1,_,Len2,LastD,M), 1790 split_ok(SplitVars,C,Lit1), !, 1791 extend_clause(C,Lit1,Clause), 1792 (RCheck = true -> 1793 (redundant(Clause,Lit1,M) -> fail; true); 1794 true), 1795 CLen is Len1 + Len2, 1796 length_ok(S,MinLen,CLen,LastD,EMin,ELength), 1797 % arg(41,S,Prolog), 1798 split_clause(Clause,Head,Body), 1799 % (Prolog = yap -> 1800 % assertz(M:'$aleph_search'(pclause,pclause(Head,Body)),DbRef); 1801 % assertz(M:'$aleph_search'(pclause,pclause(Head,Body)))), 1802 assertz(M:'$aleph_search'(pclause,pclause(Head,Body))), 1803 arg(6,S,Verbosity), 1804 (Verbosity >= 1 -> 1805 pp_dclause(Clause,M); 1806 true), 1807 get_gain1(S,Flag,Clause,CLen,EMin/ELength,Last,Best/Node, 1808 Path,L1,Pos,Neg,OVars,E,Best1,M), 1809 % (Prolog = yap -> 1810 % erase(DbRef); 1811 % retractall(M:'$aleph_search'(pclause,_))), 1812 retractall(M:'$aleph_search'(pclause,_)), 1813 Last1 is Last + 1. 1814get_gain(_,_,Last,Best,_,_,_,_,_,_,_,_,_,_,Best,Last,_M). 1815 1816get_refine_gain(S,Last,Best/Node,Path,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M):- 1817 arg(3,S,RefineOp), 1818 RefineOp = rls, 1819 refine_prelims(Best/Node,Last,M), 1820 rls_refine(clauses,Path,Path1,M), 1821 get_refine_gain1(S,Path1,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M), 1822 !. 1823get_refine_gain(S,Last,Best/Node,Path,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M):- 1824 arg(3,S,RefineOp), 1825 RefineOp \= rls, 1826 refine_prelims(Best/Node,Last,M), 1827 Path = CL-[Example,Type,_,Clause], 1828 arg(30,S,ConstructBottom), 1829 arg(43,S,LookAhead), 1830 get_user_refinement(RefineOp,LookAhead,Clause,R,_,M), 1831 match_bot(ConstructBottom,R,R1,LitNums,M), 1832 Path1 = CL-[Example,Type,LitNums,R1], 1833 get_refine_gain1(S,Path1,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M), 1834 !. 1835get_refine_gain(_,_,_,_,_,_,_,_,_,Best,Last,M):- 1836 retract(M:'$aleph_search'(best_refinement,best_refinement(Best))), 1837 retract(M:'$aleph_search'(last_refinement,last_refinement(Last))). 1838 1839get_theory_gain(S,Last,BestSoFar,T0,Pos,Neg,P,N,Best1,NewLast,M):- 1840 refine_prelims(BestSoFar,Last,M), 1841 arg(3,S,RefineOp), 1842 (RefineOp = rls -> rls_refine(theories,T0,T1,M); fail), 1843 arg(23,S,LazyPreds), 1844 (LazyPreds = [] -> Theory = T1; 1845 lazy_evaluate_theory(T1,LazyPreds,Pos,Neg,Theory,M)), 1846 retract(M:'$aleph_search'(best_refinement,best_refinement(OldBest))), 1847 retract(M:'$aleph_search'(last_refinement,last_refinement(OldLast))), 1848 arg(6,S,Verbosity), 1849 (Verbosity >= 1 -> 1850 p_message('new refinement'), 1851 pp_dclauses(Theory,M); 1852 true), 1853 record_pclauses(Theory,M), 1854 get_theory_gain1(S,Theory,OldLast,OldBest,Pos,Neg,P,N,Best1,M), 1855 retractall(M:'$aleph_search'(pclause,_)), 1856 NewLast is OldLast + 1, 1857 asserta(M:'$aleph_search'(last_refinement,last_refinement(NewLast))), 1858 asserta(M:'$aleph_search'(best_refinement,best_refinement(Best1))), 1859 (discontinue_search(S,Best1,NewLast,M) -> 1860 retract(M:'$aleph_search'(last_refinement,last_refinement(_))), 1861 retract(M:'$aleph_search'(best_refinement,best_refinement(_))); 1862 fail), 1863 !. 1864get_theory_gain(_,_,_,_,_,_,_,_,Best,Last,M):- 1865 M:'$aleph_search'(best_refinement,best_refinement(Best)), 1866 M:'$aleph_search'(last_refinement,last_refinement(Last)). 1867 1868refine_prelims(Best,Last,M):- 1869 retractall(M:'$aleph_search'(last_refinement,_)), 1870 retractall(M:'$aleph_search'(best_refinement,_)), 1871 asserta(M:'$aleph_search'(best_refinement,best_refinement(Best))), 1872 asserta(M:'$aleph_search'(last_refinement,last_refinement(Last))). 1873 1874get_refine_gain1(S,Path,MinLength,Pos,Neg,OVars,E,Best1,NewLast,M):- 1875 arg(23,S,LazyPreds), 1876 Path = CL-[Example,Type,Ids,Refine], 1877 (LazyPreds = [] -> Ids1 = Ids, Clause = Refine; 1878 lazy_evaluate_refinement(Ids,Refine,LazyPreds,Pos,Neg,Ids1,Clause,M)), 1879 retractall(M:'$aleph_search'(covers,_)), 1880 retractall(M:'$aleph_search'(coversn,_)), 1881 Path1 = CL-[Example,Type,Ids1,Clause], 1882 split_clause(Clause,Head,Body), 1883 nlits(Body,CLength0), 1884 CLength is CLength0 + 1, 1885 length_ok(S,MinLength,CLength,0,EMin,ELength), 1886 arg(41,S,Prolog), 1887 split_clause(Clause,Head,Body), 1888 (Prolog = yap -> 1889 assertz(M:'$aleph_search'(pclause,pclause(Head,Body)),DbRef); 1890 assertz(M:'$aleph_search'(pclause,pclause(Head,Body)))), 1891 retract(M:'$aleph_search'(best_refinement,best_refinement(OldBest))), 1892 retract(M:'$aleph_search'(last_refinement,last_refinement(OldLast))), 1893 arg(6,S,Verbosity), 1894 (Verbosity >= 1 -> 1895 p_message('new refinement'), 1896 pp_dclause(Clause,M); 1897 true), 1898 once(get_gain1(S,upper,Clause,CLength,EMin/ELength,OldLast,OldBest, 1899 Path1,[],Pos,Neg,OVars,E,Best1,M)), 1900 (Prolog = yap -> 1901 erase(DbRef); 1902 retractall(M:'$aleph_search'(pclause,_))), 1903 NewLast is OldLast + 1, 1904 asserta(M:'$aleph_search'(last_refinement,last_refinement(NewLast))), 1905 asserta(M:'$aleph_search'(best_refinement,best_refinement(Best1))), 1906 (discontinue_search(S,Best1,NewLast,M) -> 1907 retract(M:'$aleph_search'(last_refinement,last_refinement(_))), 1908 retract(M:'$aleph_search'(best_refinement,best_refinement(_))); 1909 fail), 1910 !. 1911 1912get_theory_gain1(S,Theory,Last,Best,Pos,Neg,P,N,Best1,M):- 1913 (M:aleph_false -> p_message('constraint violated'), 1914 Contradiction = true; 1915 Contradiction = false), 1916 Contradiction = false, 1917 Node1 is Last + 1, 1918 arg(32,S,Lang), 1919 theory_lang_ok(Theory,Lang,M), 1920 arg(38,S,NewVars), 1921 theory_newvars_ok(Theory,NewVars), 1922 arg(14,S,Depth), 1923 arg(29,S,Time), 1924 arg(34,S,Proof), 1925 prove(Depth/Time/Proof,pos,(X:-X),Pos,PCvr,TP,M), 1926 prove(Depth/Time/Proof,neg,(X:-X),Neg,NCvr,FP,M), 1927 arg(4,S,_/Evalfn), 1928 Correct is TP + (N - FP), 1929 Incorrect is FP + (P - TP), 1930 length(Theory,L), 1931 Label = [Correct,Incorrect,L], 1932 complete_label(Evalfn,Theory,Label,Label1,M), 1933 get_search_keys(heuristic,Label1,SearchKeys), 1934 arg(6,S,Verbosity), 1935 (Verbosity >= 1 -> p_message(Correct/Incorrect); true), 1936 asserta(M:'$aleph_search_node'(Node1,Theory,[],0,PCvr,NCvr,[],0)), 1937 update_open_list(SearchKeys,Node1,Label1,M), 1938 update_best_theory(S,Theory,PCvr,NCvr,Best,Label1/Node1,Best1,M), !. 1939get_theory_gain1(_,_,_,Best,_,_,_,_,Best,_M). 1940 1941get_gain1(S,_,C,CL,_,Last,Best,Path,_,Pos,Neg,_,E,Best,M):- 1942 abandon_branch(S,C,M), !, 1943 Node1 is Last + 1, 1944 arg(3,S,RefineOp), 1945 arg(7,S,ClauseLength), 1946 arg(35,S,VSearch), 1947 (ClauseLength = CL -> true; 1948 (RefineOp = false -> 1949 asserta(M:'$aleph_search_node'(Node1,0,Path,0,Pos,Neg,[],E)); 1950 true)), 1951 (VSearch = true -> 1952 asserta(M:'$aleph_search'(bad,Node1)), 1953 asserta(M:'$aleph_search_node'(Node1,C)); 1954 true). 1955get_gain1(S,_,Clause,_,_,_,Best,_,_,_,_,_,_,Best,M):- 1956 arg(8,S,Caching), 1957 Caching = true, 1958 skolemize(Clause,SHead,SBody,0,_), 1959 M:'$aleph_search_prunecache'([SHead|SBody]), !, 1960 arg(6,S,Verbosity), 1961 (Verbosity >= 1 -> p_message('in prune cache'); true). 1962get_gain1(S,Flag,C,CL,EMin/EL,Last,Best/Node,Path,L1,Pos,Neg,OVars,E,Best1,M):- 1963 split_clause(C,Head,Body), 1964 arg(22,S,Search), 1965 ((Search \== ic, M:aleph_false) -> p_message('constraint violated'), 1966 Contradiction = true; 1967 Contradiction = false), 1968 Node1 is Last + 1, 1969 arg(8,S,Caching), 1970 (Caching = true -> arg(15,S,CCLim), 1971 get_cache_entry(CCLim,C,Entry); 1972 Entry = false), 1973 arg(35,S,VSearch), 1974 (VSearch = true -> 1975 asserta(M:'$aleph_search_node'(Node1,C)); 1976 true), 1977 arg(3,S,RefineOp), 1978 refinement_ok(RefineOp,Entry,M), 1979 arg(32,S,Lang), 1980 lang_ok((Head:-Body),Lang), 1981 arg(38,S,NewVars), 1982 newvars_ok((Head:-Body),NewVars), 1983 arg(34,S,Proof), 1984 arg(37,S,Optim), 1985 rewrite_clause(Proof,Optim,(Head:-Body),(Head1:-Body1)), 1986 (Search = ic -> 1987 PCvr = [], 1988 Label = [_,_,CL], 1989 ccheck(S,(Head1:-Body1),NCvr,Label,M); 1990 prove_examples(S,Flag,Contradiction,Entry,Best,CL,EL, 1991 (Head1:-Body1),Pos,Neg,PCvr,NCvr,Label,M) 1992 ), 1993 arg(4,S,SearchStrat/Evalfn), 1994 arg(40,S,MinPosFrac), 1995 ((MinPosFrac > 0.0 ; Evalfn = wracc) -> 1996 reset_clause_prior(S,Head1,M); 1997 true 1998 ), 1999 arg(46,S,SSample), 2000 (SSample = true -> 2001 arg(47,S,SampleSize), 2002 estimate_label(SampleSize,Label,Label0,M); 2003 Label0 = Label), 2004 complete_label(Evalfn,C,Label0,Label1,M), 2005 compression_ok(Evalfn,Label1), 2006 get_search_keys(SearchStrat,Label1,SearchKeys), 2007 arg(6,S,Verbosity), 2008 arg(10,S,LCost), 2009 arg(11,S,LContra), 2010 ((Verbosity >= 1, LContra = false, LCost = false) -> 2011 Label = [A,B|_], 2012 p_message(A/B); 2013 true), 2014 arg(7,S,ClauseLength), 2015 (RefineOp = false -> 2016 get_ovars1(false,L1,OVars1,M), 2017 aleph_append(OVars1,OVars,OVars2); 2018 true), 2019 ((ClauseLength=CL, RefineOp = false) -> true; 2020 (RefineOp = false -> 2021 asserta(M:'$aleph_search_node'(Node1,L1,Path,EMin/EL,PCvr, 2022 NCvr,OVars2,E)); 2023 asserta(M:'$aleph_search_node'(Node1,0,Path,EMin/EL,PCvr, 2024 NCvr,[],E))), 2025 update_open_list(SearchKeys,Node1,Label1,M)), 2026 (VSearch = true -> 2027 asserta(M:'$aleph_search'(label,label(Node1,Label))); 2028 true), 2029 (((RefineOp \= false,Contradiction=false); 2030 (arg(28,S,HOVars),clause_ok1(Contradiction,HOVars,OVars2))) -> 2031 update_best(S,C,PCvr,NCvr,Best/Node,Label1/Node1,Best1,M); 2032 Best1=Best/Node), 2033 !. 2034get_gain1(_,_,_,_,_,_,Best,_,_,_,_,_,_,Best,_M). 2035 2036 2037abandon_branch(S,C,M):- 2038 arg(9,S,PruneDefined), 2039 PruneDefined = true, 2040 M:prune(C), !, 2041 arg(6,S,Verbosity), 2042 (Verbosity >= 1 -> p_message(pruned); true). 2043 2044clause_ok1(false,V1,V2):- 2045 aleph_subset1(V1,V2). 2046 2047% check to see if a clause is acceptable 2048% unacceptable if it fails noise, minacc, or minpos settings 2049% unacceptable if it fails search or language constraints 2050clause_ok(_,_,_M):- 2051 false, !, fail. 2052clause_ok(_,Label,M):- 2053 extract_pos(Label,P), 2054 extract_neg(Label,N), 2055 Acc is P/(P+N), 2056 setting(noise,Noise,M), 2057 setting(minacc,MinAcc,M), 2058 setting(minpos,MinPos,M), 2059 (N > Noise; Acc < MinAcc; P < MinPos), !, fail. 2060clause_ok(Clause,_,M):- 2061 M:prune(Clause), !, fail. 2062clause_ok(Clause,_,M):- 2063 setting(language,Lang,M), 2064 \+ lang_ok(Clause,Lang), !, fail. 2065clause_ok(Clause,_,M):- 2066 setting(newvars,NewVars,M), 2067 \+ newvars_ok(Clause,NewVars), !, fail. 2068clause_ok(_,_,_M). 2069 2070% check to see if refinement has been produced before 2071refinement_ok(false,_,_M):- !. 2072refinement_ok(rls,_,_M):- !. 2073refinement_ok(_,false,_M):- !. 2074refinement_ok(_,Entry,M):- 2075 (check_cache(Entry,pos,_,M); check_cache(Entry,neg,_,M)), !, 2076 p_message('redundant refinement'), 2077 fail. 2078refinement_ok(_,_,_M). 2079 2080 2081% specialised redundancy check with equality theory 2082% used only to check if equalities introduced by splitting vars make 2083% literal to be added redundant 2084split_ok(false,_,_):- !. 2085split_ok(_,Clause,Lit):- 2086 functor(Lit,Name,_), 2087 Name \= '=', 2088 copy_term(Clause/Lit,Clause1/Lit1), 2089 lit_redun(Lit1,Clause1), !, 2090 p_message('redundant literal'), nl, 2091 fail. 2092split_ok(_,_,_). 2093 2094lit_redun(Lit,(Head:-Body)):- 2095 !, 2096 lit_redun(Lit,(Head,Body)). 2097lit_redun(Lit,(L1,_)):- 2098 Lit == L1, !. 2099lit_redun(Lit,(L1,L2)):- 2100 !, 2101 execute_equality(L1), 2102 lit_redun(Lit,L2). 2103lit_redun(Lit,L):- 2104 Lit == L. 2105 2106execute_equality(Lit):- 2107 functor(Lit,'=',2), !, 2108 . 2109execute_equality(_). 2110 2111theory_lang_ok([],_). 2112theory_lang_ok([_-[_,_,_,Clause]|T],Lang):- 2113 lang_ok(Lang,Clause), 2114 theory_lang_ok(Lang,T). 2115 2116theory_newvars_ok([],_). 2117theory_newvars_ok([_-[_,_,_,Clause]|T],NewV):- 2118 newvars_ok(NewV,Clause), 2119 theory_newvars_ok(T,NewV). 2120 2121lang_ok((Head:-Body),N):- 2122 !, 2123 (lang_ok(N,Head,Body) -> true; 2124 p_message('outside language bound'), 2125 fail). 2126 2127lang_ok(N,_,_):- N is inf, !. 2128lang_ok(N,Head,Body):- 2129 get_psyms((Head,Body),PSymList), 2130 lang_ok1(PSymList,N). 2131 2132newvars_ok((Head:-Body),N):- 2133 !, 2134 (newvars_ok(N,Head,Body) -> true; 2135 p_message('outside newvars bound'), 2136 fail). 2137 2138newvars_ok(N,_,_):- N is inf, !. 2139newvars_ok(N,Head,Body):- 2140 vars_in_term([Head],[],HVars), 2141 goals_to_list(Body,BodyL), 2142 vars_in_term(BodyL,[],BVars), 2143 aleph_ord_subtract(BVars,HVars,NewVars), 2144 length(NewVars,N1), 2145 N1 =< N. 2146 2147get_psyms((L,B),[N/A|Syms]):- 2148 !, 2149 functor(L,N,A), 2150 get_psyms(B,Syms). 2151get_psyms(true,[]):- !. 2152get_psyms(L,[N/A]):- 2153 functor(L,N,A). 2154 2155lang_ok1([],_). 2156lang_ok1([Pred|Preds],N):- 2157 length(Preds,N0), 2158 aleph_delete_all(Pred,Preds,Preds1), 2159 length(Preds1,N1), 2160 PredOccurs is N0 - N1 + 1, 2161 PredOccurs =< N, 2162 lang_ok1(Preds1,N). 2163 2164rewrite_clause(sld,_,_,(X:-X)):- !. 2165rewrite_clause(restricted_sld,true,(Head:-Body),(Head1:-Body1)):- 2166 !, 2167 optimise((Head:-Body),(Head1:-Body1)). 2168rewrite_clause(_,_,Clause,Clause). 2169 2170record_pclauses([],_M). 2171record_pclauses([_-[_,_,_,Clause]|T],M):- 2172 split_clause(Clause,Head,Body), 2173 assertz(M:'$aleph_search'(pclause,pclause(Head,Body))), 2174 record_pclauses(T,M). 2175 2176% get pos/neg distribution of clause head 2177reset_clause_prior(S,Head,M):- 2178 arg(3,S,Refine), 2179 Refine = false, !, 2180 (M:'$aleph_search'(clauseprior,_) -> true; 2181 get_clause_prior(S,Head,Prior,M), 2182 assertz(M:'$aleph_search'(clauseprior,Prior)) 2183 ). 2184reset_clause_prior(S,Head,M):- 2185 copy_term(Head,Head1), 2186 numbervars(Head1,0,_), 2187 (M:'$aleph_local'(clauseprior,prior(Head1,Prior)) -> 2188 true; 2189 get_clause_prior(S,Head,Prior,M), 2190 assertz(M:'$aleph_local'(clauseprior,prior(Head1,Prior))) 2191 ), 2192 retractall(M:'$aleph_search'(clauseprior,_)), 2193 assertz(M:'$aleph_search'(clauseprior,Prior)). 2194 2195get_clause_prior(S,Head,Total-[P-pos,N-neg],M):- 2196 arg(5,S,Greedy), 2197 arg(14,S,Depth), 2198 arg(29,S,Time), 2199 arg(34,S,Proof), 2200 (Greedy = true -> 2201 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)); 2202 M:'$aleph_global'(atoms,atoms(pos,Pos)) 2203 ), 2204 M:'$aleph_global'(atoms_left,atoms_left(neg,Neg)), 2205 prove(Depth/Time/Proof,pos,(Head:-true),Pos,_,P,M), 2206 prove(Depth/Time/Proof,neg,(Head:-true),Neg,_,N,M), 2207 Total is P + N. 2208 2209get_user_refinement(auto,L,Clause,Template,0,M):- 2210 auto_refine(L,Clause,Template,M). 2211get_user_refinement(user,_,Clause,Template,0,M):- 2212 M:refine(Clause,Template). 2213 2214match_bot(false,Clause,Clause,[],_M). 2215match_bot(reduction,Clause,Clause1,Lits,M):- 2216 match_lazy_bottom(Clause,Lits,M), 2217 get_pclause(Lits,[],Clause1,_,_,_,M). 2218match_bot(saturation,Clause,Clause1,Lits,M):- 2219 once(get_aleph_clause(Clause,AlephClause)), 2220 match_bot_lits(AlephClause,[],Lits,M), 2221 get_pclause(Lits,[],Clause1,_,_,_,M). 2222 2223match_bot_lits((Lit,Lits),SoFar,[LitNum|LitNums],M):- 2224 !, 2225 match_bot_lit(Lit,LitNum,M), 2226 \+(aleph_member(LitNum,SoFar)), 2227 match_bot_lits(Lits,[LitNum|SoFar],LitNums,M). 2228match_bot_lits(Lit,SoFar,[LitNum],M):- 2229 match_bot_lit(Lit,LitNum,M), 2230 \+(aleph_member(LitNum,SoFar)). 2231 2232match_bot_lit(Lit,LitNum,M):- 2233 M:'$aleph_sat'(botsize,Last), 2234 M:'$aleph_sat_litinfo'(LitNum,_,Lit,_,_,_), 2235 LitNum >= 0, 2236 LitNum =< Last. 2237 2238match_lazy_bottom(Clause,Lits,M):- 2239 once(get_aleph_clause(Clause,AlephClause)), 2240 copy_term(Clause,CClause), 2241 split_clause(CClause,CHead,CBody), 2242 example_saturated(CHead,M), 2243 store(stage,M), 2244 set(stage,saturation,M), 2245 match_lazy_bottom1(CBody,M), 2246 reinstate(stage,M), 2247 match_bot_lits(AlephClause,[],Lits,M). 2248 2249match_lazy_bottom1(Body,M):- 2250 M:Body, 2251 match_body_modes(Body,M), 2252 fail. 2253match_lazy_bottom1(_,M):- 2254 flatten_matched_atoms(body,M). 2255 2256match_body_modes((CLit,CLits),M):- 2257 !, 2258 match_mode(body,CLit,M), 2259 match_body_modes(CLits,M). 2260match_body_modes(CLit,M):- 2261 match_mode(body,CLit,M). 2262 2263match_mode(_,true,_M):- !. 2264match_mode(Loc,CLit,M):- 2265 functor(CLit,Name,Arity), 2266 functor(Mode,Name,Arity), 2267 (Loc=head -> 2268 M:'$aleph_global'(modeh,modeh(_,Mode)); 2269 M:'$aleph_global'(modeb,modeb(_,Mode))), 2270 split_args(Mode,Mode,I,O,C,M), 2271 (Loc = head -> 2272 update_atoms(CLit,mode(Mode,O,I,C)); 2273 update_atoms(CLit,mode(Mode,I,O,C))), 2274 fail. 2275match_mode(_,_,_M). 2276 2277flatten_matched_atoms(Loc,M):- 2278 setting(i,IVal,M), 2279 (retract(M:'$aleph_sat'(botsize,BSize))-> true; BSize = 0), 2280 (retract(M:'$aleph_sat'(lastlit,Last))-> true ; Last = 0), 2281 (Loc = head -> 2282 flatten(0,IVal,BSize,BSize1); 2283 flatten(0,IVal,Last,BSize1)), 2284 asserta(M:'$aleph_sat'(botsize,BSize1)), 2285 (Last < BSize1 -> 2286 asserta(M:'$aleph_sat'(lastlit,BSize1)); 2287 asserta(M:'$aleph_sat'(lastlit,Last))), !. 2288flatten_matched_atoms(_,_M). 2289 2290% integrate head literal into lits database 2291% used during lazy evaluation of bottom clause 2292integrate_head_lit(HeadOVars,M):- 2293 example_saturated(Example,M), 2294 split_args(Example,_,_,Output,_,M), 2295 integrate_args(unknown,Example,Output), 2296 match_mode(head,Example,M), 2297 flatten_matched_atoms(head,M), 2298 get_ivars1(false,1,HeadOVars,M), !. 2299integrate_head_lit([],_M). 2300 2301 2302get_aleph_clause((Lit:-true),PLit):- 2303 !, 2304 get_aleph_lit(Lit,PLit). 2305get_aleph_clause((Lit:-Lits),(PLit,PLits)):- 2306 !, 2307 get_aleph_lit(Lit,PLit), 2308 get_aleph_lits(Lits,PLits). 2309get_aleph_clause(Lit,PLit):- 2310 get_aleph_lit(Lit,PLit). 2311 2312get_aleph_lits((Lit,Lits),(PLit,PLits)):- 2313 !, 2314 get_aleph_lit(Lit,PLit), 2315 get_aleph_lits(Lits,PLits). 2316get_aleph_lits(Lit,PLit):- 2317 get_aleph_lit(Lit,PLit). 2318 2319get_aleph_lit(Lit,PLit):- 2320 functor(Lit,Name,Arity), 2321 functor(PLit,Name,Arity), 2322 get_aleph_lit(Lit,PLit,Arity). 2323 2324get_aleph_lit(_,_,0):- !. 2325get_aleph_lit(Lit,PLit,Arg):- 2326 arg(Arg,Lit,Term), 2327 (var(Term) -> arg(Arg,PLit,Term);arg(Arg,PLit,aleph_const(Term))), 2328 NextArg is Arg - 1, 2329 get_aleph_lit(Lit,PLit,NextArg), !. 2330 2331% Claudien-style consistency checking as described by De Raedt and Dehaspe, 1996 2332% currently does not retain actual substitutions that result in inconsistencies 2333% also, only checks for constraints of the form false:- ... 2334% this simplifies the check of Body,not(Head) to just Body 2335ccheck(S,(aleph_false:-Body),[],[0,N|_],M):- 2336 (Body = true -> 2337 N is inf; 2338 arg(11,S,LContra), 2339 (LContra = false -> 2340 arg(14,S,Depth), 2341 arg(29,S,Time), 2342 findall(X,(resource_bound_call(Time,Depth,Body,M),X=1),XL), 2343 length(XL,N); 2344 lazy_ccheck(S,Body,N,M) 2345 ) 2346 ). 2347 2348lazy_ccheck(S,Body,N,M):- 2349 arg(14,S,Depth), 2350 arg(17,S,Noise), 2351 arg(29,S,Time), 2352 retractall(M:'$aleph_local'(subst_count,_)), 2353 asserta(M:'$aleph_local'(subst_count,0)), 2354 resource_bound_call(Time,Depth,Body,M), 2355 retract(M:'$aleph_local'(subst_count,N0)), 2356 N is N0 + 1, 2357 N > Noise, !. 2358lazy_ccheck(_,_,N,M):- 2359 retract(M:'$aleph_local'(subst_count,N)). 2360 2361% posonly formula as described by Muggleton, ILP-96 2362prove_examples(S,Flag,Contradiction,Entry,Best,CL,L2,Clause,Pos,Rand,PCover,RCover,[P,B,CL,I,G],M):- 2363 2364 arg(4,S,_/Evalfn), 2365 Evalfn = posonly, !, 2366 arg(11,S,LazyOnContra), 2367 ((LazyOnContra = true, Contradiction = true) -> 2368 prove_lazy_cached(S,Entry,Pos,Rand,PCover,RCover,M), 2369 interval_count(PCover,_PC), 2370 interval_count(RCover,RC); 2371 prove_pos(S,Flag,Entry,Best,[PC,L2],Clause,Pos,PCover,PC,M), 2372 prove_rand(S,Flag,Entry,Clause,Rand,RCover,RC,M)), 2373 find_posgain(PCover,P,M), 2374 arg(16,S,MM), arg(20,S,N), 2375 GC is (RC+1.0)/(N+2.0), % Laplace correction for small numbers 2376 A is log(P), 2377 B is log(GC), 2378 G is GC*MM/P, 2379 C is CL/P, 2380 % Sz is CL*M/P, 2381 % D is M*G, 2382 % I is M - D - Sz, 2383 I is A - B - C. 2384prove_examples(S,_,_,Entry,_,CL,_,_,Pos,Neg,Pos,Neg,[PC,NC,CL],M):- 2385 2386 arg(10,S,LazyOnCost), 2387 LazyOnCost = true, !, 2388 prove_lazy_cached(S,Entry,Pos,Neg,Pos1,Neg1,M), 2389 interval_count(Pos1,PC), 2390 interval_count(Neg1,NC). 2391prove_examples(S,_,true,Entry,_,CL,_,_,Pos,Neg,Pos,Neg,[PC,NC,CL],M):- 2392 2393 arg(11,S,LazyOnContra), 2394 LazyOnContra = true, !, 2395 prove_lazy_cached(S,Entry,Pos,Neg,Pos1,Neg1,M), 2396 interval_count(Pos1,PC), 2397 interval_count(Neg1,NC). 2398prove_examples(S,Flag,_,Ent,Best,CL,L2,Clause,Pos,Neg,PCover,NCover,[PC,NC,CL],M):- 2399 2400 arg(3,S,RefineOp), 2401 (RefineOp = false; RefineOp = auto), 2402 arg(7,S,ClauseLength), 2403 ClauseLength = CL, !, 2404 interval_count(Pos,MaxPCount), 2405 prove_neg(S,Flag,Ent,Best,[MaxPCount,CL],Clause,Neg,NCover,NC,M), 2406 arg(17,S,Noise), arg(18,S,MinAcc), 2407 maxlength_neg_ok(Noise/MinAcc,Ent,MaxPCount,NC,M), 2408 prove_pos(S,Flag,Ent,Best,[PC,L2],Clause,Pos,PCover,PC,M), 2409 maxlength_neg_ok(Noise/MinAcc,Ent,PC,NC,M), 2410 !. 2411prove_examples(S,Flag,_,Ent,Best,CL,L2,Clause,Pos,Neg,PCover,NCover,[PC,NC,CL],M):- 2412 prove_pos(S,Flag,Ent,Best,[PC,L2],Clause,Pos,PCover,PC,M), 2413 prove_neg(S,Flag,Ent,Best,[PC,CL],Clause,Neg,NCover,NC,M), 2414 !. 2415 2416prove_lazy_cached(S,Entry,Pos,Neg,Pos1,Neg1,M):- 2417 arg(8,S,Caching), 2418 Caching = true, !, 2419 (check_cache(Entry,pos,Pos1,M)-> 2420 true; 2421 add_cache(Entry,pos,Pos,M), 2422 Pos1 = Pos), 2423 (check_cache(Entry,neg,Neg1,M)-> 2424 true; 2425 add_cache(Entry,neg,Neg,M), 2426 Neg1 = Neg). 2427prove_lazy_cached(_,_,Pos,Neg,Pos,Neg,_M). 2428 2429complete_label(posonly,_,L,L,_M):- !. 2430complete_label(user,Clause,[P,N,L],[P,N,L,Val],M):- 2431 M:cost(Clause,[P,N,L],Cost), !, 2432 Val is -Cost. 2433complete_label(entropy,_,[P,N,L],[P,N,L,Val],M):- 2434 evalfn(entropy,[P,N,L],Entropy,M), 2435 Val is -Entropy, !. 2436complete_label(gini,_,[P,N,L],[P,N,L,Val],M):- 2437 evalfn(gini,[P,N,L],Gini,M), 2438 Val is -Gini, !. 2439complete_label(EvalFn,_,[P,N,L],[P,N,L,Val],M):- 2440 evalfn(EvalFn,[P,N,L],Val,M), !. 2441complete_label(_,_,_,_,_M):- 2442 p_message1('error'), p_message('incorrect evaluation/cost function'), 2443 fail. 2444 2445% estimate label based on subsampling 2446estimate_label(Sample,[P,N|Rest],[P1,N1|Rest],M):- 2447 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)), 2448 M:'$aleph_global'(atoms_left,atoms_left(neg,Neg)), 2449 interval_count(Pos,PC), interval_count(Neg,NC), 2450 PFrac is P/Sample, 2451 NFrac is N/Sample, 2452 P1 is integer(PFrac*PC), 2453 N1 is integer(NFrac*NC). 2454 2455% get primary and secondary search keys for search 2456% use [Primary|Secondary] notation as it is the most compact 2457get_search_keys(bf,[_,_,L,F|_],[L1|F]):- 2458 !, 2459 L1 is -1*L. 2460get_search_keys(df,[_,_,L,F|_],[L|F]):- !. 2461get_search_keys(_,[_,_,L,F|_],[F|L1]):- 2462 L1 is -1*L. 2463 2464prove_pos(_,_,_,_,_,_,[],[],0,_M):- !. 2465prove_pos(S,_,Entry,BestSoFar,PosSoFar,Clause,_,PCover,PCount,M):- 2466 M:'$aleph_search'(covers,covers(PCover,PCount)), !, 2467 pos_ok(S,Entry,BestSoFar,PosSoFar,Clause,PCover,M). 2468prove_pos(S,Flag,Entry,BestSoFar,PosSoFar,Clause,Pos,PCover,PCount,M):- 2469 prove_cache(Flag,S,pos,Entry,Clause,Pos,PCover,PCount,M), 2470 pos_ok(S,Entry,BestSoFar,PosSoFar,Clause,PCover,M), !. 2471 2472prove_neg(S,_,Entry,_,_,_,[],[],0,M):- 2473 arg(8,S,Caching), 2474 (Caching = true -> add_cache(Entry,neg,[],M); true), !. 2475prove_neg(S,Flag,Entry,_,_,Clause,Neg,NCover,NCount,M):- 2476 arg(3,S,RefineOp), 2477 RefineOp = rls, !, 2478 prove_cache(Flag,S,neg,Entry,Clause,Neg,NCover,NCount,M). 2479prove_neg(_,_,_,_,_,_,_,NCover,NCount,M):- 2480 M:'$aleph_search'(coversn,coversn(NCover,NCount)), !. 2481prove_neg(S,Flag,Entry,BestSoFar,PosSoFar,Clause,Neg,NCover,NCount,M):- 2482 arg(12,S,LazyNegs), 2483 LazyNegs = true, !, 2484 lazy_prove_neg(S,Flag,Entry,BestSoFar,PosSoFar,Clause,Neg,NCover,NCount,M). 2485prove_neg(S,Flag,Entry,[P,0,L1|_],[P,L2],Clause,Neg,[],0,M):- 2486 arg(4,S,bf/coverage), 2487 L2 is L1 - 1, 2488 !, 2489 prove_cache(Flag,S,neg,Entry,Clause,Neg,0,[],0,M), !. 2490prove_neg(S,Flag,Entry,[P,N|_],[P,L1],Clause,Neg,NCover,NCount,M):- 2491 arg(4,S,bf/coverage), 2492 !, 2493 arg(7,S,ClauseLength), 2494 (ClauseLength = L1 -> 2495 arg(2,S,Explore), 2496 (Explore = true -> MaxNegs is N; MaxNegs is N - 1), 2497 MaxNegs >= 0, 2498 prove_cache(Flag,S,neg,Entry,Clause,Neg,MaxNegs,NCover,NCount,M), 2499 NCount =< MaxNegs; 2500 prove_cache(Flag,S,neg,Entry,Clause,Neg,NCover,NCount,M)), 2501 !. 2502prove_neg(S,Flag,Entry,_,[P1,L1],Clause,Neg,NCover,NCount,M):- 2503 arg(7,S,ClauseLength), 2504 ClauseLength = L1, !, 2505 arg(17,S,Noise), arg(18,S,MinAcc), 2506 get_max_negs(Noise/MinAcc,P1,N1), 2507 prove_cache(Flag,S,neg,Entry,Clause,Neg,N1,NCover,NCount,M), 2508 NCount =< N1, 2509 !. 2510prove_neg(S,Flag,Entry,_,_,Clause,Neg,NCover,NCount,M):- 2511 prove_cache(Flag,S,neg,Entry,Clause,Neg,NCover,NCount,M), 2512 !. 2513 2514prove_rand(S,Flag,Entry,Clause,Rand,RCover,RCount,M):- 2515 prove_cache(Flag,S,rand,Entry,Clause,Rand,RCover,RCount,M), 2516 !. 2517 2518lazy_prove_neg(S,Flag,Entry,[P,N|_],[P,_],Clause,Neg,NCover,NCount,M):- 2519 arg(4,S,bf/coverage), 2520 !, 2521 MaxNegs is N + 1, 2522 prove_cache(Flag,S,neg,Entry,Clause,Neg,MaxNegs,NCover,NCount,M), 2523 !. 2524lazy_prove_neg(S,Flag,Entry,_,[P1,_],Clause,Neg,NCover,NCount,M):- 2525 arg(17,S,Noise), arg(18,S,MinAcc), 2526 get_max_negs(Noise/MinAcc,P1,N1), 2527 MaxNegs is N1 + 1, 2528 prove_cache(Flag,S,neg,Entry,Clause,Neg,MaxNegs,NCover,NCount,M), 2529 !. 2530 2531% Bug reported by Daniel Fredouille 2532% For MiAcc =:= 0, Negs was being set to P1 + 1. Unclear why. 2533% This definition is as it was up to Aleph 2. 2534get_max_negs(Noise/MinAcc,P1,N):- 2535 number(P1), 2536 (MinAcc =:= 0.0 -> N is Noise; 2537 (N1 is integer((1-MinAcc)*P1/MinAcc), 2538 (Noise < N1 -> N is Noise; N is N1)) 2539 ), !. 2540get_max_negs(Noise/_,_,Noise). 2541 2542 2543% update_open_list(+SearchKeys,+NodeRef,+Label) 2544% insert SearchKeys into openlist 2545update_open_list([K1|K2],NodeRef,Label,M):- 2546 assertz(M:'$aleph_search_gain'(K1,K2,NodeRef,Label)), 2547 retract(M:'$aleph_search'(openlist,OpenList)), 2548 uniq_insert(descending,[K1|K2],OpenList,List1), 2549 asserta(M:'$aleph_search'(openlist,List1)). 2550 2551pos_ok(S,_,_,_,_,_,_M):- 2552 arg(3,S,RefineOp), 2553 (RefineOp = rls; RefineOp = user), !. 2554pos_ok(S,Entry,_,[P,_],_,_,M):- 2555 arg(13,S,MinPos), 2556 P < MinPos, !, 2557 arg(8,S,Caching), 2558 (Caching = true -> 2559 add_prune_cache(Entry,M); 2560 true), 2561 fail. 2562pos_ok(S,Entry,_,[P,_],_,_,M):- 2563 arg(40,S,MinPosFrac), 2564 MinPosFrac > 0.0, 2565 M:'$aleph_search'(clauseprior,_-[P1-pos,_]), 2566 P/P1 < MinPosFrac, !, 2567 arg(8,S,Caching), 2568 (Caching = true -> 2569 add_prune_cache(Entry,M); 2570 true), 2571 fail. 2572pos_ok(S,_,[_,_,_,C1|_],[P,L],_,_,M):- 2573 arg(4,S,_/Evalfn), 2574 arg(2,S,Explore), 2575 ((Evalfn = user; Explore = true) -> true; 2576 evalfn(Evalfn,[P,0,L],C2,M), 2577 best_value(Evalfn,S,[P,0,L,C2],Max,M), 2578 Max > C1), !. 2579 2580 2581maxlength_neg_ok(Noise/MinAcc,Entry,P,N,M):- 2582 ((N > Noise); (P/(P+N) < MinAcc)), !, 2583 add_prune_cache(Entry,M), 2584 fail. 2585maxlength_neg_ok(_,_,_,_,_M). 2586 2587compression_ok(compression,[P,_,L|_]):- 2588 !, 2589 P - L + 1 > 0. 2590compression_ok(_,_). 2591 2592length_ok(S,MinLen,ClauseLen,LastD,ExpectedMin,ExpectedCLen):- 2593 arg(3,S,RefineOp), 2594 (RefineOp = false -> L1 = LastD; L1 = 0), 2595 (L1 < MinLen->ExpectedMin = L1;ExpectedMin = MinLen), 2596 ExpectedCLen is ClauseLen + ExpectedMin, 2597 arg(7,S,CLength), 2598 ExpectedCLen =< CLength, !. 2599 2600update_best(S,_,_,_,Best,[P,_,_,F|_]/_,Best,_M):- 2601 arg(13,S,MinPos), 2602 arg(19,S,MinScore), 2603 (P < MinPos; F is -inf; F < MinScore), !. 2604update_best(S,_,_,_,Best,[P|_]/_,Best,M):- 2605 arg(40,S,MinPosFrac), 2606 MinPosFrac > 0.0, 2607 M:'$aleph_search'(clauseprior,_-[P1-pos,_]), 2608 P/P1 < MinPosFrac, !. 2609update_best(S,_,_,_,Best,[P,N,_,_|_]/_,Best,_M):- 2610 arg(4,S,_/Evalfn), 2611 Evalfn \= posonly, 2612 % Evalfn \= user, 2613 arg(17,S,Noise), 2614 arg(18,S,MinAcc), 2615 arg(22,S,Search), 2616 Total is P + N, 2617 ((N > Noise);(Search \= ic, Total > 0, P/Total < MinAcc)), !. 2618update_best(S,Clause,PCover,NCover,Label/_,Label1/Node1,Label1/Node1,M):- 2619 Label = [_,_,_,GainE|_], 2620 Label1 = [_,_,_,Gain1E|_], 2621 arithmetic_expression_value(GainE,Gain), 2622 arithmetic_expression_value(Gain1E,Gain1), 2623 % (Gain1 = inf; Gain = -inf; Gain1 > Gain), !, 2624 Gain1 > Gain, !, 2625 retractall(M:'$aleph_search'(selected,_)), 2626 asserta(M:'$aleph_search'(selected,selected(Label1,Clause,PCover,NCover))), 2627 arg(35,S,VSearch), 2628 (VSearch = true -> 2629 retractall(M:'$aleph_search'(best,_)), 2630 asserta(M:'$aleph_search'(best,Node1)), 2631 asserta(M:'$aleph_search'(good,Node1)); 2632 true), 2633 update_good(Label1,Clause,M), 2634 show_clause(newbest,Label1,Clause,Node1,M), 2635 record_clause(newbest,Label1,Clause,Node1,M), 2636 record_clause(good,Label1,Clause,Node1,M). 2637update_best(S,Clause,_,_,Label/Node,Label1/Node1,Label/Node,M):- 2638 arg(35,S,VSearch), 2639 (VSearch = true -> 2640 asserta(M:'$aleph_search'(good,Node1)); 2641 true), 2642 update_good(Label1,Clause,M), 2643 show_clause(good,Label1,Clause,Node1,M), 2644 record_clause(good,Label1,Clause,Node1,M). 2645 2646update_good(Label,Clause,M):- 2647 setting(good,true,M), !, 2648 Label = [_,_,L|_], 2649 setting(check_good,Flag,M), 2650 update_good(Flag,L,Label,Clause,M). 2651update_good(_,_,_M). 2652 2653update_good(_,_,_,_,M):- 2654 setting(goodfile,_,M), !. 2655update_good(true,L,Label,Clause,M):- 2656 M:'$aleph_good'(L,Label,Clause), !. 2657update_good(_,L,Label,Clause,M):- 2658 assertz(M:'$aleph_good'(L,Label,Clause)), 2659 (retract(M:'$aleph_search'(last_good,Good)) -> 2660 Good1 is Good + 1; 2661 Good1 is 1), 2662 assertz(M:'$aleph_search'(last_good,Good1)). 2663 2664update_best_theory(S,_,_,_,Best,[P,N,_,F|_]/_,Best,_M):- 2665 arg(17,S,Noise), 2666 arg(18,S,MinAcc), 2667 arg(19,S,MinScore), 2668 (N > Noise; P/(P+N) < MinAcc; F < MinScore), !. 2669update_best_theory(_,Theory,PCover,NCover,Label/_,Label1/Node1,Label1/Node1,M):- 2670 Label = [_,_,_,GainE|_], 2671 Label1 = [_,_,_,Gain1E|_], 2672 arithmetic_expression_value(GainE,Gain), 2673 arithmetic_expression_value(Gain1E,Gain1), 2674 Gain1 > Gain, !, 2675 retractall(M:'$aleph_search'(selected,_)), 2676 asserta(M:'$aleph_search'(selected,selected(Label1,Theory,PCover,NCover))), 2677 show_theory(newbest,Label1,Theory,Node1,M), 2678 record_theory(newbest,Label1,Theory,Node1,M), 2679 record_theory(good,Label1,Theory,Node1,M). 2680update_best_theory(_,Theory,_,_,Best,Label1/_,Best,M):- 2681 show_theory(good,Label1,Theory,Node1,M), 2682 record_theory(good,Label1,Theory,Node1,M). 2683 2684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2685% P R U N I N G C L A U S E S 2686 2687get_node([[K1|K2]|_],[K1|K2],Node,M):- 2688 M:'$aleph_search_gain'(K1,K2,Node,_). 2689get_node([_|Gains],Gain,Node,M):- 2690 get_node(Gains,Gain,Node,M). 2691 2692prune_open(S,_,_,M):- 2693 arg(25,S,OSize), 2694 Inf is inf, 2695 OSize =\= Inf, 2696 retractall(M:'$aleph_local'(in_beam,_)), 2697 asserta(M:'$aleph_local'(in_beam,0)), 2698 M:'$aleph_search'(openlist,Gains), 2699 get_node(Gains,[K1|K2],NodeNum,M), 2700 M:'$aleph_local'(in_beam,N), 2701 (N < OSize-> 2702 retract(M:'$aleph_local'(in_beam,N)), 2703 N1 is N + 1, 2704 asserta(M:'$aleph_local'(in_beam,N1)); 2705 retract(M:'$aleph_search_gain'(K1,K2,NodeNum,_)), 2706 arg(6,S,Verbose), 2707 (Verbose < 1 -> 2708 true; 2709 p1_message('non-admissible removal'), 2710 p_message(NodeNum))), 2711 fail. 2712prune_open(S,_,_,_M):- 2713 arg(2,S,Explore), 2714 arg(3,S,RefineOp), 2715 (Explore = true; RefineOp = rls; RefineOp = user), !. 2716prune_open(_,_/N,_/N,_M):- !. 2717prune_open(S,_,[_,_,_,Best|_]/_,M):- 2718 arg(4,S,_/Evalfn), 2719 built_in_prune(Evalfn), 2720 M:'$aleph_search_gain'(_,_,_,Label), 2721 best_value(Evalfn,S,Label,Best1,M), 2722 Best1 =< Best, 2723 retract(M:'$aleph_search_gain'(_,_,_,Label)), 2724 fail. 2725prune_open(_,_,_,_M). 2726 2727built_in_prune(coverage). 2728built_in_prune(compression). 2729built_in_prune(posonly). 2730built_in_prune(laplace). 2731built_in_prune(wracc). 2732built_in_prune(mestimate). 2733built_in_prune(auto_m). 2734 2735% pruning for posonly, laplace and m-estimates devised in 2736% discussion with James Cussens 2737% pruning for weighted relative accuracy devised in 2738% discussion with Steve Moyle 2739% corrections to best_value/4 after discussion with 2740% Mark Reid and James Cussens 2741best_value(gini,_,_,0.0,_M):- !. 2742best_value(entropy,_,_,0.0,_M):- !. 2743best_value(posonly,S,[P,_,L|_],Best,_M):- 2744 arg(20,S,RSize), 2745 Best is log(P) + log(RSize+2.0) - (L+1)/P, !. 2746best_value(wracc,_,[P|_],Best,M):- 2747 (M:'$aleph_search'(clauseprior,Total-[P1-pos,_]) -> 2748 Best is P*(Total - P1)/(Total^2); 2749 Best is 0.25), !. 2750best_value(Evalfn,_,[P,_,L|Rest],Best,M):- 2751 L1 is L + 1, % need at least 1 extra literal to achieve best value 2752 evalfn(Evalfn,[P,0,L1|Rest],Best,M). 2753 2754 2755get_nextbest(S,NodeRef,M):- 2756 arg(22,S,Search), 2757 select_nextbest(Search,NodeRef,M). 2758 2759% Select the next best node 2760% Incorporates the changes made by Filip Zelezny to 2761% achieve the `randomised rapid restart' (or rrr) technique 2762% within randomised local search 2763select_nextbest(rls,NodeRef,M):- 2764 retractall(M:'$aleph_search'(nextnode,_)), 2765 setting(rls_type,Type,M), 2766 (retract(M:'$aleph_search'(rls_parentstats,stats(PStats,_,_))) -> true; true), 2767 (rls_nextbest(Type,PStats,NodeRef,Label,M) -> 2768 asserta(M:'$aleph_search'(rls_parentstats,stats(Label,[],[]))), 2769 setting(rls_type,RlsType,M), 2770 (RlsType = rrr -> 2771 true; 2772 assertz(M:'$aleph_search'(nextnode,NodeRef))); 2773 NodeRef = none), !. 2774select_nextbest(_,NodeRef,M):- 2775 retractall(M:'$aleph_search'(nextnode,_)), 2776 get_nextbest(NodeRef,M), !. 2777select_nextbest(_,none,_M). 2778 2779get_nextbest(NodeRef,M):- 2780 M:'$aleph_search'(openlist,[H|_]), 2781 H = [K1|K2], 2782 retract(M:'$aleph_search_gain'(K1,K2,NodeRef,_)), 2783 assertz(M:'$aleph_search'(nextnode,NodeRef)). 2784get_nextbest(NodeRef,M):- 2785 retract(M:'$aleph_search'(openlist,[_|T])), 2786 asserta(M:'$aleph_search'(openlist,T)), 2787 get_nextbest(NodeRef,M), !. 2788get_nextbest(none,_M). 2789 2790rls_nextbest(rrr,_,NodeRef,_,M):- 2791 get_nextbest(NodeRef,M). 2792rls_nextbest(gsat,_,NodeRef,Label,M):- 2793 retract(M:'$aleph_search'(openlist,[H|_])), 2794 H = [K1|K2], 2795 asserta(M:'$aleph_search'(openlist,[])), 2796 findall(N-L,M:'$aleph_search_gain'(K1,K2,N,L),Choices), 2797 length(Choices,Last), 2798 get_random(Last,N), 2799 aleph_remove_nth(N,Choices,NodeRef-Label,_), 2800 retractall(M:'$aleph_search_gain'(_,_,_,_)). 2801rls_nextbest(wsat,PStats,NodeRef,Label,M):- 2802 setting(walk,WProb,M), 2803 aleph_random(P), 2804 P >= WProb, !, 2805 rls_nextbest(gsat,PStats,NodeRef,Label,M). 2806rls_nextbest(wsat,PStats,NodeRef,Label,M):- 2807 p_message('random walk'), 2808 retract(M:'$aleph_search'(openlist,_)), 2809 asserta(M:'$aleph_search'(openlist,[])), 2810 findall(N-L,M:'$aleph_search_gain'(_,_,N,L),AllNodes), 2811 potentially_good(AllNodes,PStats,Choices), 2812 length(Choices,Last), 2813 get_random(Last,N), 2814 aleph_remove_nth(N,Choices,NodeRef-Label,_), 2815 retractall(M:'$aleph_search_gain'(_,_,_,_)). 2816rls_nextbest(anneal,[P,N|_],NodeRef,Label,M):- 2817 setting(temperature,Temp,M), 2818 retract(M:'$aleph_search'(openlist,_)), 2819 asserta(M:'$aleph_search'(openlist,[])), 2820 findall(N-L,M:'$aleph_search_gain'(_,_,N,L),AllNodes), 2821 length(AllNodes,Last), 2822 get_random(Last,S), 2823 aleph_remove_nth(S,AllNodes,NodeRef-Label,_), 2824 Label = [P1,N1|_], 2825 Gain is (P1 - N1) - (P - N), 2826 ((P = 1); (Gain >= 0);(aleph_random(R), R < exp(Gain/Temp))). 2827 2828potentially_good([],_,[]). 2829potentially_good([H|T],Label,[H|T1]):- 2830 H = _-Label1, 2831 potentially_good(Label,Label1), !, 2832 potentially_good(T,Label,T1). 2833potentially_good([_|T],Label,T1):- 2834 potentially_good(T,Label,T1). 2835 2836potentially_good([1|_],[P1|_]):- 2837 !, 2838 P1 > 1. 2839potentially_good([P,_,L|_],[P1,_,L1|_]):- 2840 L1 =< L, !, 2841 P1 > P. 2842potentially_good([_,N|_],[_,N1|_]):- 2843 N1 < N. 2844 2845 2846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2847% P R O V E 2848 2849% prove with caching 2850% if entry exists in cache, then return it 2851% otherwise find and cache cover 2852% if ``exact'' flag is set then only check proof for examples 2853% in the part left over due to lazy theorem-proving 2854% ideas in caching developed in discussions with James Cussens 2855 2856prove_cache(exact,S,Type,Entry,Clause,Intervals,IList,Count,M):- 2857 !, 2858 (Intervals = Exact/Left -> 2859 arg(14,S,Depth), 2860 arg(29,S,Time), 2861 arg(34,S,Proof), 2862 prove(Depth/Time/Proof,Type,Clause,Left,IList1,Count1,M), 2863 aleph_append(IList1,Exact,IList), 2864 interval_count(Exact,Count0), 2865 Count is Count0 + Count1; 2866 IList = Intervals, 2867 interval_count(IList,Count)), 2868 arg(8,S,Caching), 2869 (Caching = true -> add_cache(Entry,Type,IList); true). 2870prove_cache(upper,S,Type,Entry,Clause,Intervals,IList,Count,M):- 2871 arg(8,S,Caching), 2872 Caching = true, !, 2873 arg(14,S,Depth), 2874 arg(29,S,Time), 2875 arg(34,S,Proof), 2876 (check_cache(Entry,Type,Cached,M)-> 2877 prove_cached(S,Type,Entry,Cached,Clause,Intervals,IList,Count,M); 2878 prove_intervals(Depth/Time/Proof,Type,Clause,Intervals,IList,Count,M), 2879 add_cache(Entry,Type,IList,M)). 2880prove_cache(upper,S,Type,_,Clause,Intervals,IList,Count,M):- 2881 arg(14,S,Depth), 2882 arg(29,S,Time), 2883 arg(34,S,Proof), 2884 (Intervals = Exact/Left -> 2885 aleph_append(Left,Exact,IList1), 2886 prove(Depth/Time/Proof,Type,Clause,IList1,IList,Count,M); 2887 prove(Depth/Time/Proof,Type,Clause,Intervals,IList,Count,M)). 2888 2889prove_intervals(DepthTime,Type,Clause,I1/Left,IList,Count,M):- 2890 !, 2891 aleph_append(Left,I1,Intervals), 2892 prove(DepthTime,Type,Clause,Intervals,IList,Count,M). 2893prove_intervals(DepthTime,Type,Clause,Intervals,IList,Count,M):- 2894 prove(DepthTime,Type,Clause,Intervals,IList,Count,M). 2895 2896prove_cached(S,Type,Entry,I1/Left,Clause,Intervals,IList,Count,M):- 2897 !, 2898 arg(14,S,Depth), 2899 arg(29,S,Time), 2900 arg(34,S,Proof), 2901 prove(Depth/Time/Proof,Type,Clause,Left,I2,_,M), 2902 aleph_append(I2,I1,I), 2903 (Type = pos -> 2904 arg(5,S,Greedy), 2905 (Greedy = true -> 2906 intervals_intersection(I,Intervals,IList); 2907 IList = I); 2908 IList = I), 2909 interval_count(IList,Count), 2910 update_cache(Entry,Type,IList,M). 2911prove_cached(S,Type,Entry,I1,_,Intervals,IList,Count,M):- 2912 (Type = pos -> arg(5,S,Greedy), 2913 (Greedy = true -> 2914 intervals_intersection(I1,Intervals,IList); 2915 IList = I1); 2916 IList = I1), 2917 interval_count(IList,Count), 2918 update_cache(Entry,Type,IList,M). 2919 2920% prove at most Max atoms 2921prove_cache(exact,S,Type,Entry,Clause,Intervals,Max,IList,Count,M):- 2922 !, 2923 (Intervals = Exact/Left -> 2924 interval_count(Exact,Count0), 2925 Max1 is Max - Count0, 2926 arg(12,S,LNegs), 2927 arg(14,S,Depth), 2928 arg(29,S,Time), 2929 arg(34,S,Proof), 2930 prove(LNegs/false,Depth/Time/Proof,Type,Clause,Left,Max1,IList1,Count1,M), 2931 aleph_append(IList1,Exact,Exact1), 2932 find_lazy_left(S,Type,Exact1,Left1), 2933 IList = Exact1/Left1, 2934 Count is Count0 + Count1; 2935 IList = Intervals, 2936 interval_count(Intervals,Count)), 2937 arg(8,S,Caching), 2938 (Caching = true -> add_cache(Entry,Type,IList); true). 2939prove_cache(upper,S,Type,Entry,Clause,Intervals,Max,IList,Count,M):- 2940 arg(8,S,Caching), 2941 Caching = true, !, 2942 (check_cache(Entry,Type,Cached,M)-> 2943 prove_cached(S,Type,Entry,Cached,Clause,Intervals,Max,IList,Count,M); 2944 (prove_intervals(S,Type,Clause,Intervals,Max,IList1,Count,M)-> 2945 find_lazy_left(S,Type,IList1,Left1), 2946 add_cache(Entry,Type,IList1/Left1,M), 2947 IList = IList1/Left1, 2948 retractall(M:'$aleph_local'(example_cache,_)); 2949 collect_example_cache(IList,M), 2950 add_cache(Entry,Type,IList,M), 2951 fail)). 2952prove_cache(upper,S,Type,_,Clause,Intervals,Max,IList/Left1,Count,M):- 2953 arg(8,S,Caching), 2954 arg(12,S,LNegs), 2955 arg(14,S,Depth), 2956 arg(29,S,Time), 2957 arg(34,S,Proof), 2958 (Intervals = Exact/Left -> 2959 aleph_append(Left,Exact,IList1), 2960 prove(LNegs/Caching,Depth/Time/Proof,Type,Clause,IList1,Max,IList,Count,M); 2961 prove(LNegs/Caching,Depth/Time/Proof,Type,Clause,Intervals,Max,IList,Count,M)), 2962 find_lazy_left(S,Type,IList,Left1). 2963 2964prove_intervals(S,Type,Clause,I1/Left,Max,IList,Count,M):- 2965 !, 2966 arg(8,S,Caching), 2967 arg(12,S,LNegs), 2968 arg(14,S,Depth), 2969 arg(29,S,Time), 2970 arg(34,S,Proof), 2971 aleph_append(Left,I1,Intervals), 2972 prove(LNegs/Caching,Depth/Time/Proof,Type,Clause,Intervals,Max,IList,Count,M). 2973prove_intervals(S,Type,Clause,Intervals,Max,IList,Count,M):- 2974 arg(8,S,Caching), 2975 arg(12,S,LNegs), 2976 arg(14,S,Depth), 2977 arg(29,S,Time), 2978 arg(34,S,Proof), 2979 prove(LNegs/Caching,Depth/Time/Proof,Type,Clause,Intervals,Max,IList,Count,M). 2980 2981 2982prove_cached(S,Type,Entry, I1/Left,Clause,_,Max,IList/Left1,Count,M):- 2983 !, 2984 arg(8,S,Caching), 2985 arg(12,S,LNegs), 2986 arg(14,S,Depth), 2987 arg(29,S,Time), 2988 arg(34,S,Proof), 2989 interval_count(I1,C1), 2990 Max1 is Max - C1, 2991 Max1 >= 0, 2992 (prove(LNegs/Caching,Depth/Time/Proof,Type,Clause,Left,Max1,I2,C2,M)-> 2993 aleph_append(I2,I1,IList), 2994 Count is C2 + C1, 2995 find_lazy_left(S,Type,IList,Left1), 2996 update_cache(Entry,Type,IList/Left1,M), 2997 retractall(M:'$aleph_local'(example_cache,_)); 2998 collect_example_cache(I2/Left1,M), 2999 aleph_append(I2,I1,IList), 3000 update_cache(Entry,Type,IList/Left1,M), 3001 fail). 3002prove_cached(_,neg,_, I1/L1,_,_,_,I1/L1,C1,_M):- 3003 !, 3004 interval_count(I1,C1). 3005prove_cached(S,_,_,I1,_,_,Max,I1,C1,_M):- 3006 interval_count(I1,C1), 3007 arg(12,S,LNegs), 3008 (LNegs = true ->true; C1 =< Max). 3009 3010collect_example_cache(Intervals/Left,M):- 3011 retract(M:'$aleph_local'(example_cache,[Last|Rest])), 3012 aleph_reverse([Last|Rest],IList), 3013 list_to_intervals1(IList,Intervals), 3014 Next is Last + 1, 3015 M:'$aleph_global'(size,size(neg,LastN)), 3016 (Next > LastN -> Left = []; Left = [Next-LastN]). 3017 3018find_lazy_left(S,_,_,[]):- 3019 arg(12,S,LazyNegs), 3020 LazyNegs = false, !. 3021find_lazy_left(_,_,[],[]). 3022find_lazy_left(S,Type,[_-F],Left):- 3023 !, 3024 F1 is F + 1, 3025 (Type = pos -> arg(16,S,Last); 3026 (Type = neg -> arg(24,S,Last); 3027 (Type = rand -> arg(20,S,Last); Last = F))), 3028 (F1 > Last -> Left = []; Left = [F1-Last]). 3029find_lazy_left(S,Type,[_|T1],Left):- 3030 find_lazy_left(S,Type,T1,Left). 3031 3032 3033% prove atoms specified by Type and index set using Clause. 3034% dependent on data structure used for index set: 3035% currently index set is a list of intervals 3036% return atoms proved and their count 3037% if tail-recursive version is needed see below 3038 3039prove(_,_,_,[],[],0,_M). 3040prove(Flags,Type,Clause,[Interval|Intervals],IList,Count,M):- 3041 index_prove(Flags,Type,Clause,Interval,I1,C1,M), 3042 prove(Flags,Type,Clause,Intervals,I2,C2,M), 3043 aleph_append(I2,I1,IList), 3044 Count is C1 + C2. 3045 3046 3047%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3048% T A I L - R E C U R S I V E P R O V E/6 3049 3050% use this rather than the prove/6 above for tail recursion 3051% written by James Cussens 3052 3053 3054% prove(DepthTime,Type,Clause,Intervals,IList,Count,M):- 3055 % prove2(Intervals,DepthTime,Type,Clause,0,IList,Count,M). 3056 3057% code for tail recursive cover testing 3058% starts here 3059 3060% when we know that Sofar is a variable. 3061prove2([],_,_,_,Count,[],Count,_M). 3062prove2([Current-Finish|Intervals],Depth/Time/Proof,Type,(Head:-Body),InCount,Sofar,OutCount,M) :- 3063 M:example(Current,Type,Example), 3064 \+ prove1(Proof,Depth/Time,Example,(Head:-Body,M)), %uncovered 3065 !, 3066 (Current>=Finish -> 3067 prove2(Intervals,Depth/Time/Proof,Type,(Head:-Body),InCount,Sofar,OutCount,M); 3068 Next is Current+1,!, 3069 prove2([Next-Finish|Intervals],Depth/Time/Proof,Type,(Head:-Body),InCount,Sofar,OutCount,M) 3070 ). 3071prove2([Current-Finish|Intervals],ProofFlags,Type,Clause,InCount,Sofar,OutCount,M) :- 3072 (Current>=Finish -> 3073 Sofar=[Current-Current|Rest], 3074 MidCount is InCount+1,!, 3075 prove2(Intervals,ProofFlags,Type,Clause,MidCount,Rest,OutCount,M); 3076 Next is Current+1, 3077 Sofar=[Current-_Last|_Rest],!, 3078 prove3([Next-Finish|Intervals],ProofFlags,Type,Clause,InCount,Sofar,OutCount,M) 3079 ). 3080 3081%when Sofar is not a variable 3082prove3([Current-Finish|Intervals],Depth/Time/Proof,Type,(Head:-Body),InCount,Sofar,OutCount,M) :- 3083 M:example(Current,Type,Example), 3084 \+ prove1(Proof,Depth/Time,Example,(Head:-Body),M), %uncovered 3085 !, 3086 Last is Current-1, %found some previously 3087 Sofar=[Start-Last|Rest], %complete found interval 3088 MidCount is InCount+Current-Start, 3089 (Current>=Finish -> 3090 prove2(Intervals,Depth/Time/Proof,Type,(Head:-Body),MidCount,Rest,OutCount,M); 3091 Next is Current+1,!, 3092 prove2([Next-Finish|Intervals],Depth/Time/Proof,Type,(Head:-Body),MidCount,Rest,OutCount,M) 3093 ). 3094prove3([Current-Finish|Intervals],ProofFlags,Type,Clause,InCount,Sofar,OutCount,M) :- 3095 (Current>=Finish -> 3096 Sofar=[Start-Finish|Rest], 3097 MidCount is InCount+Finish-Start+1,!, 3098 prove2(Intervals,ProofFlags,Type,Clause,MidCount,Rest,OutCount,M); 3099 Next is Current+1,!, 3100 prove3([Next-Finish|Intervals],ProofFlags,Type,Clause,InCount,Sofar,OutCount,M) 3101 ). 3102 3103 3104% code for tail recursive cover testing 3105% ends here 3106 3107index_prove(_,_,_,Start-Finish,[],0,_M):- 3108 Start > Finish, !. 3109index_prove(ProofFlags,Type,Clause,Start-Finish,IList,Count,M):- 3110 index_prove1(ProofFlags,Type,Clause,Start,Finish,Last,M), 3111 Last0 is Last - 1 , 3112 Last1 is Last + 1, 3113 (Last0 >= Start-> 3114 index_prove(ProofFlags,Type,Clause,Last1-Finish,Rest,Count1,M), 3115 IList = [Start-Last0|Rest], 3116 Count is Last - Start + Count1; 3117 index_prove(ProofFlags,Type,Clause,Last1-Finish,IList,Count,M)). 3118 3119prove1(G,M):- 3120 depth_bound_call(G,M), !. 3121 3122prove1(user,_,Example,Clause,M):- 3123 prove(Clause,Example,M), !. 3124prove1(restricted_sld,Depth/Time,Example,(Head:-Body),M):- 3125 \+((\+(((Example = Head),resource_bound_call(Time,Depth,Body,M))))), !. 3126prove1(sld,Depth/Time,Example,_,M):- 3127 \+(\+(resource_bound_call(Time,Depth,Example,M))), !. 3128 3129index_prove1(_,_,_,Num,Last,Num,_M):- 3130 Num > Last, !. 3131index_prove1(Depth/Time/Proof,Type,Clause,Num,Finish,Last,M):- 3132 M:example(Num,Type,Example), 3133 prove1(Proof,Depth/Time,Example,Clause,M), !, 3134 Num1 is Num + 1, 3135 index_prove1(Depth/Time/Proof,Type,Clause,Num1,Finish,Last,M). 3136index_prove1(_,_,_,Last,_,Last,_M). 3137 3138 3139% proves at most Max atoms using Clause. 3140 3141prove(_,_,_,_,[],_,[],0,_M). 3142prove(Flags,ProofFlags,Type,Clause,[Interval|Intervals],Max,IList,Count,M):- 3143 index_prove(Flags,ProofFlags,Type,Clause,Interval,Max,I1,C1,M), !, 3144 Max1 is Max - C1, 3145 prove(Flags,ProofFlags,Type,Clause,Intervals,Max1,I2,C2,M), 3146 aleph_append(I2,I1,IList), 3147 Count is C1 + C2. 3148 3149 3150index_prove(_,_,_,_,Start-Finish,_,[],0,_M):- 3151 Start > Finish, !. 3152index_prove(Flags,ProofFlags,Type,Clause,Start-Finish,Max,IList,Count,M):- 3153 index_prove1(Flags,ProofFlags,Type,Clause,Start,Finish,0,Max,Last,M), 3154 Last0 is Last - 1 , 3155 Last1 is Last + 1, 3156 (Last0 >= Start-> 3157 Max1 is Max - Last + Start, 3158 ((Max1 = 0, Flags = true/_) -> 3159 Rest = [], Count1 = 0; 3160 index_prove(Flags,ProofFlags,Type,Clause,Last1-Finish, 3161 Max1,Rest,Count1,M)), 3162 IList = [Start-Last0|Rest], 3163 Count is Last - Start + Count1; 3164 index_prove(Flags,ProofFlags,Type,Clause,Last1-Finish,Max,IList,Count,M)). 3165 3166index_prove1(false/_,_,_,_,_,_,Proved,Allowed,_,_M):- 3167 Proved > Allowed, !, fail. 3168index_prove1(_,_,_,_,Num,Last,_,_,Num,_M):- 3169 Num > Last, !. 3170index_prove1(true/_,_,_,_,Num,_,Allowed,Allowed,Num,_M):- !. 3171index_prove1(LNegs/Caching,Depth/Time/Proof,Type,Clause,Num,Finish,Proved,Allowed,Last,M):- 3172 M:example(Num,Type,Example), 3173 prove1(Proof,Depth/Time,Example,Clause,M), !, 3174 Num1 is Num + 1, 3175 Proved1 is Proved + 1, 3176 (Caching = true -> 3177 (retract(M:'$aleph_local'(example_cache,L)) -> 3178 asserta(M:'$aleph_local'(example_cache,[Num|L])); 3179 asserta(M:'$aleph_local'(example_cache,[Num]))); 3180 true), 3181 index_prove1(LNegs/Caching,Depth/Time/Proof,Type,Clause,Num1,Finish,Proved1,Allowed,Last,M). 3182index_prove1(_,_,_,_,Last,_,_,_,Last,_M). 3183 3184% resource_bound_call(Time,Depth,Goals) 3185% attempt to prove Goals using depth bounded theorem-prover 3186% in at most Time secs 3187resource_bound_call(T,Depth,Goals,M):- 3188 Inf is inf, 3189 T =:= Inf, 3190 !, 3191 depth_bound_call(Goals,Depth,M). 3192resource_bound_call(T,Depth,Goals,M):- 3193 catch(time_bound_call(T,prooflimit,depth_bound_call(Goals,Depth,M),M), 3194 prooflimit,fail). 3195 3196time_bound_call(T,Exception,Goal,M):- 3197 alarm(T,throw(Exception),X), 3198 (M:Goal -> remove_alarm(X); remove_alarm(X), fail). 3199 3200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3201% C A C H I N G 3202 3203clear_cache(M):- 3204 retractall(M:'$aleph_search_cache'(_)), 3205 retractall(M:'$aleph_search_prunecache'(_)). 3206 3207check_cache(Entry,Type,I,M):- 3208 Entry \= false, 3209 M:'$aleph_search_cache'(Entry), !, 3210 functor(Entry,_,Arity), 3211 (Type = pos -> Arg is Arity - 1; Arg is Arity), 3212 arg(Arg,Entry,I), 3213 nonvar(I). 3214 3215add_cache(false,_,_,_M):- !. 3216add_cache(Entry,Type,I,M):- 3217 (retract(M:'$aleph_search_cache'(Entry))-> true ; true), 3218 functor(Entry,_,Arity), 3219 (Type = pos -> Arg is Arity - 1; Arg is Arity), 3220 (arg(Arg,Entry,I)-> asserta(M:'$aleph_search_cache'(Entry)); 3221 true), !. 3222 3223update_cache(Entry,Type,I,M):- 3224 Entry \= false, 3225 functor(Entry,Name,Arity), 3226 (Type = pos -> Arg is Arity - 1; Arg is Arity), 3227 arg(Arg,Entry,OldI), 3228 OldI = _/_, 3229 retract(M:'$aleph_search_cache'(Entry)), 3230 functor(NewEntry,Name,Arity), 3231 Arg0 is Arg - 1, 3232 copy_args(Entry,NewEntry,1,Arg0), 3233 arg(Arg,NewEntry,I), 3234 Arg1 is Arg + 1, 3235 copy_args(Entry,NewEntry,Arg1,Arity), 3236 asserta(M:'$aleph_search_cache'(NewEntry)), !. 3237update_cache(_,_,_,_M). 3238 3239 3240add_prune_cache(false,_M):- !. 3241add_prune_cache(Entry,M):- 3242 (M:'$aleph_global'(caching,set(caching,true))-> 3243 functor(Entry,_,Arity), 3244 A1 is Arity - 2, 3245 arg(A1,Entry,Clause), 3246 asserta(M:'$aleph_search_prunecache'(Clause)); 3247 true). 3248 3249get_cache_entry(Max,Clause,Entry):- 3250 skolemize(Clause,Head,Body,0,_), 3251 length(Body,L1), 3252 Max >= L1 + 1, 3253 aleph_hash_term([Head|Body],Entry), !. 3254get_cache_entry(_,_,false). 3255 3256% upto 3-argument indexing using predicate names in a clause 3257aleph_hash_term([L0,L1,L2,L3,L4|T],Entry):- 3258 !, 3259 functor(L1,P1,_), functor(L2,P2,_), 3260 functor(L3,P3,_), functor(L4,P4,_), 3261 functor(Entry,P4,6), 3262 arg(1,Entry,P2), arg(2,Entry,P3), 3263 arg(3,Entry,P1), arg(4,Entry,[L0,L1,L2,L3,L4|T]). 3264aleph_hash_term([L0,L1,L2,L3],Entry):- 3265 !, 3266 functor(L1,P1,_), functor(L2,P2,_), 3267 functor(L3,P3,_), 3268 functor(Entry,P3,5), 3269 arg(1,Entry,P2), arg(2,Entry,P1), 3270 arg(3,Entry,[L0,L1,L2,L3]). 3271aleph_hash_term([L0,L1,L2],Entry):- 3272 !, 3273 functor(L1,P1,_), functor(L2,P2,_), 3274 functor(Entry,P2,4), 3275 arg(1,Entry,P1), arg(2,Entry,[L0,L1,L2]). 3276aleph_hash_term([L0,L1],Entry):- 3277 !, 3278 functor(L1,P1,_), 3279 functor(Entry,P1,3), 3280 arg(1,Entry,[L0,L1]). 3281aleph_hash_term([L0],Entry):- 3282 functor(L0,P0,_), 3283 functor(Entry,P0,3), 3284 arg(1,Entry,[L0]). 3285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3286% T R E E S 3287 3288construct_tree(Type,M):- 3289 setting(searchtime,Time,M), 3290 Inf is inf, 3291 Time =\= Inf, 3292 SearchTime is integer(Time), 3293 SearchTime > 0, !, 3294 catch(time_bound_call(SearchTime,searchlimit,find_tree(Type),M), 3295 searchlimit,p_message('Time limit reached')). 3296construct_tree(Type,M):- 3297 find_tree(Type,M). 3298 3299% find_tree(Type,M) where Type is one of 3300% classification, regression, class_probability 3301find_tree(Type,M):- 3302 retractall(M:'$aleph_search'(tree,_)), 3303 retractall(M:'$aleph_search'(tree_besterror,_)), 3304 retractall(M:'$aleph_search'(tree_gain,_)), 3305 retractall(M:'$aleph_search'(tree_lastleaf,_)), 3306 retractall(M:'$aleph_search'(tree_leaf,_)), 3307 retractall(M:'$aleph_search'(tree_newleaf,_)), 3308 retractall(M:'$aleph_search'(tree_startdistribution,_)), 3309 get_start_distribution(Type,Distribution,M), 3310 asserta(M:'$aleph_search'(tree_startdistribution,d(Type,Distribution))), 3311 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)), 3312 setting(dependent,Argno,M), 3313 p_message('constructing tree'), 3314 stopwatch(StartClock), 3315 get_search_settings(S,M), 3316 auto_refine(aleph_false,Head,M), 3317 gen_leaf(Leaf,M), 3318 eval_treenode(S,Type,(Head:-true),[Argno],Pos,Examples,N,Cost,M), 3319 asserta(M:'$aleph_search'(tree_leaf,l(Leaf,Leaf,[Head,Cost,N],Examples))), 3320 find_tree1([Leaf],S,Type,[Argno],M), 3321 prune_rules(S,Type,[Argno],M), 3322 stopwatch(StopClock), 3323 add_tree(S,Type,[Argno],M), 3324 Time is StopClock - StartClock, 3325 p1_message('construction time'), p_message(Time). 3326 3327get_start_distribution(regression,0-[0,0],_M):- !. 3328get_start_distribution(model,0-[0,0],M):- 3329 setting(evalfn,mse,M), !. 3330get_start_distribution(model,0-Distribution,M):- 3331 setting(evalfn,accuracy,M), !, 3332 (setting(classes,Classes,M) -> true; 3333 !, 3334 p_message('missing setting for classes'), 3335 fail), 3336 initialise_distribution(Classes,Distribution), !. 3337get_start_distribution(Tree,0-Distribution,M):- 3338 (Tree = classification; Tree = class_probability), 3339 (setting(classes,Classes,M) -> true; 3340 !, 3341 p_message('missing setting for classes'), 3342 fail), 3343 initialise_distribution(Classes,Distribution), !. 3344get_start_distribution(_,_,_M):- 3345 p_message('incorrect/missing setting for tree_type or evalfn'), 3346 fail. 3347 3348initialise_distribution([],[]). 3349initialise_distribution([Class|Classes],[0-Class|T]):- 3350 initialise_distribution(Classes,T). 3351 3352laplace_correct([],[]). 3353laplace_correct([N-Class|Classes],[N1-Class|T]):- 3354 N1 is N + 1, 3355 laplace_correct(Classes,T). 3356 3357find_tree1([],_,_,_,_M). 3358find_tree1([Leaf|Leaves],S,Type,Predict,M):- 3359 can_split(S,Type,Predict,Leaf,Left,Right,M), !, 3360 split_leaf(Leaf,Left,Right,NewLeaves,M), 3361 aleph_append(NewLeaves,Leaves,LeavesLeft), 3362 find_tree1(LeavesLeft,S,Type,Predict,M). 3363find_tree1([_|LeavesLeft],S,Type,Predict,M):- 3364 find_tree1(LeavesLeft,S,Type,Predict,M). 3365 3366prune_rules(S,Tree,Predict,M):- 3367 setting(prune_tree,true,M), 3368 prune_rules1(Tree,S,Predict,M), !. 3369prune_rules(_,_,_,_M). 3370 3371% pessimistic pruning by employing corrections to observed errors 3372prune_rules1(class_probability,_,_,_M):- 3373 p_message('no pruning for class probability trees'), !. 3374prune_rules1(model,_,_,_M):- 3375 p_message('no pruning for model trees'), !. 3376prune_rules1(Tree,S,Predict,M):- 3377 p_message('pruning clauses'), 3378 M:'$aleph_search'(tree_leaf,l(Leaf,Parent,Clause,Examples)), 3379 prune_rule(Tree,S,Predict,Clause,Examples,NewClause,NewExamples,M), 3380 retract(M:'$aleph_search'(tree_leaf,l(Leaf,Parent,Clause,Examples))), 3381 asserta(M:'$aleph_search'(tree_newleaf,l(Leaf,Parent,NewClause,NewExamples))), 3382 fail. 3383prune_rules1(_,_,_,M):- 3384 retract(M:'$aleph_search'(tree_newleaf,l(Leaf,Parent,NewClause,NewExamples))), 3385 asserta(M:'$aleph_search'(tree_leaf,l(Leaf,Parent,NewClause,NewExamples))), 3386 fail. 3387prune_rules1(_,_,_,_M). 3388 3389prune_rule(Tree,S,PredictArg,[Clause,_,N],Examples,[PrunedClause,E1,NCov],NewEx,M):- 3390 node_stats(Tree,Examples,PredictArg,Total-Distribution,M), 3391 leaf_prediction(Tree,Total-Distribution,_,Incorrect), 3392 estimate_error(Tree,Incorrect,Total,Upper,M), 3393 split_clause(Clause,Head,Body), 3394 goals_to_list(Body,BodyL), 3395 arg(14,S,Depth), 3396 arg(29,S,Time), 3397 arg(34,S,Proof), 3398 greedy_prune_rule(Tree,Depth/Time/Proof,PredictArg,[Head|BodyL],Upper,C1L,E1,M), 3399 list_to_clause(C1L,PrunedClause), 3400 % p1_message('pruned clause'), p_message(Clause), 3401 % p_message('to'), 3402 % p_message(PrunedClause), 3403 (E1 < Upper -> 3404 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)), 3405 prove(Depth/Time/Proof,pos,PrunedClause,Pos,NewEx,NCov,M); 3406 NewEx = Examples, 3407 NCov = N). 3408 3409 3410% estimate error using binomial distribution as done in C4.5 3411estimate_error(classification,Incorrect,Total,Error,M):- 3412 setting(confidence,Conf,M), 3413 estimate_error(1.0/0.0,0.0/1.0,Conf,Total,Incorrect,Error). 3414 3415% estimate upper bound on sample std deviation by 3416% assuming the n values in a leaf are normally distributed. 3417% In this case, a (1-alpha)x100 confidence interval for the 3418% variance is (n-1)s^2/X^2(alpha/2) =< var =< (n-1)s^2/X^2(1-alpha/2) 3419estimate_error(regression,Sd,1,Sd,_M):- !. 3420estimate_error(regression,Sd,N,Upper,M):- 3421 (setting(confidence,Conf,M) -> true; Conf = 0.95), 3422 Alpha is 1.0 - Conf, 3423 DF is N - 1, 3424 Prob is 1 - Alpha/2, 3425 chi_square(DF,Prob,ChiSq), 3426 Upper is Sd*sqrt((N-1)/ChiSq). 3427 3428bound_error(classification,Error,Total,Lower,Upper,M):- 3429 (setting(confidence,Alpha,M) -> true; Alpha = 0.95), 3430 approx_z(Alpha,Z), 3431 Lower is Error - Z*sqrt(Error*(1-Error)/Total), 3432 Upper is Error + Z*sqrt(Error*(1-Error)/Total). 3433 3434approx_z(P,2.58):- P >= 0.99, !. 3435approx_z(P,Z):- P >= 0.98, !, Z is 2.33 + (P-0.98)*(2.58-2.33)/(0.99-0.98). 3436approx_z(P,Z):- P >= 0.95, !, Z is 1.96 + (P-0.95)*(2.33-1.96)/(0.98-0.95). 3437approx_z(P,Z):- P >= 0.90, !, Z is 1.64 + (P-0.90)*(1.96-1.64)/(0.95-0.90). 3438approx_z(P,Z):- P >= 0.80, !, Z is 1.28 + (P-0.80)*(1.64-1.28)/(0.90-0.80). 3439approx_z(P,Z):- P >= 0.68, !, Z is 1.00 + (P-0.68)*(1.28-1.00)/(0.80-0.68). 3440approx_z(P,Z):- P >= 0.50, !, Z is 0.67 + (P-0.50)*(1.00-0.67)/(0.68-0.50). 3441approx_z(_,0.67). 3442 3443greedy_prune_rule(Tree,Flags,PredictArg,Clause,Err0,NewClause,BestErr,M):- 3444 greedy_prune_rule1(Tree,Flags,PredictArg,Clause,Err0,Clause1,Err1,M), 3445 Clause \= Clause1, !, 3446 greedy_prune_rule(Tree,Flags,PredictArg,Clause1,Err1,NewClause,BestErr,M). 3447greedy_prune_rule(_,_,_,C,E,C,E,_M). 3448 3449 3450greedy_prune_rule1(Tree,Flags,PredictArg,[Head|Body],Err0,_,_,M):- 3451 retractall(M:'$aleph_search'(tree_besterror,_)), 3452 asserta(M:'$aleph_search'(tree_besterror,besterror([Head|Body],Err0))), 3453 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)), 3454 aleph_delete(_,Body,Left), 3455 strip_negs(Left,Body1), 3456 aleph_mode_linked([Head|Body1],M), 3457 list_to_clause([Head|Left],Clause), 3458 prove(Flags,pos,Clause,Pos,Ex1,_,M), 3459 node_stats(Tree,Ex1,PredictArg,Total-Distribution,M), 3460 leaf_prediction(Tree,Total-Distribution,_,Incorrect), 3461 estimate_error(Tree,Incorrect,Total,Upper,M), 3462 M:'$aleph_search'(tree_besterror,besterror(_,BestError)), 3463 Upper =< BestError, 3464 retract(M:'$aleph_search'(tree_besterror,besterror(_,BestError))), 3465 asserta(M:'$aleph_search'(tree_besterror,besterror([Head|Left],Upper))), 3466 fail. 3467greedy_prune_rule1(_,_,_,_,_,Clause1,Err1,M):- 3468 retract(M:'$aleph_search'(tree_besterror,besterror(Clause1,Err1))). 3469 3470strip_negs([],[]). 3471strip_negs([not(L)|T],[L|T1]):- 3472 !, 3473 strip_negs(T,T1). 3474strip_negs([L|T],[L|T1]):- 3475 strip_negs(T,T1). 3476 3477add_tree(_,Tree,Predict,M):- 3478 retract(M:'$aleph_search'(tree_leaf,l(_,_,Leaf,Examples))), 3479 Leaf = [Clause,Cost,P], 3480 add_prediction(Tree,Clause,Predict,Examples,Clause1,M), 3481 p_message('best clause'), 3482 pp_dclause(Clause1,M), 3483 nlits(Clause,L), 3484 Gain is -Cost, 3485 asserta(M:'$aleph_global'(hypothesis,hypothesis([P,0,L,Gain],Clause1,Examples,[]))), 3486 addhyp(M), 3487 fail. 3488add_tree(_,_,_,_M). 3489 3490add_prediction(Tree,Clause,PredictArg,Examples,Clause1,M):- 3491 split_clause(Clause,Head,_), 3492 (Tree = model -> 3493 setting(evalfn,Evalfn,M), 3494 add_model(Evalfn,Clause,PredictArg,Examples,Clause1,_,_,M); 3495 node_stats(Tree,Examples,PredictArg,Distribution,M), 3496 leaf_prediction(Tree,Distribution,Prediction,Error), 3497 tparg(PredictArg,Head,Var), 3498 add_prediction(Tree,Clause,Var,Prediction,Error,Clause1,M)). 3499 3500add_prediction(classification,Clause,Var,Prediction,_,Clause1,_M):- 3501 extend_clause(Clause,(Var = Prediction),Clause1). 3502add_prediction(class_probability,Clause,Var,Prediction,_,Clause1,_M):- 3503 extend_clause(Clause,(random(Var,Prediction)),Clause1). 3504add_prediction(regression,Clause,Var,Mean,Sd,Clause1,_M):- 3505 extend_clause(Clause,(random(Var,normal(Mean,Sd))),Clause1). 3506 3507add_model(Evalfn,Clause,PredictArg,Examples,_,_,_,M):- 3508 retractall(M:'$aleph_local'(tree_model,_,_,_)), 3509 Best is inf, 3510 split_clause(Clause,Head,_), 3511 tparg(PredictArg,Head,Var), 3512 asserta(M:'$aleph_local'(tree_model,aleph_false,0,Best)), 3513 M:'$aleph_global'(model,model(Name/Arity)), 3514 functor(Model,Name,Arity), 3515 auto_extend(Clause,Model,C,M), 3516 leaf_predicts(Arity,Model,Var), 3517 lazy_evaluate_refinement([],C,[Name/Arity],Examples,[],[],C1,M), 3518 find_model_error(Evalfn,Examples,C1,PredictArg,Total,Error,M), 3519 % pp_dclause(C1,M), 3520 % p1_message(error), 3521 % p1_message(Error), 3522 M:'$aleph_local'(tree_model,_,_,BestSoFar), 3523 %p1_message(BestSoFar), 3524 (Error < BestSoFar -> 3525 retract(M:'$aleph_local'(tree_model,_,_,_)), 3526 asserta(M:'$aleph_local'(tree_model,C1,Total,Error)); 3527 true), 3528 fail. 3529add_model(_,_,_,_,Clause,Total,Error,M):- 3530 retract(M:'$aleph_local'(tree_model,Clause,Total,Error)). 3531 3532 3533find_model_error(Evalfn,Examples,(Head:-Body),[PredictArg],T,E,M):- 3534 functor(Head,_,Arity), 3535 findall(Actual-Pred, 3536 (aleph_member(Interval,Examples), 3537 aleph_member3(N,Interval), 3538 M:example(N,pos,Example), 3539 copy_iargs(Arity,Example,Head,PredictArg), 3540 once(M:Body), 3541 arg(PredictArg,Head,Pred), 3542 arg(PredictArg,Example,Actual) 3543 ), 3544 L), 3545 sum_model_errors(L,Evalfn,0,0.0,T,E), !. 3546 3547sum_model_errors([],_,N,E,N,E). 3548sum_model_errors([Act-Pred|T],Evalfn,NSoFar,ESoFar,N,E):- 3549 get_model_error(Evalfn,Act,Pred,E1), 3550 E1SoFar is ESoFar + E1, 3551 N1SoFar is NSoFar + 1, 3552 sum_model_errors(T,Evalfn,N1SoFar,E1SoFar,N,E). 3553 3554get_model_error(mse,Act,Pred,E):- 3555 E is (Act-Pred)^2. 3556get_model_error(accuracy,Act,Pred,E):- 3557 (Act = Pred -> E is 0.0; E is 1.0). 3558 3559leaf_predicts(0,_,_):- !, fail. 3560leaf_predicts(Arg,Model,Var):- 3561 arg(Arg,Model,Var1), 3562 var(Var1), 3563 Var1 == Var, !. 3564leaf_predicts(Arg,Model,Var):- 3565 Arg1 is Arg - 1, 3566 leaf_predicts(Arg1,Model,Var). 3567 3568leaf_prediction(classification,Total-Distribution,Class,Incorrect):- 3569 find_maj_class(Distribution,N-Class), 3570 Incorrect is Total - N. 3571leaf_prediction(class_probability,T1-D1,NDistr,0):- 3572 length(D1,NClasses), 3573 laplace_correct(D1,LaplaceD1), 3574 LaplaceTotal is T1 + NClasses, 3575 normalise_distribution(LaplaceD1,LaplaceTotal,NDistr). 3576leaf_prediction(regression,_-[Mean,Sd],Mean,Sd). 3577 3578find_maj_class([X],X):- !. 3579find_maj_class([N-Class|Rest],MajClass):- 3580 find_maj_class(Rest,N1-C1), 3581 (N > N1 -> MajClass = N-Class; MajClass = N1-C1). 3582 3583can_split(S,Type,Predict,Leaf,Left,Right,M):- 3584 arg(21,S,MinGain), 3585 M:'$aleph_search'(tree_leaf,l(Leaf,_,[Clause,Cost,N],Examples)), 3586 Cost >= MinGain, 3587 get_best_subtree(S,Type,Predict,[Clause,Cost,N],Examples,Gain,Left,Right,M), 3588 Gain >= MinGain, 3589 p_message('found clauses'), 3590 Left = [ClF,CostF|_], Right = [ClS,CostS|_], 3591 arg(4,S,_/Evalfn), 3592 pp_dclause(ClS,M), 3593 print_eval(Evalfn,CostS), 3594 pp_dclause(ClF,M), 3595 print_eval(Evalfn,CostF), 3596 p1_message('expected cost reduction'), p_message(Gain). 3597 3598get_best_subtree(S,Type,Predict,[Clause,Cost,N],Examples,Gain,Left,Right,M):- 3599 arg(42,S,Interactive), 3600 arg(43,S,LookAhead), 3601 retractall(M:'$aleph_search'(tree_gain,_)), 3602 MInf is -inf, 3603 (Interactive = false -> 3604 asserta(M:'$aleph_search'(tree_gain,tree_gain(MInf,[],[]))); 3605 true), 3606 split_clause(Clause,Head,Body), 3607 arg(4,S,_/Evalfn), 3608 arg(13,S,MinPos), 3609 auto_refine(LookAhead,Clause,ClS,M), 3610 tree_refine_ok(Type,ClS,M), 3611 eval_treenode(S,Type,ClS,Predict,Examples,ExS,NS,CostS,M), 3612 NS >= MinPos, 3613 rm_intervals(ExS,Examples,ExF), 3614 split_clause(ClS,Head,Body1), 3615 get_goaldiffs(Body,Body1,Diff), 3616 extend_clause(Clause,not(Diff),ClF), 3617 eval_treenode(S,Type,ClF,Predict,ExF,NF,CostF,M), 3618 NF >= MinPos, 3619 AvLeafCost is (NS*CostS + NF*CostF)/N, 3620 CostReduction is Cost - AvLeafCost, 3621 (Interactive = false -> 3622 pp_dclause(ClS,M), print_eval(Evalfn,CostS), 3623 pp_dclause(ClF,M), print_eval(Evalfn,CostF), 3624 p1_message('expected cost reduction'), p_message(CostReduction), 3625 M:'$aleph_search'(tree_gain,tree_gain(BestSoFar,_,_)), 3626 CostReduction > BestSoFar, 3627 retract(M:'$aleph_search'(tree_gain,tree_gain(BestSoFar,_,_))), 3628 asserta(M:'$aleph_search'(tree_gain,tree_gain(CostReduction, 3629 [ClF,CostF,NF,ExF], 3630 [ClS,CostS,NS,ExS]))); 3631 asserta(M:'$aleph_search'(tree_gain,tree_gain(CostReduction, 3632 [ClF,CostF,NF,ExF], 3633 [ClS,CostS,NS,ExS])))), 3634 3635 AvLeafCost =< 0.0, 3636 !, 3637 get_best_subtree(Interactive,Clause,Gain,Left,Right,M). 3638get_best_subtree(S,_,_,[Clause|_],_,Gain,Left,Right,M):- 3639 arg(42,S,Interactive), 3640 get_best_subtree(Interactive,Clause,Gain,Left,Right,M). 3641 3642get_best_subtree(false,_,Gain,Left,Right,M):- 3643 retract(M:'$aleph_search'(tree_gain,tree_gain(Gain,Left,Right))), !. 3644get_best_subtree(true,Clause,Gain,Left,Right,M):- 3645 nl, write('Extending path: '), nl, 3646 write('---------------'), nl, 3647 pp_dclause(Clause,M), 3648 findall(MCR-[Left,Right], 3649 (M:'$aleph_search'(tree_gain,tree_gain(CostReduction,Left,Right)), 3650 MCR is -1*CostReduction), 3651 SplitsList), 3652 keysort(SplitsList,Sorted), 3653 get_best_split(Clause,Sorted,Gain,Left,Right), 3654 retractall(M:'$aleph_search'(tree_gain,_)). 3655 3656get_best_split(Clause,Splits,Gain,Left,Right):- 3657 show_split_list(Clause,Splits), 3658 ask_best_split(Splits,Gain,Left,Right). 3659 3660show_split_list(Clause,Splits):- 3661 tab(4), write('Split Information'), nl, 3662 tab(4), write('-----------------'), nl, nl, 3663 tab(4), write('No.'), 3664 tab(4), write('Split'), 3665 nl, 3666 tab(4), write('---'), 3667 tab(4), write('-----'), 3668 nl, 3669 show_split_list(Splits,1,Clause). 3670 3671show_split_list([],_,_). 3672show_split_list([MCR-[[_,_,NF,_],[CLS,_,NS,_]]|Rest],SplitNum,Clause):- 3673 copy_term(Clause,ClauseCopy), 3674 split_clause(ClauseCopy,Head,Body), 3675 copy_term(CLS,CLSCopy), 3676 numbervars(CLSCopy,0,_), 3677 split_clause(CLSCopy,Head,Body1), 3678 get_goaldiffs(Body,Body1,Diff), 3679 Gain is -1*MCR, 3680 tab(4), write(SplitNum), 3681 tab(4), write(Diff), nl, 3682 tab(12), write('Succeeded (Right Branch): '), write(NS), nl, 3683 tab(12), write('Failed (Left Branch) : '), write(NF), nl, 3684 tab(12), write('Cost Reduction : '), write(Gain), nl, nl, 3685 NextSplit is SplitNum + 1, 3686 show_split_list(Rest,NextSplit,Clause). 3687 3688ask_best_split(Splits,Gain,Left,Right):- 3689 repeat, 3690 tab(4), write('-> '), 3691 write('Select Split Number (or "none.")'), nl, 3692 read(Answer), 3693 (Answer = none -> 3694 Gain is -inf, 3695 Left = [], 3696 Right = []; 3697 SplitNum is integer(Answer), 3698 aleph_remove_nth(SplitNum,Splits,MCR-[Left,Right],_), 3699 Gain is -1*MCR 3700 ), 3701 !. 3702 3703tree_refine_ok(model,Clause,M):- 3704 M:'$aleph_global'(model,model(Name/Arity)), 3705 functor(Model,Name,Arity), 3706 in(Clause,Model,M), !, 3707 fail. 3708tree_refine_ok(_,_,_M). 3709 3710 3711eval_treenode(S,Tree,Clause,PredictArg,PCov,N,Cost,M):- 3712 arg(4,S,_/Evalfn), 3713 treenode_cost(Tree,Evalfn,Clause,PCov,PredictArg,N,Cost,M). 3714 3715eval_treenode(S,Tree,Clause,PredictArg,Pos,PCov,N,Cost,M):- 3716 arg(4,S,_/Evalfn), 3717 arg(13,S,MinPos), 3718 arg(14,S,Depth), 3719 arg(29,S,Time), 3720 arg(34,S,Proof), 3721 prove(Depth/Time/Proof,pos,Clause,Pos,PCov,PCount,M), 3722 PCount >= MinPos, 3723 treenode_cost(Tree,Evalfn,Clause,PCov,PredictArg,N,Cost,M). 3724 3725treenode_cost(model,Evalfn,Clause,Covered,PredictArg,Total,Cost,M):- 3726 !, 3727 add_model(Evalfn,Clause,PredictArg,Covered,_,Total,Cost,M). 3728treenode_cost(Tree,Evalfn,_,Covered,PredictArg,Total,Cost,M):- 3729 node_stats(Tree,Covered,PredictArg,Total-Distribution,M), 3730 Total > 0, 3731 impurity(Tree,Evalfn,Total-Distribution,Cost). 3732 3733node_stats(Tree,Covered,PredictArg,D,M):- 3734 M:'$aleph_search'(tree_startdistribution,d(Tree,D0)), 3735 (Tree = regression -> 3736 cont_distribution(Covered,PredictArg,D0,D,M); 3737 discr_distribution(Covered,PredictArg,D0,D,M)). 3738 3739discr_distribution([],_,D,D,_M). 3740discr_distribution([S-F|Intervals],PredictArg,T0-D0,D,M):- 3741 discr_distribution(S,F,PredictArg,T0-D0,T1-D1,M), 3742 discr_distribution(Intervals,PredictArg,T1-D1,D,M). 3743 3744discr_distribution(N,F,_,D,D,_M):- N > F, !. 3745discr_distribution(N,F,PredictArg,T0-D0,D,M):- 3746 M:example(N,pos,Example), 3747 tparg(PredictArg,Example,Actual), 3748 N1 is N + 1, 3749 T1 is T0 + 1, 3750 (aleph_delete(C0-Actual,D0,D1) -> 3751 C1 is C0 + 1, 3752 discr_distribution(N1,F,PredictArg,T1-[C1-Actual|D1],D,M); 3753 discr_distribution(N1,F,PredictArg,T1-[1-Actual|D0],D,M)). 3754 3755cont_distribution([],_,T-[S,SS],T-[Mean,Sd],_M):- 3756 (T = 0 -> Mean = 0, Sd = 0; 3757 Mean is S/T, 3758 Sd is sqrt(SS/T - Mean*Mean)). 3759cont_distribution([S-F|Intervals],PredictArg,T0-D0,D,M):- 3760 cont_distribution(S,F,PredictArg,T0-D0,T1-D1,M), 3761 cont_distribution(Intervals,PredictArg,T1-D1,D,M). 3762 3763cont_distribution(N,F,_,D,D,_M):- N > F, !. 3764cont_distribution(N,F,PredictArg,T0-[S0,SS0],D,M):- 3765 M:example(N,pos,Example), 3766 tparg(PredictArg,Example,Actual), 3767 N1 is N + 1, 3768 T1 is T0 + 1, 3769 S1 is S0 + Actual, 3770 SS1 is SS0 + Actual*Actual, 3771 cont_distribution(N1,F,PredictArg,T1-[S1,SS1],D,M). 3772 3773impurity(regression,sd,_-[_,Sd],Sd):- !. 3774impurity(classification,entropy,Total-Distribution,Cost):- 3775 sum_entropy(Distribution,Total,S), 3776 Cost is -S/(Total*log(2)), !. 3777impurity(classification,gini,Total-Distribution,Cost):- 3778 sum_gini(Distribution,Total,Cost), !. 3779impurity(class_probability,entropy,Total-Distribution,Cost):- 3780 sum_entropy(Distribution,Total,S), 3781 Cost is -S/(Total*log(2)), !. 3782impurity(class_probability,gini,Total-Distribution,Cost):- 3783 sum_gini(Distribution,Total,Cost), !. 3784impurity(_,_,_,_):- 3785 err_message('inappropriate settings for tree_type and/or evalfn'), 3786 fail. 3787 3788 3789sum_gini([],_,0). 3790sum_gini([N-_|Rest],Total,Sum):- 3791 N > 0, !, 3792 sum_gini(Rest,Total,C0), 3793 P is N/Total, 3794 Sum is P*(1-P) + C0. 3795sum_gini([_|Rest],Total,Sum):- 3796 sum_gini(Rest,Total,Sum). 3797 3798sum_entropy([],_,0). 3799sum_entropy([N-_|Rest],Total,Sum):- 3800 N > 0, !, 3801 sum_entropy(Rest,Total,C0), 3802 Sum is N*log(N/Total) + C0. 3803sum_entropy([_|Rest],Total,Sum):- 3804 sum_entropy(Rest,Total,Sum). 3805 3806% only binary splits 3807% left = condition at node fails 3808% right = condition at node succeeds 3809split_leaf(Leaf,LeftTree,RightTree,[Left,Right],M):- 3810 retract(M:'$aleph_search'(tree_leaf,l(Leaf,Parent, 3811 [Clause,Cost,N],Examples))), 3812 gen_leaf(Left,M), 3813 gen_leaf(Right,M), 3814 LeftTree = [ClF,CostF,NF,ExF], 3815 RightTree = [ClS,CostS,NS,ExS], 3816 asserta(M:'$aleph_search'(tree,t(Leaf,Parent,[Clause,Cost,N], 3817 Examples,Left,Right))), 3818 asserta(M:'$aleph_search'(tree_leaf,l(Left,Leaf,[ClF,CostF,NF],ExF))), 3819 asserta(M:'$aleph_search'(tree_leaf,l(Right,Leaf,[ClS,CostS,NS],ExS))). 3820 3821gen_leaf(Leaf1,M):- 3822 retract(M:'$aleph_search'(tree_lastleaf,Leaf0)), !, 3823 Leaf1 is Leaf0 + 1, 3824 asserta(M:'$aleph_search'(tree_lastleaf,Leaf1)). 3825gen_leaf(0,M):- 3826 asserta(M:'$aleph_search'(tree_lastleaf,0)). 3827 3828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3829% G C W S 3830 3831% examine list of clauses to be specialised 3832% generate an exception theory for each clause that covers negative examples 3833gcws(M):- 3834 setting(evalfn,EvalFn,M), 3835 repeat, 3836 retract(M:'$aleph_search'(sphyp,hypothesis([P,N,L|T],Clause,PCover,NCover))), 3837 (PCover = _/_ -> label_create(pos,Clause,Label1,M), 3838 extract_pos(Label1,PCover1), 3839 interval_count(PCover1,P1); 3840 PCover1 = PCover, 3841 P1 = P), 3842 (NCover = _/_ -> label_create(neg,Clause,Label2,M), 3843 extract_neg(Label2,NCover1), 3844 interval_count(NCover1,N1); 3845 NCover1 = NCover, 3846 N1 = N), 3847 (N1 = 0 -> NewClause = Clause, NewLabel = [P1,N1,L|T]; 3848 MinAcc is P1/(2*P1 - 1), 3849 set(minacc,MinAcc,M), 3850 set(noise,N1,M), 3851 gcws(Clause,PCover1,NCover1,NewClause,M), 3852 L1 is L + 1, 3853 complete_label(EvalFn,NewClause,[P,0,L1],NewLabel,M)), 3854 assertz(M:'$aleph_search'(gcwshyp,hypothesis(NewLabel,NewClause,PCover1,[]))), 3855 \+(M:'$aleph_search'(sphyp,hypothesis(_,_,_,_))), !. 3856 3857 3858% gcws(+Clause,+PCvr,+NCvr,-Clause1) 3859% specialise Clause that covers pos examples PCvr and neg examples NCvr 3860% result is is Clause extended with a single negated literal 3861% clauses in exception theory are added to list for specialisation 3862gcws(Clause,PCover,NCover,Clause1,M):- 3863 gen_absym(AbName,M), 3864 split_clause(Clause,Head,Body), 3865 functor(Head,_,Arity), 3866 add_determinations(AbName/Arity,true,M), 3867 add_modes(AbName/Arity,M), 3868 gen_ab_examples(AbName/Arity,PCover,NCover,M), 3869 cwinduce(M), 3870 Head =.. [_|Args], 3871 AbLit =.. [AbName|Args], 3872 (Body = true -> Body1 = not(AbLit) ; app_lit(not(AbLit),Body,Body1)), 3873 Clause1 = (Head:-Body1). 3874 3875% greedy set-cover based construction of abnormality theory 3876% starts with the first exceptional example 3877% each clause obtained is added to list of clauses to be specialised 3878cwinduce(M):- 3879 store(greedy,M), 3880 set(greedy,true,M), 3881 M:'$aleph_global'(atoms_left,atoms_left(pos,PosSet)), 3882 PosSet \= [], 3883 repeat, 3884 M:'$aleph_global'(atoms_left,atoms_left(pos,[Num-X|Y])), 3885 sat(Num,M), 3886 reduce(M:_), 3887 retract(M:'$aleph_global'(hypothesis,hypothesis(Label,H,PCover,NCover))), 3888 asserta(M:'$aleph_search'(sphyp,hypothesis(Label,H,PCover,NCover))), 3889 rm_seeds1(PCover,[Num-X|Y],NewPosLeft), 3890 retract(M:'$aleph_global'(atoms_left,atoms_left(pos,[Num-X|Y]))), 3891 asserta(M:'$aleph_global'(atoms_left,atoms_left(pos,NewPosLeft))), 3892 NewPosLeft = [], 3893 retract(M:'$aleph_global'(atoms_left,atoms_left(pos,NewPosLeft))), 3894 reinstate(greedy,M), !. 3895cwinduce(_M). 3896 3897 3898% gen_ab_examples(+Ab,+PCover,+NCover) 3899% obtain examples for abnormality predicate Ab by 3900% pos examples are copies of neg examples in NCover 3901% neg examples are copies of pos examples in PCover 3902% writes new examples to temporary ".f" and ".n" files 3903% to ensure example/3 remains a static predicate 3904% alters search parameters accordingly 3905gen_ab_examples(Ab/_,PCover,NCover,M):- 3906 create_examples(PosFile,Ab,neg,NCover,pos,PCover1,M), 3907 create_examples(NegFile,Ab,pos,PCover,neg,NCover1,M), 3908 aleph_consult(PosFile,M), 3909 aleph_consult(NegFile,M), 3910 retractall(M:'$aleph_global'(atoms_left,_)), 3911 retractall(M:'$aleph_global'(size,_)), 3912 asserta(M:'$aleph_global'(atoms_left,atoms_left(pos,PCover1))), 3913 asserta(M:'$aleph_global'(atoms_left,atoms_left(neg,NCover1))), 3914 interval_count(PCover1,PSize), 3915 interval_count(NCover1,NSize), 3916 asserta(M:'$aleph_global'(size,size(pos,PSize))), 3917 asserta(M:'$aleph_global'(size,size(neg,NSize))), 3918 delete_file(PosFile), 3919 delete_file(NegFile). 3920 3921% create_examples(+File,+OldType,+OldE,+NewType,-NewE) 3922% copy OldE examples of OldType to give NewE examples of NewType 3923% copy stored in File 3924create_examples(File,Ab,OldT,OldE,NewT,[Next-Last],M):- 3925 tmp_file_stream(utf8,File,Stream), 3926 M:'$aleph_global'(last_example,last_example(NewT,OldLast)), 3927 set_output(Stream), 3928 create_copy(OldE,OldT,NewT,Ab,OldLast,Last,M), 3929 close(Stream), 3930 set_output(user_output), 3931 Last > OldLast, !, 3932 retract(M:'$aleph_global'(last_example,last_example(NewT,OldLast))), 3933 Next is OldLast + 1, 3934 asserta(M:'$aleph_global'(last_example,last_example(NewT,Last))). 3935create_examples(_,_,_,_,_,[],_M). 3936 3937create_copy([],_,_,_,L,L,_M). 3938create_copy([X-Y|T],OldT,NewT,Ab,Num,Last,M):- 3939 create_copy(X,Y,OldT,NewT,Ab,Num,Num1,M), 3940 create_copy(T,OldT,NewT,Ab,Num1,Last,M). 3941 3942create_copy(X,Y,_,_,_,L,L,_M):- X > Y, !. 3943create_copy(X,Y,OldT,NewT,Ab,Num,Last,M):- 3944 M:example(X,OldT,Example), 3945 Example =.. [_|Args], 3946 NewExample =.. [Ab|Args], 3947 Num1 is Num + 1, 3948 aleph_writeq(example(Num1,NewT,NewExample)), write('.'), nl, 3949 X1 is X + 1, 3950 create_copy(X1,Y,OldT,NewT,Ab,Num1,Last,M). 3951 3952% gen_absym(-Name) 3953% generate new abnormality predicate symbol 3954gen_absym(Name,M):- 3955 (retract(M:'$aleph_global'(last_ab,last_ab(N))) -> 3956 N1 is N + 1; 3957 N1 is 0), 3958 asserta(M:'$aleph_global'(last_ab,last_ab(N1))), 3959 concat([ab,N1],Name). 3960%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3961% C L A U S E O P T I M I S A T I O N S 3962 3963 3964optimise(Clause,Clause1):- 3965 remove_redundant(Clause,Clause0), 3966 reorder_clause(Clause0,Clause1). 3967 3968remove_redundant((Head:-Body),(Head1:-Body1)):- 3969 goals_to_list((Head,Body),ClauseL), 3970 remove_subsumed(ClauseL,[Head1|Body1L]), 3971 (Body1L = [] -> Body1 = true; list_to_goals(Body1L,Body1)). 3972 3973reorder_clause((Head:-Body), Clause) :- 3974 % term_variables(Head,LHead), 3975 vars_in_term([Head],[],LHead), 3976 number_goals_and_get_vars(Body,LHead,1,_,[],Conj), 3977 calculate_independent_sets(Conj,[],BSets), 3978 compile_clause(BSets,Head,Clause). 3979 3980number_goals_and_get_vars((G,Body),LHead,I0,IF,L0,[g(I0,LVF,NG)|LGs]) :- !, 3981 I is I0+1, 3982 get_goal_vars(G,LHead,LVF,NG), 3983 number_goals_and_get_vars(Body,LHead,I,IF,L0,LGs). 3984number_goals_and_get_vars(G,LHead,I,I,L0,[g(I,LVF,NG)|L0]) :- 3985 get_goal_vars(G,LHead,LVF,NG). 3986 3987get_goal_vars(G,LHead,LVF,G) :- 3988 % term_variables(G,LV0), 3989 vars_in_term([G],[],LVI), 3990 aleph_ord_subtract(LVI,LHead,LVF). 3991 3992calculate_independent_sets([],BSets,BSets). 3993calculate_independent_sets([G|Ls],BSets0,BSetsF) :- 3994 add_goal_to_set(G,BSets0,BSetsI), 3995 calculate_independent_sets(Ls,BSetsI,BSetsF). 3996 3997add_goal_to_set(g(I,LV,G),Sets0,SetsF) :- 3998 add_to_sets(Sets0,LV,[g(I,LV,G)],SetsF). 3999 4000add_to_sets([],LV,Gs,[[LV|Gs]]). 4001add_to_sets([[LV|Gs]|Sets0],LVC,GsC,[[LV|Gs]|SetsF]) :- 4002 aleph_ord_disjoint(LV,LVC), !, 4003 add_to_sets(Sets0,LVC,GsC,SetsF). 4004add_to_sets([[LV|Gs]|Sets0],LVC,GsC,SetsF) :- 4005 aleph_ord_union(LV,LVC,LVN), 4006 join_goals(Gs,GsC,GsN), 4007 add_to_sets(Sets0,LVN,GsN,SetsF). 4008 4009join_goals([],L,L):- !. 4010join_goals(L,[],L):- !. 4011join_goals([g(I1,VL1,G1)|T],[g(I2,VL2,G2)|T2],Z) :- 4012 I1 < I2, !, 4013 Z = [g(I1,VL1,G1)|TN], 4014 join_goals(T,[g(I2,VL2,G2)|T2],TN). 4015join_goals([H|T],[g(I2,VL2,G2)|T2],Z) :- 4016 Z = [g(I2,VL2,G2)|TN], 4017 join_goals(T,[H|T2],TN). 4018 4019compile_clause(Goals,Head,(Head:-Body)):- 4020 compile_clause2(Goals,Body). 4021 4022compile_clause2([[_|B]], B1):- 4023 !, 4024 glist_to_goals(B,B1). 4025compile_clause2([[_|B]|Bs],(B1,!,NB)):- 4026 glist_to_goals(B,B1), 4027 compile_clause2(Bs,NB). 4028 4029glist_to_goals([g(_,_,Goal)],Goal):- !. 4030glist_to_goals([g(_,_,Goal)|Goals],(Goal,Goals1)):- 4031 glist_to_goals(Goals,Goals1). 4032 4033% remove literals subsumed in the body of a clause 4034remove_subsumed([Head|Lits],Lits1):- 4035 delete(Lit,Lits,Left), 4036 \+(\+(redundant(Lit,[Head|Lits],[Head|Left]))), !, 4037 remove_subsumed([Head|Left],Lits1). 4038remove_subsumed(L,L). 4039 4040% determine if Lit is subsumed by a body literal 4041redundant(Lit,Lits,[Head|Body]):- 4042 copy_term([Head|Body],Rest1), 4043 member(Lit1,Body), 4044 Lit = Lit1, 4045 aleph_subsumes(Lits,Rest1).
4052aleph_subsumes(Lits,Lits1):- 4053 \+(\+((numbervars(Lits,0,_),numbervars(Lits1,0,_),aleph_subset1(Lits,Lits1)))). 4054 4055 4056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4057% S A T / R E D U C E
4067sat(M:Num):- 4068 sat(Num,M). 4069 4070sat(Num,M):- 4071 integer(Num),!, 4072 M:example(Num,pos,_), 4073 sat(pos,Num,M),!. 4074sat(Example,M):- 4075 record_example(check,uspec,Example,Num,M), 4076 sat(uspec,Num,M), !. 4077 4078sat(Type,Num,M):- 4079 setting(construct_bottom,false,M), !, 4080 sat_prelims(M), 4081 M:example(Num,Type,Example), 4082 broadcast(start(sat(Num))), 4083 p1_message('sat'), p_message(Num), p_message(Example), 4084 record_sat_example(Num,M), 4085 asserta(M:'$aleph_sat'(example,example(Num,Type))), 4086 asserta(M:'$aleph_sat'(hovars,[])), 4087 broadcast(end(sat(Num, 0, 0.0))). 4088sat(Type,Num,M):- 4089 setting(construct_bottom,reduction,M), !, 4090 sat_prelims(M), 4091 M:example(Num,Type,Example), 4092 broadcast(start(sat(Num))), 4093 p1_message('sat'), p_message(Num), p_message(Example), 4094 record_sat_example(Num,M), 4095 asserta(M:'$aleph_sat'(example,example(Num,Type))), 4096 integrate_head_lit(HeadOVars,M), 4097 asserta(M:'$aleph_sat'(hovars,HeadOVars)), 4098 broadcast(end(sat(Num, 0, 0.0))). 4099sat(Type,Num,M):- 4100 set(stage,saturation,M), 4101 sat_prelims(M), 4102 M:example(Num,Type,Example), 4103 broadcast(start(sat(Num))), 4104 p1_message('sat'), p_message(Num), p_message(Example), 4105 record_sat_example(Num,M), 4106 asserta(M:'$aleph_sat'(example,example(Num,Type))), 4107 split_args(Example,Mode,Input,Output,Constants,M), 4108 integrate_args(unknown,Example,Output,M), 4109 stopwatch(StartClock), 4110 assertz(M:'$aleph_sat_atom'(Example,mode(Mode,Output,Input,Constants))), 4111 M:'$aleph_global'(i,set(i,Ival)), 4112 flatten(0,Ival,0,Last1,M), 4113 M:'$aleph_sat_litinfo'(1,_,Atom,_,_,_), 4114 get_vars(Atom,Output,HeadOVars), 4115 asserta(M:'$aleph_sat'(hovars,HeadOVars)), 4116 get_vars(Atom,Input,HeadIVars), 4117 asserta(M:'$aleph_sat'(hivars,HeadIVars)), 4118 functor(Example,Name,Arity), 4119 get_determs(Name/Arity,L,M), 4120 (M:'$aleph_global'(determination,determination(Name/Arity,'='/2))-> 4121 asserta(M:'$aleph_sat'(eq,true)); 4122 asserta(M:'$aleph_sat'(eq,false))), 4123 get_atoms(L,1,Ival,Last1,Last,M), 4124 stopwatch(StopClock), 4125 Time is StopClock - StartClock, 4126 asserta(M:'$aleph_sat'(lastlit,Last)), 4127 asserta(M:'$aleph_sat'(botsize,Last)), 4128 update_generators(M), 4129 rm_moderepeats(Last,Repeats,M), 4130 rm_commutative(Last,Commutative,M), 4131 rm_symmetric(Last,Symmetric,M), 4132 rm_redundant(Last,Redundant,M), 4133 rm_uselesslits(Last,NotConnected,M), 4134 rm_nreduce(Last,NegReduced,M), 4135 /* write("Last:"),nl,write(Last),nl, 4136 write("Repeats:"),nl,write(Repeats),nl, 4137 write("NotConnected:"),nl,write(NotConnected),nl, 4138 write("Commutative:"),nl,write(Commutative),nl, 4139 write("Symmetric:"),nl,write(Symmetric),nl, 4140 write("Redundant:"),nl,write(Redundant),nl, 4141 write("NegReduced:"),nl,write(NegReduced),nl, */ 4142 TotalLiterals is 4143 Last-Repeats-NotConnected-Commutative-Symmetric-Redundant-NegReduced, 4144 show(bottom,M), 4145 p1_message('literals'), p_message(TotalLiterals), 4146 p1_message('saturation time'), p_message(Time), 4147 broadcast(end(sat(Num, TotalLiterals, Time))), 4148 store(bottom,M), 4149 noset(stage,M). 4150sat(_,_,M):- 4151 noset(stage,M).
4158reduce(M:Cl):- 4159 setting(search,Search,M), 4160 catch(reduce(Search,Cl,M),abort,reinstate_values), !. 4161 4162reduce(Search,M):- 4163 reduce(Search,_Cl,M). 4164% no search: add bottom clause as hypothesis 4165reduce(false,B,M):- 4166 !, 4167 add_bottom(B,M). 4168% iterative beam search as described by Ross Quinlan+MikeCameron-Jones,IJCAI-95 4169reduce(ibs,RClause,M):- 4170 !, 4171 retractall(M:'$aleph_search'(ibs_rval,_)), 4172 retractall(M:'$aleph_search'(ibs_nodes,_)), 4173 retractall(M:'$aleph_search'(ibs_selected,_)), 4174 store_values([openlist,caching,explore],M), 4175 set(openlist,1,M), 4176 set(caching,true,M), 4177 set(explore,true,M), 4178 asserta(M:'$aleph_search'(ibs_rval,1.0)), 4179 asserta(M:'$aleph_search'(ibs_nodes,0)), 4180 setting(evalfn,Evalfn,M), 4181 get_start_label(Evalfn,Label,M), 4182 (M:'$aleph_sat'(example,example(Num,Type)) -> 4183 M:example(Num,Type,Example), 4184 asserta(M:'$aleph_search'(ibs_selected,selected(Label,(Example:-true), 4185 [Num-Num],[]))); 4186 asserta(M:'$aleph_search'(ibs_selected,selected(Label,(false:-true), 4187 [],[])))), 4188 stopwatch(Start), 4189 repeat, 4190 setting(openlist,OldOpen,M), 4191 p1_message('ibs beam width'), p_message(OldOpen), 4192 find_clause(bf,M), 4193 M:'$aleph_search'(current,current(_,Nodes0,[PC,NC|_]/_)), 4194 N is NC + PC, 4195 estimate_error_rate(Nodes0,0.5,N,NC,NewR), 4196 p1_message('ibs estimated error'), p_message(NewR), 4197 retract(M:'$aleph_search'(ibs_rval,OldR)), 4198 retract(M:'$aleph_search'(ibs_nodes,Nodes1)), 4199 M:'$aleph_search'(selected,selected(BL,RCl,PCov,NCov)), 4200 NewOpen is 2*OldOpen, 4201 Nodes2 is Nodes0 + Nodes1, 4202 set(openlist,NewOpen,M), 4203 asserta(M:'$aleph_search'(ibs_rval,NewR)), 4204 asserta(M:'$aleph_search'(ibs_nodes,Nodes2)), 4205 ((NewR >= OldR; NewOpen > 512) -> true; 4206 retract(M:'$aleph_search'(ibs_selected,selected(_,_,_,_))), 4207 asserta(M:'$aleph_search'(ibs_selected,selected(BL,RCl,PCov,NCov))), 4208 fail), 4209 !, 4210 stopwatch(Stop), 4211 Time is Stop - Start, 4212 retractall(M:'$aleph_search'(ibs_rval,_)), 4213 retract(M:'$aleph_search'(ibs_nodes,Nodes)), 4214 retract(M:'$aleph_search'(ibs_selected,selected(BestLabel,RClause,PCover,NCover))), 4215 add_hyp(BestLabel,RClause,PCover,NCover,M), 4216 p1_message('ibs clauses constructed'), p_message(Nodes), 4217 p1_message('ibs search time'), p_message(Time), 4218 p_message('ibs best clause'), 4219 pp_dclause(RClause,M), 4220 show_stats(Evalfn,BestLabel), 4221 record_search_stats(RClause,Nodes,Time), 4222 reinstate_values([openlist,caching,explore]). 4223 4224% iterative deepening search 4225reduce(id,RClause,M):- 4226 !, 4227 retractall(M:'$aleph_search'(id_nodes,_)), 4228 retractall(M:'$aleph_search'(id_selected,_)), 4229 store_values([caching,clauselength],M), 4230 setting(clauselength,MaxCLen,M), 4231 set(clauselength,1,M), 4232 set(caching,true,M), 4233 asserta(M:'$aleph_search'(id_nodes,0)), 4234 setting(evalfn,Evalfn,M), 4235 get_start_label(Evalfn,Label,M), 4236 (M:'$aleph_sat'(example,example(Num,Type)) -> 4237 M:example(Num,Type,Example), 4238 asserta(M:'$aleph_search'(id_selected,selected(Label,(Example:-true), 4239 [Num-Num],[]))); 4240 asserta(M:'$aleph_search'(id_selected,selected(Label,(false:-true), 4241 [],[])))), 4242 stopwatch(Start), 4243 repeat, 4244 setting(clauselength,OldCLen,M), 4245 p1_message('id clauselength setting'), p_message(OldCLen), 4246 find_clause(df,M), 4247 M:'$aleph_search'(current,current(_,Nodes0,_)), 4248 retract(M:'$aleph_search'(id_nodes,Nodes1)), 4249 M:'$aleph_search'(selected,selected([P,N,L,F|T],RCl,PCov,NCov)), 4250 M:'$aleph_search'(id_selected,selected([_,_,_,F1|_],_,_,_)), 4251 NewCLen is OldCLen + 1, 4252 Nodes2 is Nodes0 + Nodes1, 4253 set(clauselength,NewCLen,M), 4254 M:'$aleph_search'(id_nodes,Nodes2), 4255 (F1 >= F -> true; 4256 retract(M:'$aleph_search'(id_selected,selected([_,_,_,F1|_],_,_,_))), 4257 asserta(M:'$aleph_search'(id_selected,selected([P,N,L,F|T],RCl,PCov,NCov))), 4258 set(best,[P,N,L,F|T],M)), 4259 NewCLen > MaxCLen, 4260 !, 4261 stopwatch(Stop), 4262 Time is Stop - Start, 4263 retract(M:'$aleph_search'(id_nodes,Nodes)), 4264 retract(M:'$aleph_search'(id_selected,selected(BestLabel,RClause,PCover,NCover))), 4265 add_hyp(BestLabel,RClause,PCover,NCover,M), 4266 p1_message('id clauses constructed'), p_message(Nodes), 4267 p1_message('id search time'), p_message(Time), 4268 p_message('id best clause'), 4269 pp_dclause(RClause,M), 4270 show_stats(Evalfn,BestLabel), 4271 record_search_stats(RClause,Nodes,Time,M), 4272 noset(best,M), 4273 reinstate_values([caching,clauselength],M). 4274 4275% iterative language search as described by Rui Camacho, 1996 4276reduce(ils,RClause,M):- 4277 !, 4278 retractall(M:'$aleph_search'(ils_nodes,_)), 4279 retractall(M:'$aleph_search'(ils_selected,_)), 4280 store_values([caching,language],M), 4281 set(searchstrat,bf,M), 4282 set(language,1,M), 4283 set(caching,true,M), 4284 asserta(M:'$aleph_search'(ils_nodes,0)), 4285 setting(evalfn,Evalfn,M), 4286 get_start_label(Evalfn,Label,M), 4287 (M:'$aleph_sat'(example,example(Num,Type)) -> 4288 M:example(Num,Type,Example), 4289 asserta(M:'$aleph_search'(ils_selected,selected(Label,(Example:-true), 4290 [Num-Num],[]))); 4291 asserta(M:'$aleph_search'(ils_selected,selected(Label,(false:-true), 4292 [],[])))), 4293 stopwatch(Start), 4294 repeat, 4295 setting(language,OldLang,M), 4296 p1_message('ils language setting'), p_message(OldLang), 4297 find_clause(bf,M), 4298 M:'$aleph_search'(current,current(_,Nodes0,_)), 4299 retract(M:'$aleph_search'(ils_nodes,Nodes1)), 4300 M:'$aleph_search'(selected,selected([P,N,L,F|T],RCl,PCov,NCov)), 4301 M:'$aleph_search'(ils_selected,selected([_,_,_,F1|_],_,_,_)), 4302 NewLang is OldLang + 1, 4303 Nodes2 is Nodes0 + Nodes1, 4304 set(language,NewLang,M), 4305 asserta(M:'$aleph_search'(ils_nodes,Nodes2)), 4306 (F1 >= F -> true; 4307 retract(M:'$aleph_search'(ils_selected,selected([_,_,_,F1|_],_,_,_))), 4308 asserta(M:'$aleph_search'(ils_selected,selected([P,N,L,F|T],RCl,PCov,NCov))), 4309 set(best,[P,N,L,F|T],M), 4310 fail), 4311 !, 4312 stopwatch(Stop), 4313 Time is Stop - Start, 4314 retract(M:'$aleph_search'(ils_nodes,Nodes)), 4315 retract(M:'$aleph_search'(ils_selected,selected(BestLabel,RClause,PCover,NCover))), 4316 add_hyp(BestLabel,RClause,PCover,NCover,M), 4317 p1_message('ils clauses constructed'), p_message(Nodes), 4318 p1_message('ils search time'), p_message(Time), 4319 p_message('ils best clause'), 4320 pp_dclause(RClause,M), 4321 show_stats(Evalfn,BestLabel), 4322 record_search_stats(RClause,Nodes,Time,M), 4323 noset(best,M), 4324 reinstate_values([caching,language],M). 4325 4326 4327% implementation of a randomised local search for clauses 4328% currently, this can use either: simulated annealing with a fixed temp 4329% or a GSAT-like algorithm 4330% the choice of these is specified by the parameter: rls_type 4331% both annealing and GSAT employ random multiple restarts 4332% and a limit on the number of moves 4333% the number of restarts is specified by set(tries,...) 4334% the number of moves is specified by set(moves,...) 4335% annealing currently restricted to using a fixed temperature 4336% the temperature is specified by set(temperature,...) 4337% the use of a fixed temp. makes it equivalent to the Metropolis alg. 4338% GSAT if given a ``random-walk probability'' performs Selman et als walksat 4339% the walk probability is specified by set(walk,...) 4340% a walk probability of 0 is equivalent to doing standard GSAT 4341reduce(rls,RBest,M):- 4342 !, 4343 setting(tries,MaxTries,M), 4344 MaxTries >= 1, 4345 store_values([caching,refine,refineop],M), 4346 set(searchstrat,heuristic,M), 4347 set(caching,true,M), 4348 setting(refine,Refine,M), 4349 (Refine \= false -> true; set(refineop,rls,M)), 4350 setting(threads,Threads,M), 4351 rls_search(Threads, MaxTries, Time, Nodes, selected(BestLabel, 4352 RBest,PCover,NCover),M), 4353 add_hyp(BestLabel,RBest,PCover,NCover,M), 4354 p1_message('rls nodes constructed'), p_message(Nodes), 4355 p1_message('rls search time'), p_message(Time), 4356 p_message('rls best result'), 4357 pp_dclause(RBest,M), 4358 setting(evalfn,Evalfn,M), 4359 show_stats(Evalfn,BestLabel), 4360 record_search_stats(RBest,Nodes,Time,M), 4361 noset(best,M), 4362 reinstate_values([caching,refine,refineop],M). 4363 4364 4365% stochastic clause selection based on ordinal optimisation 4366% see papers by Y.C. Ho and colleagues for more details 4367reduce(scs,RBest,M):- 4368 !, 4369 store_values([tries,moves,rls_type,clauselength_distribution],M), 4370 stopwatch(Start), 4371 (setting(scs_sample,SampleSize,M) -> true; 4372 setting(scs_percentile,K,M), 4373 K > 0.0, 4374 setting(scs_prob,P,M), 4375 P < 1.0, 4376 SampleSize is integer(log(1-P)/log(1-K/100) + 1)), 4377 (setting(scs_type,informed,M,M)-> 4378 (setting(clauselength_distribution,_D,M,M) -> true; 4379 setting(clauselength,CL,M), 4380 estimate_clauselength_distribution(CL,100,K,D,M), 4381 % max_in_list(D,Prob-Length), 4382 % p1_message('using clauselength distribution'), 4383 % p_message([Prob-Length]), 4384 % set(clauselength_distribution,[Prob-Length])); 4385 p1_message('using clauselength distribution'), 4386 p_message(D), 4387 set(clauselength_distribution,D,M)); 4388 true), 4389 set(tries,SampleSize,M), 4390 set(moves,0,M), 4391 set(rls_type,gsat,M), 4392 reduce(rls,M), 4393 stopwatch(Stop), 4394 Time is Stop - Start, 4395 M:'$aleph_search'(rls_nodes,Nodes), 4396 M:'$aleph_search'(rls_selected,selected(BestLabel,RBest,_,_)), 4397 p1_message('scs nodes constructed'), p_message(Nodes), 4398 p1_message('scs search time'), p_message(Time), 4399 p_message('scs best result'), 4400 pp_dclause(RBest,M), 4401 setting(evalfn,Evalfn,M), 4402 show_stats(Evalfn,BestLabel), 4403 record_search_stats(RBest,Nodes,Time,M), 4404 p1_message('scs search time'), p_message(Time), 4405 reinstate_values([tries,moves,rls_type,clauselength_distribution],M). 4406 4407% simple association rule search 4408% For a much more sophisticated approach see: L. Dehaspe, PhD Thesis, 1998 4409% Here, simply find all rules within search that cover at least 4410% a pre-specificed fraction of the positive examples 4411reduce(ar,Cl,M):- 4412 !, 4413 clear_cache(M), 4414 (setting(pos_fraction,PFrac,M) -> true; 4415 p_message('value required for pos_fraction parameter'), 4416 fail), 4417 M:'$aleph_global'(atoms_left,atoms_left(pos,Pos)), 4418 retract(M:'$aleph_global'(atoms_left,atoms_left(neg,Neg))), 4419 interval_count(Pos,P), 4420 MinPos is PFrac*P, 4421 store_values([minpos,evalfn,explore,caching,minacc,good],M), 4422 set(searchstrat,bf,M), 4423 set(minpos,MinPos,M), 4424 set(evalfn,coverage,M), 4425 set(explore,true,M), 4426 set(caching,true,M), 4427 set(minacc,0.0,M), 4428 set(good,true,M), 4429 asserta(M:'$aleph_global'(atoms_left,atoms_left(neg,[]))), 4430 find_clause(bf,M), 4431 show(good,M), 4432 good_clauses(Cl,M), 4433 retract(M:'$aleph_global'(atoms_left,atoms_left(neg,[]))), 4434 asserta(M:'$aleph_global'(atoms_left,atoms_left(neg,Neg))), 4435 reinstate_values([minpos,evalfn,explore,caching,minacc,good],M). 4436 4437% search for integrity constraints 4438% modelled on the work by L. De Raedt and L. Dehaspe, 1996 4439reduce(ic,Cl,M):- 4440 !, 4441 store_values([minpos,minscore,evalfn,explore,refineop],M), 4442 setting(refineop,RefineOp,M), 4443 (RefineOp = false -> set(refineop,auto,M); true), 4444 set(minpos,0,M), 4445 set(searchstrat,bf,M), 4446 set(evalfn,coverage,M), 4447 set(explore,true,M), 4448 setting(noise,N,M), 4449 MinScore is -N, 4450 set(minscore,MinScore,M), 4451 find_clause(bf,Cl,M), 4452 reinstate_values([minpos,minscore,evalfn,explore,refineop],M). 4453 4454reduce(bf,Cl,M):- 4455 !, 4456 find_clause(bf,Cl,M). 4457 4458reduce(df,Cl,M):- 4459 !, 4460 find_clause(df,Cl,M). 4461 4462reduce(heuristic,Cl,M):- 4463 !, 4464 find_clause(heuristic,Cl,M). 4465 4466 4467% find_clause(Search,M) where Search is one of bf, df, heuristic 4468find_clause(Search,M):- 4469 find_clause(Search,_Cl,M). 4470 4471find_clause(Search,RClause,M):- 4472 set(stage,reduction,M), 4473 set(searchstrat,Search,M), 4474 p_message('reduce'), 4475 reduce_prelims(L,P,N,M), 4476 asserta(M:'$aleph_search'(openlist,[])), 4477 get_search_settings(S,M), 4478 arg(4,S,_/Evalfn), 4479 get_start_label(Evalfn,Label,M), 4480 (M:'$aleph_sat'(example,example(Num,Type)) -> 4481 M:example(Num,Type,Example), 4482 asserta(M:'$aleph_search'(selected,selected(Label,(Example:-true), 4483 [Num-Num],[]))); 4484 asserta(M:'$aleph_search'(selected,selected(Label,(false:-true),[],[])))), 4485 arg(13,S,MinPos), 4486 interval_count(P,PosLeft), 4487 PosLeft >= MinPos, 4488 M:'$aleph_search'(selected,selected(L0,C0,P0,N0)), 4489 add_hyp(L0,C0,P0,N0,M), 4490 (M:'$aleph_global'(max_set,max_set(Type,Num,Label1,ClauseNum))-> 4491 BestSoFar = Label1/ClauseNum; 4492 (M:'$aleph_global'(best,set(best,Label2))-> 4493 BestSoFar = Label2/0; 4494 BestSoFar = Label/0)), 4495 asserta(M:'$aleph_search'(best_label,BestSoFar)), 4496 p1_message('best label so far'), p_message(BestSoFar), 4497 arg(3,S,RefineOp), 4498 4499 stopwatch(StartClock), 4500 (RefineOp = false -> 4501 get_gains(S,0,BestSoFar,[],false,[],0,L,[1],P,N,[],1,Last,NextBest,M), 4502 update_max_head_count(0,Last,M); 4503 clear_cache(M), 4504 4505 interval_count(P,MaxPC), 4506 asserta(M:'$aleph_local'(max_head_count,MaxPC)), 4507 StartClause = 0-[Num,Type,[],aleph_false], 4508 get_gains(S,0,BestSoFar,StartClause,_,_,_,L,[StartClause], 4509 P,N,[],1,Last,NextBest,M)), 4510 asserta(M:'$aleph_search_expansion'(1,0,1,Last)), 4511 4512 get_nextbest(S,_,M), 4513 asserta(M:'$aleph_search'(current,current(1,Last,NextBest))), 4514 4515 search(S,Nodes,M), 4516 stopwatch(StopClock), 4517 Time is StopClock - StartClock, 4518 M:'$aleph_search'(selected,selected(BestLabel,RClause,PCover,NCover)), 4519 retract(M:'$aleph_search'(openlist,_)), 4520 add_hyp(BestLabel,RClause,PCover,NCover,M), 4521 p1_message('clauses constructed'), p_message(Nodes), 4522 p1_message('search time'), p_message(Time), 4523 p_message('best clause'), 4524 pp_dclause(RClause,M), 4525 show_stats(Evalfn,BestLabel), 4526 update_search_stats(Nodes,Time,M), 4527 record_search_stats(RClause,Nodes,Time,M), 4528 noset(stage,M), 4529 !. 4530find_clause(_,RClause,M):- 4531 M:'$aleph_search'(selected,selected(BestLabel,RClause,PCover,NCover)), 4532 retract(M:'$aleph_search'(openlist,_)), 4533 add_hyp(BestLabel,RClause,PCover,NCover,M), 4534 p_message('best clause'), 4535 pp_dclause(RClause,M), 4536 (setting(evalfn,Evalfn,M) -> true; Evalfn = coverage), 4537 show_stats(Evalfn,BestLabel), 4538 noset(stage,M), 4539 !. 4540 4541% find_theory(Search,M) where Search is rls only at present 4542find_theory(rls,Program,M):- 4543 !, 4544 retractall(M:'$aleph_search'(rls_move,_)), 4545 retractall(M:'$aleph_search'(rls_nodes,_)), 4546 retractall(M:'$aleph_search'(rls_parentstats,_)), 4547 retractall(M:'$aleph_search'(rls_selected,_)), 4548 setting(tries,MaxTries,M), 4549 MaxTries >= 1, 4550 store_values([caching,store_bottom],M), 4551 set(caching,false,M), 4552 set(store_bottom,true,M), 4553 M:'$aleph_global'(atoms,atoms(pos,PosSet)), 4554 M:'$aleph_global'(atoms,atoms(neg,NegSet)), 4555 interval_count(PosSet,P0), 4556 interval_count(NegSet,N0), 4557 setting(evalfn,Evalfn,M), 4558 complete_label(Evalfn,[0-[0,0,[],false]],[P0,N0,1],Label,M), 4559 asserta(M:'$aleph_search'(rls_selected,selected(Label,[0-[0,0,[],false]], 4560 PosSet,NegSet))), 4561 asserta(M:'$aleph_search'(rls_nodes,0)), 4562 asserta(M:'$aleph_search'(rls_restart,1)), 4563 get_search_settings(S,M), 4564 set(best,Label,M), 4565 stopwatch(Start), 4566 repeat, 4567 retractall(M:'$aleph_search'(rls_parentstats,_)), 4568 retractall(M:'$aleph_search'(rls_move,_)), 4569 retractall(M:'$aleph_search_seen'(_,_)), 4570 asserta(M:'$aleph_search'(rls_move,1)), 4571 asserta(M:'$aleph_search'(rls_parentstats,stats(Label,PosSet,NegSet))), 4572 M:'$aleph_search'(rls_restart,R), 4573 p1_message('restart'), p_message(R), 4574 find_theory1(rls,M), 4575 M:'$aleph_search'(current,current(_,Nodes0,_)), 4576 retract(M:'$aleph_search'(rls_nodes,Nodes1)), 4577 M:'$aleph_search'(selected,selected([P,N,L,F|T],RCl,PCov,NCov)), 4578 M:'$aleph_search'(rls_selected,selected([_,_,_,F1|_],_,_,_)), 4579 retract(M:'$aleph_search'(rls_restart,R)), 4580 R1 is R + 1, 4581 asserta(M:'$aleph_search'(rls_restart,R1)), 4582 Nodes2 is Nodes0 + Nodes1, 4583 asserta(M:'$aleph_search'(rls_nodes,Nodes2)), 4584 (F1 >= F -> true; 4585 retract(M:'$aleph_search'(rls_selected,selected([_,_,_,F1|_],_,_,_))), 4586 asserta(M:'$aleph_search'(rls_selected,selected([P,N,L,F|T],RCl,PCov,NCov))), 4587 set(best,[P,N,L,F|T],M)), 4588 setting(best,BestSoFar,M), 4589 (R1 > MaxTries;discontinue_search(S,BestSoFar/_,Nodes2,M)), 4590 !, 4591 stopwatch(Stop), 4592 Time is Stop - Start, 4593 M:'$aleph_search'(rls_nodes,Nodes), 4594 M:'$aleph_search'(rls_selected,selected(BestLabel,RBest,PCover,NCover)), 4595 add_hyp(BestLabel,RBest,PCover,NCover,M), 4596 p1_message('nodes constructed'), p_message(Nodes), 4597 p1_message('search time'), p_message(Time), 4598 p_message('best theory'), 4599 Program=RBest, 4600 pp_dclauses(RBest,M), 4601 show_stats(Evalfn,BestLabel), 4602 record_search_stats(RBest,Nodes,Time,M), 4603 noset(best,M), 4604 reinstate_values([caching,refine,refineop,store_bottom],M). 4605 4606find_theory1(_,M):- 4607 clean_up_reduce(M), 4608 M:'$aleph_global'(atoms,atoms(pos,Pos)), 4609 M:'$aleph_global'(atoms,atoms(neg,Neg)), 4610 asserta(M:'$aleph_search'(openlist,[])), 4611 asserta(M:'$aleph_search'(nextnode,none)), 4612 stopwatch(StartClock), 4613 get_search_settings(S,M), 4614 arg(4,S,_/Evalfn), 4615 interval_count(Pos,P), 4616 interval_count(Neg,N), 4617 complete_label(Evalfn,[0-[0,0,[],false]],[P,N,1],Label,M), 4618 asserta(M:'$aleph_search'(selected,selected(Label,[0-[0,0,[],false]],Pos,Neg))), 4619 get_theory_gain(S,0,Label/0,[0-[0,0,[],false]],Pos,Neg,P,N,NextBest,Last,M), 4620 asserta(M:'$aleph_search'(current,current(0,Last,NextBest))), 4621 get_nextbest(S,_,M), 4622 tsearch(S,Nodes,M), 4623 stopwatch(StopClock), 4624 Time is StopClock - StartClock, 4625 M:'$aleph_search'(selected,selected(BestLabel,RTheory,PCover,NCover)), 4626 retract(M:'$aleph_search'(openlist,_)), 4627 add_hyp(BestLabel,RTheory,PCover,NCover,M), 4628 p1_message('theories constructed'), p_message(Nodes), 4629 p1_message('search time'), p_message(Time), 4630 p_message('best theory'), 4631 pp_dclauses(RTheory,M), 4632 show_stats(Evalfn,BestLabel), 4633 update_search_stats(Nodes,Time,M), 4634 record_tsearch_stats(RTheory,Nodes,Time,M). 4635 4636estimate_error_rate(H,Del,N,E,R):- 4637 TargetProb is 1-exp(log(1-Del)/H), 4638 estimate_error(1.0/0.0,0.0/1.0,TargetProb,N,E,R). 4639 4640estimate_error(L/P1,U/P2,P,N,E,R):- 4641 M is (L+U)/2, 4642 binom_lte(N,M,E,P3), 4643 ADiff is abs(P - P3), 4644 (ADiff < 0.00001 -> 4645 R is M; 4646 (P3 > P -> 4647 estimate_error(L/P1,M/P3,P,N,E,R); 4648 estimate_error(M/P3,U/P2,P,N,E,R) 4649 ) 4650 ). 4651 4652 4653zap_rest(Lits,M):- 4654 retract(M:'$aleph_sat_litinfo'(LitNum,Depth,Atom,I,O,D)), 4655 (aleph_member1(LitNum,Lits) -> 4656 intersect1(Lits,D,D1,_), 4657 asserta(M:'$aleph_sat_litinfo'(LitNum,Depth,Atom,I,O,D1)); 4658 true), 4659 fail. 4660zap_rest(_,_M). 4661 4662sat_prelims(M):- 4663 clean_up_sat(M), 4664 clean_up_hypothesis(M), 4665 reset_counts(M), 4666 set_up_builtins(M). 4667 4668 4669reduce_prelims(L,P,N,M):- 4670 clean_up_reduce(M), 4671 check_posonly(M), 4672 check_auto_refine(M), 4673 (M:'$aleph_sat'(lastlit,L) -> true; 4674 L = 0, asserta(M:'$aleph_sat'(lastlit,L))), 4675 (M:'$aleph_sat'(botsize,_B) -> true; 4676 B = 0, asserta(M:'$aleph_sat'(botsize,B))), 4677 ((M:'$aleph_global'(lazy_evaluate,lazy_evaluate(_));setting(greedy,true,M))-> 4678 M:'$aleph_global'(atoms_left,atoms_left(pos,P)); 4679 M:'$aleph_global'(atoms,atoms(pos,P))), 4680 setting(evalfn,E,M), 4681 (E = posonly -> NType = rand; NType = neg), 4682 M:'$aleph_global'(atoms_left,atoms_left(NType,N)), 4683 asserta(M:'$aleph_search'(nextnode,none)). 4684 4685set_up_builtins(M):- 4686 gen_nlitnum(Cut,M), 4687 asserta(M:'$aleph_sat_litinfo'(Cut,0,'!',[],[],[])). 4688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4689% T H R E A D S 4690 4691% multi-threaded randomised local search 4692rls_search(1, MaxTries, Time, Nodes, Selected,M) :- 4693 !, 4694 retractall(M:'$aleph_search'(rls_restart,_)), 4695 retractall(M:'$aleph_search'(rls_nodes,_)), 4696 retractall(M:'$aleph_search'(rls_selected,_)), 4697 asserta(M:'$aleph_search'(rls_restart,1)), 4698 setting(evalfn,Evalfn,M), 4699 get_start_label(Evalfn,Label,M), 4700 set(best,Label,M), 4701 get_search_settings(S,M), 4702 arg(4,S,SearchStrat/_), 4703 (M:'$aleph_sat'(example,example(Num,Type)) -> 4704 M:example(Num,Type,Example), 4705 asserta(M:'$aleph_search'(rls_selected,selected(Label, 4706 (Example:-true),[Num-Num],[]))); 4707 asserta(M:'$aleph_search'(rls_selected,selected(Label, 4708 (false:-true),[],[]))) 4709 ), 4710 asserta(M:'$aleph_search'(rls_nodes,0)), 4711 stopwatch(Start), 4712 estimate_numbers(_,M), 4713 repeat, 4714 retract(M:'$aleph_search'(rls_restart,R)), 4715 R1 is R + 1, 4716 asserta(M:'$aleph_search'(rls_restart,R1)), 4717 rls_thread(R, SearchStrat, Label, Nodes0, selected(Best,RCl,PCov,NCov),M), 4718 Best = [_,_,_,F|_], 4719 M:'$aleph_search'(rls_selected,selected([_,_,_,F1|_],_,_,_)), 4720 (F1 >= F -> true; 4721 retract(M:'$aleph_search'(rls_selected,selected([_,_,_,F1|_], 4722 _,_,_))), 4723 asserta(M:'$aleph_search'(rls_selected,selected(Best,RCl, 4724 PCov,NCov))), 4725 set(best,Best,M) 4726 ), 4727 setting(best,BestSoFar,M), 4728 retract(M:'$aleph_search'(rls_nodes,Nodes1)), 4729 Nodes2 is Nodes0 + Nodes1, 4730 asserta(M:'$aleph_search'(rls_nodes,Nodes2)), 4731 (R1 > MaxTries; discontinue_search(S,BestSoFar/_,Nodes2,M)), 4732 !, 4733 stopwatch(Stop), 4734 Time is Stop - Start, 4735 retractall(M:'$aleph_search'(rls_restart,_)), 4736 retract(M:'$aleph_search'(rls_nodes,Nodes)), 4737 retract(M:'$aleph_search'(rls_selected,Selected)). 4738rls_search(N, MaxTries, Time, Nodes, Selected,M) :- 4739 retractall(M:'$aleph_search'(rls_restart,_)), 4740 retractall(M:'$aleph_search'(rls_nodes,_)), 4741 retractall(M:'$aleph_search'(rls_selected,_)), 4742 setting(evalfn,Evalfn,M), 4743 get_start_label(Evalfn,Label,M), 4744 set(best,Label,M), 4745 get_search_settings(S,M), 4746 arg(4,S,SearchStrat/_), 4747 (M:'$aleph_sat'(example,example(Num,Type)) -> 4748 M:example(Num,Type,Example), 4749 asserta(M:'$aleph_search'(rls_selected,selected(Label, 4750 (Example:-true),[Num-Num],[]))); 4751 asserta(M:'$aleph_search'(rls_selected,selected(Label, 4752 (false:-true),[],[]))) 4753 ), 4754 asserta(M:'$aleph_search'(rls_nodes,0)), 4755 estimate_numbers(_,M), % so all threads can use same estimates 4756 thread_self(Master), 4757 message_queue_create(Queue), 4758 create_worker_pool(N, Master, Queue, WorkerIds,M), 4759 forall(between(1, MaxTries, R), 4760 thread_send_message(Queue, rls_restart(R, SearchStrat, Label,M))), 4761 collect_results(rls_restart,MaxTries,[0,S],[Time|_],M), 4762 kill_worker_pool(Queue, WorkerIds), 4763 retractall(M:'$aleph_search'(rls_restart,_)), 4764 retract(M:'$aleph_search'(rls_nodes,Nodes)), 4765 retract(M:'$aleph_search'(rls_selected,Selected)). 4766 4767rls_thread(R, SearchStrat, Label, Nodes0, selected(Best,RCl,PCov,NCov),M) :- 4768 retractall(M:'$aleph_search'(best_refinement,_)), 4769 retractall(M:'$aleph_search'(last_refinement,_)), 4770 retractall(M:'$aleph_search'(rls_move,_)), 4771 retractall(M:'$aleph_search'(rls_parentstats,_)), 4772 retractall(M:'$aleph_search_seen'(_,_)), 4773 asserta(M:'$aleph_search'(rls_move,1)), 4774 asserta(M:'$aleph_search'(rls_parentstats,stats(Label,[],[]))), 4775 p1_message('restart'), p_message(R), 4776 find_clause(SearchStrat,M), 4777 M:'$aleph_search'(current,current(_,Nodes0,_)), 4778 M:'$aleph_search'(selected,selected(Best,RCl,PCov,NCov)), 4779 retractall(M:'$aleph_search'(best_refinement,_)), 4780 retractall(M:'$aleph_search'(last_refinement,_)), 4781 retractall(M:'$aleph_search'(rls_move,_)), 4782 retractall(M:'$aleph_search'(rls_parentstats,_)). 4783 4784 4785%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4786% T H R E A D S 4787 4788create_worker_pool(N, Master, Queue, WorkerIds,M) :- 4789 create_worker_pool(1, N, Master, Queue, WorkerIds,M). 4790 4791create_worker_pool(I, N, _, _, [],_M) :- 4792 I > N, !. 4793create_worker_pool(I, N, Master, Queue, [Id|T],M) :- 4794 atom_concat(worker_, I, Alias), 4795 thread_create(worker(Queue, Master,M), Id, [alias(Alias)]), 4796 I2 is I + 1, 4797 create_worker_pool(I2, N, Master, Queue, T,M). 4798 4799kill_worker_pool(Queue, WorkerIds) :- 4800 p_message('Killing workers'), 4801 forall(aleph_member(Worker, WorkerIds), 4802 kill_worker(Queue, Worker)), 4803 p_message('Waiting for workers'), 4804 forall(aleph_member(Worker, WorkerIds), 4805 thread_join(Worker, _)), 4806 message_queue_destroy(Queue), 4807 p_message('Ok, all done'). 4808 4809kill_worker(Queue, Worker) :- 4810 thread_send_message(Queue, all_done), 4811 thread_signal(Worker, throw(surplus_to_requirements)). 4812 4813worker(Queue, Master,M) :- 4814 thread_get_message(Queue, Message), 4815 work(Message, Master,M), 4816 worker(Queue, Master). 4817 4818work(rls_restart(R, SearchStrat, Label), Master,M) :- 4819 statistics(cputime, CPU0), 4820 rls_thread(R, SearchStrat, Label, Nodes, Selected,M), 4821 statistics(cputime, CPU1), 4822 CPU is CPU1 - CPU0, 4823 thread_send_message(Master, done(CPU, Nodes, Selected)). 4824work(all_done, _,_M) :- 4825 thread_exit(done). 4826 4827collect_results(rls_restart,NResults,In,Out,M):- 4828 collect_results(0,NResults,rls_restart,In,Out,M). 4829 4830collect_results(R0,MaxR,Flag,In,Out,M):- 4831 thread_get_message(Message), 4832 collect(Flag,Message,In,Out1,Done,M), 4833 R1 is R0 + 1, 4834 ( (Done == false, 4835 R1 < MaxR) 4836 -> collect_results(R1,MaxR,Flag,Out1,Out) 4837 ; Out = Out1 4838 ). 4839 4840collect(rls_restart,done(CPU, Nodes, selected(Best,RCl,PCov,NCov)),[T0,S], [T1,S],Done,M) :- 4841 T1 is CPU + T0, 4842 Best = [_,_,_,F|_], 4843 M:'$aleph_search'(rls_selected,selected([_,_,_,F1|_],_,_,_)), 4844 (F1 >= F -> true; 4845 retract(M:'$aleph_search'(rls_selected,selected( 4846 [_,_,_,F1|_],_,_,_))), 4847 asserta(M:'$aleph_search'(rls_selected,selected(Best, 4848 RCl,PCov,NCov))), 4849 set(best,Best,M)), 4850 setting(best,BestSoFar,M), 4851 retract(M:'$aleph_search'(rls_nodes,Nodes1)), 4852 Nodes2 is Nodes + Nodes1, 4853 asserta(M:'$aleph_search'(rls_nodes,Nodes2)), 4854 ( discontinue_search(S,BestSoFar/_,Nodes2,M) 4855 -> Done = true 4856 ; Done = false 4857 ). 4858 4859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4860% C O N T R O L
4868induce_clauses(M:Program):- 4869 setting(interactive,true,M), !, 4870 induce_incremental(M:Program). 4871induce_clauses(M:Program):- 4872 induce(M:Program).
4880induce(M:Program):- 4881 clean_up(M), 4882 set(greedy,true,M), 4883 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))), 4884 M:'$aleph_global'(atoms_left,atoms_left(pos,PosSet)), 4885 PosSet \= [], 4886 store(portray_search,M), 4887 set(portray_search,false,M), 4888 setting(samplesize,S,M), 4889 setting(abduce,Abduce,M), 4890 record_settings(M), 4891 stopwatch(StartClock), 4892 repeat, 4893 gen_sample(pos,S,M), 4894 4895 retractall(M:'$aleph_global'(besthyp,besthyp(_,_,_,_,_))), 4896 asserta(M:'$aleph_global'(besthyp,besthyp([-inf,0,1,-inf],0,(false),[],[]))), 4897 get_besthyp(Abduce,M), 4898 (setting(gcws,true,M) -> sphyp(M), addgcws(M); addhyp(M)), 4899 show_atoms_left(M), 4900 record_atoms_left(M), 4901 M:'$aleph_global'(atoms_left,atoms_left(pos,[])), 4902 stopwatch(StopClock), 4903 Time is StopClock - StartClock, 4904 copy_theory(Program,M), 4905 show(theory,M), 4906 record_theory(Time,M), 4907 noset(greedy,M), 4908 reinstate(portray_search,M), 4909 4910 p1_message('time taken'), p_message(Time), 4911 show_total_stats(M), 4912 record_total_stats(M), !. 4913 4914copy_theory(Program,M):- 4915 M:'$aleph_global'(rules,rules(L)), 4916 aleph_member(ClauseNum,L), 4917 copy_theory_inner(ClauseNum,Program,M), 4918 aleph_member(ClauseNum,L), 4919 M:'$aleph_global'(theory,theory(ClauseNum,_,_,_,_)). 4920 %copy_theory_eval(ClauseNum,Program,_). 4921copy_theory(_,_M). 4922 4923copy_theory_inner(ClauseNum,[SubProgram|TailP],M):- 4924 integer(ClauseNum), 4925 ClauseNum > 0,!, 4926 M:'$aleph_global'(theory,theory(ClauseNum,_,SubProgram,_,_)), 4927 ClauseNum1 is ClauseNum-1, 4928 copy_theory_inner(ClauseNum1,TailP,M). 4929 4930copy_theory_inner(0,[],_M). 4931 4932copy_modes(Modes,M):- 4933 findall(mode(Mode,D),M:'$aleph_global'(mode,mode(Mode,D)),Modes). 4934 4935copy_constraints(Constraints,M):- 4936 findall(Clause,M:'$aleph_good'(_,_,Clause),Constraints). 4937 4938copy_features(Features,M):- 4939 findall((Head:-Body),M:'$aleph_feature'(feature,feature(_,_,_,Head,Body)),Features). 4940 4941% ============= UNUSED ==================== 4942copy_theory_eval(0,_,Label,M):- 4943 M:'$aleph_global'(hypothesis,hypothesis(_,Clause,_,_)), !, 4944 label_create(Clause,Label,M), 4945 p_message('Rule 0'), 4946 pp_dclause(Clause,M), 4947 extract_count(pos,Label,PC), 4948 extract_count(neg,Label,NC), 4949 extract_length(Label,L), 4950 label_print_eval([PC,NC,L]), 4951 nl. 4952copy_theory_eval(ClauseNum,Program,_,M):- 4953 integer(ClauseNum), 4954 ClauseNum > 0, 4955 M:'$aleph_global'(theory,theory(ClauseNum,_,Clause,_,_)), 4956 !, 4957 copy_theory_eval_inner(Clause,Program). 4958copy_theory_eval(_,_,_,_M). 4959copy_theory_eval_inner((H:-true),Program):- 4960 !, 4961 copy_theory_eval_inner(H,Program). 4962copy_theory_eval_inner((H:-B),Program):- 4963 !, 4964 copy_term((H:-B),(Head:-Body)), 4965 numbervars((Head:-Body),0,_), 4966 add_lit_to_program(Body,Program). 4967copy_theory_eval_inner((Lit),Program):- 4968 !, 4969 copy_term(Lit,Lit1), 4970 numbervars(Lit1,0,_), 4971 add_lit_to_program(Lit1,Program). 4972 4973add_lit_to_program((Lit,Lits),[Lit|Program1]):- 4974 add_lit_to_program(Lits,Program1). 4975add_lit_to_program((Lit),[Lit]). 4976 4977% ============= /UNUSED ====================
4986% slow 4987induce_max(M:Program):- 4988 clean_up(M), 4989 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))), 4990 M:'$aleph_global'(atoms,atoms(pos,PosSet)), 4991 PosSet \= [], 4992 store(portray_search,M), 4993 set(portray_search,false,M), 4994 record_settings(M), 4995 stopwatch(StartClock), 4996 set(maxcover,true,M), 4997 aleph_induce_max(PosSet,M), 4998 stopwatch(StopClock), 4999 Time is StopClock - StartClock, 5000 copy_theory(Program,M), 5001 show(theory,M), 5002 record_theory(Time,M), 5003 noset(maxcover,M), 5004 reinstate(portray_search,M), 5005 reinstate(greedy,M), 5006 p1_message('time taken'), p_message(Time), 5007 show_total_stats(M), 5008 record_total_stats(M), !. 5009 5010aleph_induce_max([],_M). 5011aleph_induce_max([Start-Finish|Intervals],M):- 5012 asserta(M:'$aleph_local'(counter,Start)), 5013 induce_max1(Finish,M), 5014 aleph_induce_max(Intervals,M). 5015 5016induce_max1(Finish,M):- 5017 M:'$aleph_local'(counter,S), 5018 S =< Finish, !, 5019 (setting(resample,Resample,M) -> true; Resample = 1), 5020 repeat, 5021 retract(M:'$aleph_local'(counter,Start)), 5022 gen_sample(Resample,pos,Start,M), 5023 get_besthyp(false,M), 5024 update_coverset(pos,Start,M), 5025 Next is Start+1, 5026 assertz(M:'$aleph_local'(counter,Next)), 5027 Next > Finish, !, 5028 retract(M:'$aleph_local'(counter,Next)). 5029induce_max1(_,_).
5037induce_cover(M:Program):-
5038 clean_up(M),
5039 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))),
5040 M:'$aleph_global'(atoms,atoms(pos,PosSet)),
5041 PosSet \= [],
5042 store(portray_search,M),
5043 set(portray_search,false,M),
5044 setting(samplesize,S,M),
5045 setting(abduce,Abduce,M),
5046 record_settings(M),
5047 stopwatch(StartClock),
5048 repeat,
5049 gen_sample(pos,S,M),
5050 asserta(M:'$aleph_global'(besthyp,besthyp([-inf,0,1,-inf],0,
5051 (false),[],[]))),
5052 get_besthyp(Abduce,M),
5053 addhyp(M),
5054 M:'$aleph_global'(atoms_left,atoms_left(pos,[])),
5055 stopwatch(StopClock),
5056 Time is StopClock - StartClock,
5057 copy_theory(Program,M),
5058 show(theory,M),
5059 record_theory(Time,M),
5060 reinstate(portray_search,M),
5061 reinstate(greedy,M),
5062 p1_message('time taken'), p_message(Time),
5063 show_total_stats(M),
5064 record_total_stats(M), !.
not(E)
: E is added as a negative example/
5092induce_incremental(M:Program):-
5093 clean_up(M),
5094 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))),
5095 store_values([interactive,portray_search,proof_strategy,mode],M),
5096 set(portray_search,false,M),
5097 set(proof_strategy,sld,M),
5098 set(interactive,true,M),
5099 record_settings(M),
5100 stopwatch(StartClock),
5101 repeat,
5102 ask_example_web(E,M),
5103 ((E = end_of_file; E = none) -> true;
5104 once(record_example(check,pos,E,N,M)),
5105 retractall(M:'$aleph_global'(example_selected,
5106 example_selected(_,_))),
5107 asserta(M:'$aleph_global'(example_selected,
5108 example_selected(pos,N))),
5109 once(sat(N,M)),
5110 once(reduce(M:_)),
5111 once(process_hypothesis_web(M)),
5112 fail),
5113 !,
5114 stopwatch(StopClock),
5115 Time is StopClock - StartClock,
5116 copy_theory(Program0,M),
5117 reverse(Program0,Program),
5118 show(theory,M),
5119 show(pos,M),
5120 show(neg,M),
5121 show(aleph_false/0,M),
5122 show(prune/1,M),
5123 record_theory(Time,M),
5124 reinstate_values([interactive,portray_search,proof_strategy,mode],M),
5125 p1_message('time taken'), p_message(Time).
aleph_set(tries,...)
the number of moves is specified by aleph_set(moves,...)
annealing currently restricted to using a fixed temperature
the temperature is specified by aleph_set(temperature,...)
the fixed temp. makes it equivalent to the Metropolis alg.
WSAT requires a ``random-walk probability''
the walk probability is specified by aleph_set(walk,...)
a walk probability of 0 is equivalent to doing standard GSAT
theory accuracy is the evaluation function
/5151aleph_induce_theory(rls,M):- 5152 clean_up(M), 5153 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))), 5154 store(evalfn,M), 5155 set(evalfn,accuracy,M), 5156 record_settings(M), 5157 find_theory(rls,_,M), 5158 reinstate(evalfn,M), 5159 show_total_stats(M), 5160 record_total_stats(M), !. 5161aleph_induce_theory(_,_M). 5162 5163aleph_induce_theory(rls,Program,M):- 5164 clean_up(M), 5165 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))), 5166 store(evalfn,M), 5167 set(evalfn,accuracy,M), 5168 record_settings(M), 5169 find_theory(rls,Program,M), 5170 reinstate(evalfn,M), 5171 show_total_stats(M), 5172 record_total_stats(M), !. 5173 5174induce_theory(M:Program):- 5175 setting(search,Search,M), 5176 aleph_induce_theory(Search,Program,M).
5191induce_constraints(M:Constraints):-
5192 clean_up(M),
5193 retractall(M:'$aleph_global'(search_stats,search_stats(_,_))),
5194 store_values([portray_search,search,construct_bottom,good,goodfile],M),
5195 noset(goodfile,M),
5196 set(portray_search,false,M),
5197 set(construct_bottom,false,M),
5198 set(search,ic,M),
5199 set(good,true,M),
5200 sat(uspec,0,M),
5201 reduce(M:_),
5202 copy_constraints(Constraints,M),
5203 show(constraints,M),
5204 reinstate_values([portray_search,search,construct_bottom,good,goodfile],M),
5205 show_total_stats(M),
5206 record_total_stats(M), !.
5214induce_modes(M:Modes):-
5215 clean_up(M),
5216 store_values([typeoverlap],M),
5217 search_modes(M),
5218 reinstate_values([typeoverlap],M),
5219 copy_modes(Modes,M),
5220 show(modes,M),!.
aleph_set(max_features,F)
the features are constructed by doing the following:
while (number of features =< F) do:
/
5233induce_features(M:Features):-
5234 clean_up(M),
5235 store_values([good,check_good,updateback,construct_features,samplesize,greedy,explore,lazy_on_contradiction],M),
5236 set(good,true,M),
5237 set(check_good,true,M),
5238 set(updateback,false,M),
5239 set(construct_features,true,M),
5240 set(lazy_on_contradiction,true,M),
5241 (setting(feature_construction,exhaustive,M) -> set(explore,true,M);
5242 true),
5243 setting(max_features,FMax,M),
5244 record_settings(M),
5245 stopwatch(StartClock),
5246 M:'$aleph_global'(atoms_left,atoms_left(pos,AtomsLeft)),
5247 repeat,
5248 gen_sample(pos,0,M),
5249 retractall(M:'$aleph_global'(besthyp,besthyp(_,_,_,_,_))),
5250 asserta(M:'$aleph_global'(besthyp,besthyp([-inf,0,1,-inf],0,(false),[],[]))),
5251 get_besthyp(false,M),
5252 addhyp(M),
5253 show_atoms_left(M),
5254 record_atoms_left(M),
5255 ((M:'$aleph_search'(last_good,LastGood), LastGood >= FMax);
5256 M:'$aleph_global'(atoms_left,atoms_left(pos,[]))), !,
5257 gen_features(M),
5258 stopwatch(StopClock),
5259 Time is StopClock - StartClock,
5260 copy_features(Features,M),
5261 show(features,M),
5262 record_features(Time,M),
5263 retract(M:'$aleph_global'(atoms_left,atoms_left(pos,_))),
5264 assertz(M:'$aleph_global'(atoms_left,atoms_left(pos,AtomsLeft))),
5265 reinstate_values([good,check_good,updateback,construct_features,samplesize,greedy,explore,lazy_on_contradiction],M), !.
aleph_set(tree_type,...)
In addition, the following parameters are relevant
aleph_set(classes,ListofClasses)
: when tree_type is classification or
or class_probabilityaleph_set(prune_tree,Flag)
: for pruning rules from a treealeph_set(confidence,C)
: for pruning of rules as described by
J R Quinlan in the C4.5 bookaleph_set(lookahead,L)
: lookahead for the refinement operator to avoid
local zero-gain literalsaleph_set(dependent,A)
: argument of the dependent variable in the examplesThe basic procedure attempts to construct a tree to predict the dependent variable in the examples. Note that the mode declarations must specify the variable as an output argument. Paths from root to leaf constitute clauses. Tree-construction is viewed as a refinement operation: any leaf can currently be refined by extending the corresponding clause. The extension is done using Aleph's automatic refinement operator that extends clauses within the mode language. A lookahead option allows additions to include several literals. Classification problems currently use entropy gain to measure worth of additions. Regression and model trees use reduction in standard deviation to measure worth of additions. This is not quite correct for the latter. Pruning for classification is done on the final set of clauses from the tree. The technique used here is the reduced-error pruning method. For classification trees, this is identical to the one proposed by Quinlan in C4.5: Programs for Machine Learning, Morgan Kauffmann. For regression and model trees, this is done by using a pessimistic estimate of the sample standard deviation. This assumes normality of observed values in a leaf. This method and others have been studied by L. Torgo in "A Comparative Study of Reliable Error Estimators for Pruning Regression Trees" Following work by F Provost and P Domingos, pruning is not employed for class probability prediction. Currently no pruning is performed for model trees. /
5309induce_tree(M:Program):- 5310 clean_up(M), 5311 setting(tree_type,Type,M), 5312 store_values([refine],M), 5313 set(refine,auto,M), 5314 setting(mingain,MinGain,M), 5315 (MinGain =< 0.0 -> 5316 err_message('inappropriate setting for mingain'), 5317 fail; 5318 true 5319 ), 5320 record_settings(M), 5321 stopwatch(StartClock), 5322 construct_tree(Type,M), 5323 stopwatch(StopClock), 5324 Time is StopClock - StartClock, 5325 copy_theory(Program0,M), 5326 reverse(Program0,Program), 5327 show(theory,M), 5328 record_theory(Time,M), 5329 reinstate_values([refine],M), !. 5330% utilities for the induce predicates 5331 5332 5333% randomly pick a positive example and construct bottom clause 5334% example is from those uncovered by current theory 5335% and whose bottom clause has not been stored away previously 5336% makes at most 100 attempts to find such an example 5337rsat(M):- 5338 M:'$aleph_global'(atoms_left,atoms_left(pos,PosSet)), 5339 PosSet \= [], 5340 store(resample,M), 5341 set(resample,1,M), 5342 rsat(100,M), 5343 reinstate(resample,M). 5344 5345rsat(0,_M):- !. 5346rsat(N,M):- 5347 gen_sample(pos,1,M), 5348 M:'$aleph_global'(example_selected,example_selected(pos,Num)), 5349 (\+(M:'$aleph_sat'(stored,stored(Num,pos,_))) -> 5350 !, 5351 retract(M:'$aleph_global'(example_selected, 5352 example_selected(pos,Num))), 5353 sat(pos,Num,M); 5354 N1 is N - 1, 5355 rsat(N1,M)). 5356 5357get_besthyp(AbduceFlag,M):- 5358 retract(M:'$aleph_global'(example_selected, 5359 example_selected(pos,Num))), 5360 reset_best_label(M), % set-up target to beat 5361 sat(Num,M), 5362 reduce(M:_), 5363 update_besthyp(Num,M), 5364 (AbduceFlag = true -> 5365 M:example(Num,pos,Atom), 5366 abgen(Atom,AbGen,M), 5367 once(retract(M:'$aleph_global'(hypothesis, 5368 hypothesis(Label,_,PCover,NCover)))), 5369 assert(M:'$aleph_global'(hypothesis, 5370 hypothesis(Label,AbGen,PCover,NCover))), 5371 update_besthyp(Num,M); 5372 true), 5373 fail. 5374get_besthyp(_,M):- 5375 retract(M:'$aleph_global'(besthyp,besthyp(L,Num,H,PC,NC))), 5376 H \= false, !, 5377 ((setting(samplesize,S,M),S>1)-> 5378 setting(nodes,Nodes,M), 5379 show_clause(sample,L,H,Nodes,M), 5380 record_clause(sample,L,H,Nodes,M); 5381 true), 5382 add_hyp(L,H,PC,NC,M), 5383 asserta(M:'$aleph_global'(example_selected, 5384 example_selected(pos,Num))), !. 5385get_besthyp(_,_M). 5386 5387 5388reset_best_label(M):- 5389 M:'$aleph_global'(besthyp,besthyp(Label1,_,Clause,P,N)), 5390 M:'$aleph_search'(best_label,Label/_), 5391 Label = [_,_,L,GainE|_], 5392 Label1 = [_,_,L1,Gain1E|_], 5393 % Gain > Gain1, !, 5394 arithmetic_expression_value(GainE,Gain), 5395 arithmetic_expression_value(Gain1E,Gain1), 5396 ((Gain1 > Gain);(Gain1 =:= Gain, L1 < L)), !, 5397 retract(M:'$aleph_search'(best_label,Label/_)), 5398 asserta(M:'$aleph_search'(best_label,Label1/0)), 5399 retractall(M:'$aleph_search'(selected,_)), 5400 asserta(M:'$aleph_search'(selected,selected(Label1,Clause,P,N))). 5401reset_best_label(_M). 5402 5403 5404update_besthyp(Num,M):- 5405 M:'$aleph_global'(hypothesis,hypothesis(Label,H,PCover,NCover)), 5406 M:'$aleph_global'(besthyp,besthyp(Label1,_,_,_,_)), 5407 Label = [_,_,L,GainE|_], 5408 Label1 = [_,_,L1,Gain1E|_], 5409 % Gain > Gain1, !, 5410 arithmetic_expression_value(GainE,Gain), 5411 arithmetic_expression_value(Gain1E,Gain1), 5412 ((Gain > Gain1);(Gain =:= Gain1, L < L1)), !, 5413 retract(M:'$aleph_global'(besthyp,besthyp(Label1,_,_,_,_))), 5414 assertz(M:'$aleph_global'(besthyp,besthyp(Label,Num,H,PCover,NCover))). 5415update_besthyp(_,_M). 5416 5417 5418% generate a new feature from a good clause 5419gen_features(M):- 5420 aleph_abolish('$aleph_feature'/2,M), 5421 (setting(dependent,PredictArg,M) -> true; PredictArg is 0), 5422 (setting(minscore,FMin,M) -> true; FMin = -inf), 5423 M:'$aleph_good'(_,Label,Clause), 5424 Label = [_,_,_,FE|_], 5425 arithmetic_expression_value(FE,F), 5426 F >= FMin, 5427 split_clause(Clause,Head,Body), 5428 Body \= true, 5429 functor(Head,Name,Arity), 5430 functor(Template,Name,Arity), 5431 copy_iargs(Arity,Head,Template,PredictArg), 5432 get_feature_class(PredictArg,Head,Body,Class,M), 5433 gen_feature((Template:-Body),Label,Class,M), 5434 fail. 5435gen_features(M):- 5436 (setting(dependent,PredictArg,M) -> true; PredictArg is 0), 5437 setting(good,true,M), 5438 setting(goodfile,File,M), 5439 aleph_open(File,read,Stream), 5440 (setting(minscore,FMin,M) -> true; FMin = -inf), 5441 repeat, 5442 read(Stream,Fact), 5443 (Fact = M:'$aleph_good'(_,Label,Clause) -> 5444 Label = [_,_,_,FE|_], 5445 arithmetic_expression_value(FE,F), 5446 F >= FMin, 5447 split_clause(Clause,Head,Body), 5448 Body \= true, 5449 functor(Head,Name,Arity), 5450 functor(Template,Name,Arity), 5451 copy_iargs(Arity,Head,Template,PredictArg), 5452 get_feature_class(PredictArg,Head,Body,Class,M), 5453 gen_feature((Template:-Body),Label,Class,M), 5454 fail; 5455 close(Stream), ! 5456 ). 5457gen_features(_M). 5458 5459get_feature_class(Argno,Head,Body,Class,M):- 5460 has_class(Argno,Head,Body,Class,M), !. 5461get_feature_class(_,_,_,_,_M). 5462 5463has_class(Argno,Head,_,Class,_M):- 5464 arg(Argno,Head,Class), 5465 ground(Class), !. 5466has_class(Argno,Head,Body,Class,M):- 5467 arg(Argno,Head,DepVar), 5468 in((DepVar=Class),Body,M), 5469 ground(Class), !. 5470 5471ask_example(E,M):- 5472 (M:'$aleph_global'(example_selected,example_selected(pos,N)) -> 5473 M:example(N,pos,E1); 5474 E1 = none), 5475 !, 5476 show_options(example_selection), 5477 tab(4), 5478 write('Response '), p1_message(default:E1), write('?'), nl, 5479 read(Response), 5480 (Response = ok -> E = E1; E = Response). 5481 5482ask_example_web(E,M):- 5483 (M:'$aleph_global'(example_selected,example_selected(pos,N)) -> 5484 M:example(N,pos,E1); 5485 E1 = none), 5486 !, 5487 show_options_web(example_selection), 5488 tab(4), 5489 write('Response '), p1_message(default:E1), write('?'), nl, 5490 read(Response), 5491 (Response = ok -> E = E1; E = Response). 5492 5493process_hypothesis(M):- 5494 show(hypothesis,M), 5495 repeat, 5496 show_options(hypothesis_selection), 5497 tab(4), 5498 write('Response?'), nl, 5499 read(Response), 5500 process_hypothesis(Response,M), 5501 (Response = end_of_file; Response = none), !. 5502 5503process_hypothesis_web(M):- 5504 show(hypothesis,M), 5505 repeat, 5506 show_options_web(hypothesis_selection), 5507 tab(4), 5508 write('Response?'), nl, 5509 read(Response), 5510 process_hypothesis(Response,M), 5511 (Response = end_of_file; Response = none), !. 5512 5513process_hypothesis(end_of_file,_M):- 5514 nl, nl, !. 5515process_hypothesis(none,_M):- 5516 nl, nl, !. 5517process_hypothesis(ok,M):- 5518 !, 5519 update_theory(_,M), 5520 nl, p_message('added new clause'). 5521process_hypothesis(prune,M):- 5522 !, 5523 retract(M:'$aleph_global'(hypothesis,hypothesis(_,H,_,_))), 5524 Prune = ( 5525 hypothesis(Head,Body,_,M), 5526 goals_to_list(Body,BodyL), 5527 clause_to_list(H,HL), 5528 aleph_subsumes(HL,[Head|BodyL])), 5529 assertz(M:(prune(H):- Prune)), 5530 nl, p_message('added new prune statement'). 5531process_hypothesis(overgeneral,M):- 5532 !, 5533 retract(M:'$aleph_global'(hypothesis,hypothesis(_,H,_,_))), 5534 Constraint = ( 5535 hypothesis(Head,Body,_,M), 5536 goals_to_list(Body,BodyL), 5537 clause_to_list(H,HL), 5538 aleph_subsumes([Head|BodyL],HL)), 5539 assertz(M:(aleph_false:- Constraint)), 5540 nl, p_message('added new constraint'). 5541process_hypothesis(overgeneral because not(E),M):- 5542 !, 5543 record_example(check,neg,E,_,M), 5544 nl, p_message('added new negative example'). 5545process_hypothesis(overspecific,M):- 5546 !, 5547 retract(M:'$aleph_global'(hypothesis,hypothesis(_,H,_,_))), 5548 (retract(M:'$aleph_global'(example_selected,example_selected(_,_)))-> 5549 true; 5550 true), 5551 record_example(check,pos,H,N,M), 5552 asserta(M:'$aleph_global'(example_selected,example_selected(pos,N))), 5553 nl, p_message('added new positive example'). 5554process_hypothesis(overspecific because E,M):- 5555 !, 5556 retract(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 5557 (retract(M:'$aleph_global'(example_selected,example_selected(_,_)))-> 5558 true; 5559 true), 5560 record_example(check,pos,E,N,M), 5561 asserta(M:'$aleph_global'(example_selected,example_selected(pos,N))), 5562 nl, p_message('added new positive example'). 5563process_hypothesis(AlephCommand,M):- 5564 M:AlephCommand. 5565 5566show_options(example_selection):- 5567 nl, 5568 tab(4), 5569 write('Options:'), nl, 5570 tab(8), 5571 write('-> "ok." to accept default example'), nl, 5572 tab(8), 5573 write('-> Enter an example'), nl, 5574 tab(8), 5575 write('-> ctrl-D or "none." to end'), nl, nl. 5576show_options(hypothesis_selection):- 5577 nl, 5578 tab(4), 5579 write('Options:'), nl, 5580 tab(8), 5581 write('-> "ok." to accept clause'), nl, 5582 tab(8), 5583 write('-> "prune." to prune clause and its refinements from the search'), nl, 5584 tab(8), 5585 write('-> "overgeneral." to add clause as a constraint'), nl, 5586 tab(8), 5587 write('-> "overgeneral because not(E)." to add E as a negative example'), nl, 5588 tab(8), 5589 write('-> "overspecific." to add clause as a positive example'), nl, 5590 tab(8), 5591 write('-> "overspecific because E." to add E as a positive example'), nl, 5592 tab(8), 5593 write('-> any Aleph command'), nl, 5594 tab(8), 5595 write('-> "ctrl-D or "none." to end'), nl, nl. 5596 5597show_options_web(example_selection):- 5598 nl, 5599 tab(4), 5600 write('Options:'), nl, 5601 tab(8), 5602 write('-> "ok." to accept default example'), nl, 5603 tab(8), 5604 write('-> Enter an example'), nl, 5605 tab(8), 5606 write('-> "none." to end'), nl, nl. 5607show_options_web(hypothesis_selection):- 5608 nl, 5609 tab(4), 5610 write('Options:'), nl, 5611 tab(8), 5612 write('-> "ok." to accept clause'), nl, 5613 tab(8), 5614 write('-> "prune." to prune clause and its refinements from the search'), nl, 5615 tab(8), 5616 write('-> "overgeneral." to add clause as a constraint'), nl, 5617 tab(8), 5618 write('-> "overgeneral because not(E)." to add E as a negative example'), nl, 5619 tab(8), 5620 write('-> "overspecific." to add clause as a positive example'), nl, 5621 tab(8), 5622 write('-> "overspecific because E." to add E as a positive example'), nl, 5623 tab(8), 5624 write('-> any Aleph command'), nl, 5625 tab(8), 5626 write('-> "none." to end'), nl, nl. 5627 5628 5629get_performance(M):- 5630 setting(evalfn,Evalfn,M), 5631 (Evalfn = sd; Evalfn = mse), !. 5632get_performance(M):- 5633 findall(Example,M:example(_,pos,Example),Pos), 5634 findall(Example,M:example(_,neg,Example),Neg), 5635 (test_ex(Pos,noshow,Tp,TotPos,M)-> 5636 Fn is TotPos - Tp; 5637 TotPos = 0, Tp = 0, Fn = 0), 5638 (test_ex(Neg,noshow,Fp,TotNeg,M)-> 5639 Tn is TotNeg - Fp; 5640 TotNeg = 0, Tn = 0, Fp = 0), 5641 TotPos + TotNeg > 0, 5642 p_message('Training set performance'), 5643 write_cmatrix([Tp,Fp,Fn,Tn]), 5644 p1_message('Training set summary'), p_message([Tp,Fp,Fn,Tn]), 5645 fail. 5646get_performance(M):- 5647 (setting(test_pos,PFile,M) -> 5648 test(PFile,noshow,Tp,TotPos,M), 5649 Fn is TotPos - Tp; 5650 TotPos = 0, Tp = 0, Fn = 0), 5651 (setting(test_neg,NFile,M) -> 5652 test(NFile,noshow,Fp,TotNeg,M), 5653 Tn is TotNeg - Fp; 5654 TotNeg = 0, Tn = 0, Fp = 0), 5655 TotPos + TotNeg > 0, 5656 p_message('Test set performance'), 5657 write_cmatrix([Tp,Fp,Fn,Tn]), 5658 p1_message('Test set summary'), p_message([Tp,Fp,Fn,Tn]), 5659 fail. 5660get_performance(_M). 5661 5662write_cmatrix([Tp,Fp,Fn,Tn]):- 5663 P is Tp + Fn, N is Fp + Tn, 5664 PP is Tp + Fp, PN is Fn + Tn, 5665 Total is PP + PN, 5666 (Total = 0 -> Accuracy is 0.5; Accuracy is (Tp + Tn)/Total), 5667 find_max_width([Tp,Fp,Fn,Tn,P,N,PP,PN,Total],0,W1), 5668 W is W1 + 2, 5669 tab(5), write(' '), tab(W), write('Actual'), nl, 5670 tab(5), write(' '), write_entry(W,'+'), tab(6), write_entry(W,'-'), nl, 5671 tab(5), write('+'), 5672 write_entry(W,Tp), tab(6), write_entry(W,Fp), tab(6), write_entry(W,PP), nl, 5673 write('Pred '), nl, 5674 tab(5), write('-'), 5675 write_entry(W,Fn), tab(6), write_entry(W,Tn), tab(6), write_entry(W,PN), nl, nl, 5676 tab(5), write(' '), write_entry(W,P), tab(6), write_entry(W,N), 5677 tab(6), write_entry(W,Total), nl, nl, 5678 write('Accuracy = '), write(Accuracy), nl. 5679 5680 5681find_max_width([],W,W). 5682find_max_width([V|T],W1,W):- 5683 name(V,VList), 5684 length(VList,VL), 5685 (VL > W1 -> find_max_width(T,VL,W); 5686 find_max_width(T,W1,W)). 5687 5688write_entry(W,V):- 5689 name(V,VList), 5690 length(VList,VL), 5691 Y is integer((W-VL)/2), 5692 tab(Y), write(V), tab(Y). 5693 5694%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5695% A B D U C T I O N 5696 5697% Generalisation of an abductive explanation for a fact. 5698% The basic procedure is a simplified variant of S. Moyle's Alecto 5699% program. Alecto is described in some detail in S. Moyle, 5700% "Using Theory Completion to Learn a Navigation Control Program", 5701% Proceedings of the Twelfth International Conference on ILP (ILP2002), 5702% S. Matwin and C.A. Sammut (Eds), LNAI 2583, pp 182-197, 5703% 2003. 5704% Alecto does the following: for each positive example, an 5705% abductive explanation is obtained. This explanation is set of 5706% ground atoms. The union of abductive explanations from all 5707% positive examples is formed (this is also a set of ground atoms). 5708% These are then generalised to give the final theory. The 5709% ground atoms in an abductive explanation are obtained using 5710% Yamamoto's SOLD resolution or SOLDR (Skip Ordered Linear resolution for 5711% Definite clauses). 5712% One complication with abductive learning is this: for a given 5713% positive example to be provable, we require all the ground atoms 5714% in its abductive explanation to be true. Correctly therefore, 5715% we would need to assert the abductive explanation before 5716% checking the utility of any hypothesis. To avoid unnecessary 5717% asserts and retracts, the "pclause" trick is used here (see 5718% record_testclause/0). 5719 5720abgen(Fact,M):- 5721 abgen(Fact,_,M). 5722 5723abgen(Fact,AbGen,M):- 5724 retractall(M:'$aleph_search'(abgenhyp,hypothesis(_,_,_,_))), 5725 Minf is -inf, 5726 asserta(M:'$aleph_search'(abgenhyp, 5727 hypothesis([Minf,0,1,Minf],[false],[],[]))), 5728 setting(max_abducibles,Max,M), 5729 abgen(Fact,Max,AbGen,M), 5730 M:'$aleph_global'(hypothesis,hypothesis(Label,_,PCover,NCover)), 5731 Label = [_,_,LE,GainE|_], 5732 arithmetic_expression_value(LE,L), 5733 arithmetic_expression_value(GainE,Gain), 5734 M:'$aleph_search'(abgenhyp,hypothesis(Label1,_,_,_)), 5735 Label1 = [_,_,L1E,Gain1E|_], 5736 arithmetic_expression_value(L1E,L1), 5737 arithmetic_expression_value(Gain1E,Gain1), 5738 once(((Gain > Gain1); (Gain =:= Gain1, L < L1))), 5739 once(retract(M:'$aleph_search'(abgenhyp,hypothesis(_,_,_,_)))), 5740 asserta(M:'$aleph_search'(abgenhyp, 5741 hypothesis(Label,AbGen,PCover,NCover))), 5742 fail. 5743abgen(_,AbGen,M):- 5744 retractall(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 5745 M:'$aleph_search'(abgenhyp,hypothesis(Label,AbGen,PCover,NCover)), 5746 asserta(M:'$aleph_global'(hypothesis, 5747 hypothesis(Label,AbGen,PCover,NCover))). 5748 5749abgen(Fact,Max,AbGen,M):- 5750 sold_prove(Fact,AbAtoms,M), 5751 ground(AbAtoms), 5752 length(AbAtoms,N), 5753 N =< Max, 5754 prolog_type(Prolog), 5755 (Prolog = yap -> 5756 store_abduced_atoms(AbAtoms,AssertRefs,M); 5757 store_abduced_atoms(AbAtoms,M)), 5758 store(proof_strategy,M), 5759 set(proof_strategy,sld,M), 5760 gen_abduced_atoms(AbAtoms,AbGen,M), 5761 reinstate(proof_strategy,M), 5762 (Prolog = yap -> 5763 erase_refs(AssertRefs); 5764 remove_abduced_atoms(AbAtoms,M)). 5765 5766gen_abduced_atoms([],[],_M). 5767gen_abduced_atoms([AbAtom|AbAtoms],[AbGen|AbGens],M):- 5768 functor(AbAtom,Name,Arity), 5769 add_determinations(Name/Arity,true,M), 5770 sat(AbAtom,M), 5771 reduce(M:_), 5772 M:'$aleph_global'(hypothesis,hypothesis(_,AbGen,_,_)), 5773 remove_explained(AbAtoms,AbGen,AbAtoms1,M), 5774 gen_abduced_atoms(AbAtoms1,AbGens,M). 5775 5776remove_explained([],_,[],_M). 5777remove_explained([AbAtom|AbAtoms],(Head:-Body),Rest,M):- 5778 \+((\+ M:((AbAtom = Head), Body))), !, 5779 remove_explained(AbAtoms,(Head:-Body),Rest,M). 5780remove_explained([AbAtom|AbAtoms],(Head:-Body),[AbAtom|Rest],M):- 5781 remove_explained(AbAtoms,(Head:-Body),Rest,M). 5782 5783store_abduced_atoms([],[],_M). 5784store_abduced_atoms([AbAtom|AbAtoms],[DbRef|DbRefs],M):- 5785 assertz(M:'$aleph_search'(abduced,pclause(AbAtom,true)),DbRef), 5786 store_abduced_atoms(AbAtoms,DbRefs,M). 5787 5788store_abduced_atoms([],_M). 5789store_abduced_atoms([AbAtom|AbAtoms],M):- 5790 assertz(M:'$aleph_search'(abduced,pclause(AbAtom,true))), 5791 store_abduced_atoms(AbAtoms,M). 5792 5793remove_abduced_atoms([],_M). 5794remove_abduced_atoms([AbAtom|AbAtoms],M):- 5795 retract(M:'$aleph_search'(abduced,pclause(AbAtom,true))), 5796 remove_abduced_atoms(AbAtoms,M). 5797 5798 5799% sold_prove(+G,-A) 5800% Where G is an input goal (comma separated conjunction of atoms) 5801% and A is a list of atoms (containing the abductive explanation). 5802% This procedure is due to S.Moyle 5803sold_prove(Goal,SkippedGoals,M):- 5804 soldnf_solve(Goal,Skipped,M), 5805 sort(Skipped,SkippedGoals). 5806 5807soldnf_solve(Goal,Skipped,M):- 5808 soldnf_solve(Goal,true,[],Skipped,M). 5809 5810soldnf_solve((Goal,Goals),Status,SkippedSoFar,Skipped,M):- 5811 !, 5812 soldnf_solve(Goal,Status1,SkippedSoFar,Skipped1,M), 5813 soldnf_solve(Goals,Status2,Skipped1,Skipped,M), 5814 conj_status(Status1,Status2,Status). 5815soldnf_solve(not(Goal),true,SkippedSoFar,Skipped,M):- 5816 soldnf_solve(Goal,false,SkippedSoFar,Skipped,M). 5817soldnf_solve(not(Goal),false,SkippedSoFar,Skipped,M):- 5818 !, 5819 soldnf_solve(Goal,true,SkippedSoFar,Skipped,M). 5820soldnf_solve(Goal,Status,SkippedSoFar,SkippedSoFar,M):- 5821 soldnf_builtin(Goal,M), !, 5822 soldnfcall(Goal,Status,M). 5823soldnf_solve(Goal,Status,SkippedSoFar,Skipped,M):- 5824 soldnf_clause(Goal,Body,M), 5825 soldnf_solve(Body,Status,SkippedSoFar,Skipped,M). 5826soldnf_solve(Goal,true,SkippedSoFar,[Goal|SkippedSoFar],M):- 5827 skippable(Goal,M). 5828 5829soldnf_clause(Goal,_Body,M):-soldnf_builtin(Goal,M),!,fail. 5830soldnf_clause(Goal,Body,M):- 5831 clause(M:,Body). 5832 5833soldnf_builtin(not(_Goal),_M):-!,fail. 5834soldnf_builtin(A,M):-predicate_property(M:A,built_in). 5835 5836soldnfcall(Goal,true,M):- 5837 M:Goal, !. 5838soldnfcall(_,false,_M). 5839 5840conj_status(true,true,true):- !. 5841conj_status(_,_,false). 5842 5843skippable(Pred,M):- 5844 functor(Pred,Name,Arity), 5845 M:'$aleph_global'(abducible,abducible(Name/Arity)). 5846 5847%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5848% L A Z Y E V A L U A T I O N 5849 5850 5851% lazy_evaluate_theory(+Clauses,+Lazy,+Pos,+Neg,-Theory) 5852% evaluate lazy preds in a set of clauses 5853% untested 5854lazy_evaluate_theory([],_,_,_,[],_M). 5855lazy_evaluate_theory([Refine|T],LazyPreds,Pos,Neg,[Refine1|T1],M):- 5856 Refine = A-[B,C,D,Clause], 5857 lazy_evaluate_refinement(D,Clause,LazyPreds,Pos,Neg,D1,Clause1,M), 5858 Refine1 = A-[B,C,D1,Clause1], 5859 lazy_evaluate_theory(T,LazyPreds,Pos,Neg,T1,M). 5860 5861% lazy evaluation of literals in a refinement operation 5862lazy_evaluate_refinement([],Refine,Lazy,Pos,Neg,[],NewRefine,M):- 5863 clause_to_list(Refine,Lits), 5864 lazy_evaluate_refinement(Lits,Lazy,[],Pos,Neg,Lits1,M), 5865 list_to_clause(Lits1,NewRefine), !. 5866lazy_evaluate_refinement(Lits,_,Lazy,Pos,Neg,Lits1,NewRefine,M):- 5867 Lits \= [], 5868 lazy_evaluate_refinement(Lits,Lazy,[],Pos,Neg,Lits1,M), 5869 get_pclause(Lits1,[],NewRefine,_,_,_,M), !. 5870lazy_evaluate_refinement(Lits,Refine,_,_,_,Lits,Refine,_M). 5871 5872 5873lazy_evaluate_refinement([],_,L,_,_,L,_M):- !. 5874lazy_evaluate_refinement([Lit|Lits],LazyPreds,Path,PosCover,NegCover,Refine,M):- 5875 lazy_evaluate([Lit],LazyPreds,Path,PosCover,NegCover,[Lit1],M), 5876 aleph_append([Lit1],Path,Path1), !, 5877 lazy_evaluate_refinement(Lits,LazyPreds,Path1,PosCover,NegCover,Refine,M). 5878 5879 5880% lazy evaluation of specified literals 5881% all #'d arguments of these literals are evaluated at reduction-time 5882% From Version 5 (dated Sat Nov 29 13:02:36 GMT 2003), collects both 5883% input and output args (previously only collected input args) 5884lazy_evaluate(Lits,[],_,_,_,Lits,_M):- !. 5885lazy_evaluate([],_,_,_,_,[],_M):- !. 5886lazy_evaluate([LitNum|LitNums],LazyPreds,Path,PosCover,NegCover,Lits,M):- 5887 (integer(LitNum) -> 5888 BottomExists = true, 5889 M:'$aleph_sat_litinfo'(LitNum,Depth,Atom,I,O,D), 5890 functor(Atom,Name,Arity), 5891 aleph_member1(Name/Arity,LazyPreds), !, 5892 get_pclause([LitNum|Path],[],(Lit:-(Goals)),_,_,_,M); 5893 BottomExists = false, 5894 Atom = LitNum, 5895 Depth = 0, 5896 functor(Atom,Name,Arity), 5897 aleph_member1(Name/Arity,LazyPreds), !, 5898 split_args(LitNum,_,I,O,C,M), 5899 D = [], 5900 list_to_clause([LitNum|Path],(Lit:-(Goals)))), 5901 goals_to_clause(Goals,Clause), 5902 lazy_prove(pos,Lit,Clause,PosCover,M), 5903 (M:'$aleph_global'(positive_only,positive_only(Name/Arity))-> 5904 true; 5905 lazy_prove_negs(Lit,Clause,NegCover,M)), 5906 functor(LazyLiteral,Name,Arity), 5907 collect_args(I,LazyLiteral,M), 5908 collect_args(O,LazyLiteral,M), 5909 lazy_evaluate1(BottomExists,Atom,Depth,I,O,C,D,LazyLiteral,NewLits,M), 5910 retractall(M:'$aleph_local'(lazy_evaluate,_)), 5911 lazy_evaluate(LitNums,LazyPreds,Path,PosCover,NegCover,NewLits1,M), 5912 update_list(NewLits1,NewLits,Lits). 5913lazy_evaluate([LitNum|LitNums],LazyPreds,Path,PosCover,NegCover,[LitNum|Lits],M):- 5914 lazy_evaluate(LitNums,LazyPreds,Path,PosCover,NegCover,Lits,M). 5915 5916lazy_prove_negs(Lit,Clause,_,M):- 5917 M:'$aleph_global'(lazy_negs,set(lazy_negs,true)), !, 5918 M:'$aleph_global'(atoms,atoms(neg,NegCover)), 5919 lazy_prove(neg,Lit,Clause,NegCover,M). 5920lazy_prove_negs(Lit,Clause,NegCover,M):- 5921 lazy_prove(neg,Lit,Clause,NegCover,M). 5922 5923collect_args([],_,_M). 5924collect_args([Argno/_|Args],Literal,M):- 5925 findall(Term, 5926 (M:'$aleph_local'(lazy_evaluate,eval(pos,Lit)), 5927 tparg(Argno,Lit,Term)), 5928 PTerms), 5929 findall(Term, 5930 (M:'$aleph_local'(lazy_evaluate,eval(neg,Lit)), 5931 tparg(Argno,Lit,Term)), 5932 NTerms), 5933 tparg(Argno,Literal,[PTerms,NTerms]), 5934 collect_args(Args,Literal,M). 5935 5936% when construct_bottom = false 5937% currently do not check if user's definition of lazily evaluated 5938% literal corresponds to recall number in the modes 5939lazy_evaluate1(false,Atom,_,I,O,C,_,Lit,NewLits,M):- 5940 functor(Atom,Name,Arity), 5941 p1_message('lazy evaluation'), p_message(Name), 5942 functor(NewLit,Name,Arity), 5943 findall(NewLit,(M:Lit,copy_args(Lit,NewLit,C)),NewLits), 5944 copy_io_args(NewLits,Atom,I,O). 5945 5946lazy_evaluate1(true,Atom,Depth,I,O,_,D,Lit,NewLits,M):- 5947 % M:'$aleph_sat'(lastlit,_), 5948 call_library_pred(Atom,Depth,Lit,I,O,D,M), 5949 findall(LitNum,(retract(M:'$aleph_local'(lazy_evaluated,LitNum))),NewLits). 5950 5951call_library_pred(OldLit,Depth,Lit,I,O,D,M):- 5952 functor(OldLit,Name,Arity), 5953 M:'$aleph_global'(lazy_recall,lazy_recall(Name/Arity,Recall)), 5954 asserta(M:'$aleph_local'(callno,1)), 5955 p1_message('lazy evaluation'), p_message(Name), 5956 repeat, 5957 evaluate(OldLit,Depth,Lit,I,O,D,M), 5958 retract(M:'$aleph_local'(callno,CallNo)), 5959 NextCall is CallNo + 1, 5960 asserta(M:'$aleph_local'(callno,NextCall)), 5961 NextCall > Recall, 5962 !, 5963 p_message('completed'), 5964 retract(M:'$aleph_local'(callno,NextCall)). 5965 5966evaluate(OldLit,_,Lit,I,O,D,M):- 5967 functor(OldLit,Name,Arity), 5968 functor(NewLit,Name,Arity), 5969 M:Lit, 5970 copy_args(OldLit,NewLit,I), 5971 copy_args(OldLit,NewLit,O), 5972 copy_consts(Lit,NewLit,Arity), 5973 update_lit(LitNum,false,NewLit,I,O,D,M), 5974 \+(M:'$aleph_local'(lazy_evaluated,LitNum)), 5975 asserta(M:'$aleph_local'(lazy_evaluated,LitNum)), !. 5976evaluate(_,_,_,_,_,_,_M). 5977 5978copy_io_args([],_,_,_). 5979copy_io_args([New|NewL],Old,I,O):- 5980 copy_args(Old,New,I), 5981 copy_args(Old,New,O), 5982 copy_io_args(NewL,Old,I,O). 5983 5984copy_args(_,_,[]). 5985copy_args(Old,New,[Arg/_|T]):- 5986 tparg(Arg,Old,Term), 5987 tparg(Arg,New,Term), 5988 copy_args(Old,New,T), !. 5989 5990copy_consts(_,_,0):- !. 5991copy_consts(Old,New,Arg):- 5992 arg(Arg,Old,Term), 5993 arg(Arg,New,Term1), 5994 var(Term1), !, 5995 Term1 = aleph_const(Term), 5996 Arg0 is Arg - 1, 5997 copy_consts(Old,New,Arg0). 5998copy_consts(Old,New,Arg):- 5999 Arg0 is Arg - 1, 6000 copy_consts(Old,New,Arg0). 6001 6002% copy_modeterm(+Old,-New) 6003% copy term structure from Old to New 6004% by finding an appropriate mode declaration 6005copy_modeterm(Lit1,Lit2,M):- 6006 functor(Lit1,Name,Arity), 6007 find_mode(mode,Name/Arity,Mode,M), 6008 functor(Lit2,Name,Arity), 6009 copy_modeterms(Mode,Lit2,Arity), 6010 \+((\+ (Lit1 = Lit2))). 6011 6012% find_mode(+modetype,+Name/+Arity,-Mode) 6013% find a mode for Name/Arity of type modetype 6014find_mode(mode,Name/Arity,Mode,M):- 6015 !, 6016 functor(Mode,Name,Arity), 6017 M:'$aleph_global'(mode,mode(_,Mode)). 6018find_mode(modeh,Name/Arity,Mode,M):- 6019 !, 6020 functor(Mode,Name,Arity), 6021 M:'$aleph_global'(modeh,modeh(_,Mode)). 6022find_mode(modeb,Name/Arity,Mode,M):- 6023 !, 6024 functor(Mode,Name,Arity), 6025 M:'$aleph_global'(modeb,modeb(_,Mode)). 6026 6027% copy_modeterms(+Mode,+Lit,+Arity) 6028% copy all term structures in a mode template 6029copy_modeterms(_,_,0):- !. 6030copy_modeterms(Mode,Lit,Arg):- 6031 arg(Arg,Mode,Term), 6032 nonvar(Term), 6033 functor(Term,Name,Arity), 6034 \+((Name = '+'; Name = '-'; Name = '#')), !, 6035 functor(NewTerm,Name,Arity), 6036 arg(Arg,Lit,NewTerm), 6037 copy_modeterms(Term,NewTerm,Arity), 6038 Arg0 is Arg - 1, 6039 copy_modeterms(Mode,Lit,Arg0). 6040copy_modeterms(Mode,Lit,Arg):- 6041 Arg0 is Arg - 1, 6042 copy_modeterms(Mode,Lit,Arg0). 6043 6044 6045% theorem-prover for lazy evaluation of literals 6046lazy_prove(Type,Lit,Clause,Intervals,M):- 6047 (Clause = (Head:-Body)-> 6048 lazy_prove(Intervals,Type,Lit,Head,Body,M); 6049 lazy_prove(Intervals,Type,Lit,Clause,true,M)). 6050 6051lazy_prove([],_,_,_,_,_M). 6052lazy_prove([Interval|Intervals],Type,Lit,Head,Body,M):- 6053 lazy_index_prove(Interval,Type,Lit,Head,Body,M), 6054 lazy_prove(Intervals,Type,Lit,Head,Body,M). 6055 6056lazy_index_prove(Start-Finish,_,_,_,_,_M):- 6057 Start > Finish, !. 6058lazy_index_prove(Start-Finish,Type,Lit,Head,Body,M):- 6059 lazy_index_prove1(Type,Lit,Head,Body,Start,M), 6060 Start1 is Start + 1, 6061 lazy_index_prove(Start1-Finish,Type,Lit,Head,Body,M). 6062 6063% bind input args of lazy literal 6064% each example gives an set of input bindings 6065% this is different from Aleph 2 where only a single binding was obtained 6066lazy_index_prove1(Type,Lit,Head,Body,Num,M):- 6067 depth_bound_call((example(Num,Type,Head),Body),M), 6068 \+(M:'$aleph_local'(lazy_evaluate,eval(Type,Lit))), 6069 asserta(M:'$aleph_local'(lazy_evaluate,eval(Type,Lit))), 6070 fail. 6071lazy_index_prove1(_,_,_,_,_,_M). 6072 6073 6074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6075% S L P 6076% implemented as described by Muggleton, ILP-96 6077 6078condition_target(M):- 6079 M:'$aleph_global'(condition,set(condition,true)), 6080 add_generator(M), 6081 M:'$aleph_global'(modeh,modeh(_,Pred)), 6082 functor(Pred,Name,Arity), 6083 p_message('conditioning'), 6084 make_sname(Name,SName), 6085 functor(SPred,SName,Arity), 6086 SPred =.. [_|Args], 6087 functor(Fact,Name,Arity), 6088 M:example(_,_,Fact), 6089 Fact =.. [_|Args], 6090 condition(SPred,M), 6091 fail. 6092condition_target(M):- 6093 \+(M:'$aleph_global'(condition,set(condition,true))), 6094 add_generator(M), !. 6095condition_target(_M). 6096 6097 6098add_generator(M):- 6099 M:'$aleph_global'(modeh,modeh(_,Pred)), 6100 functor(Pred,Name,Arity), 6101 make_sname(Name,SName), 6102 functor(SPred,SName,Arity), 6103 (clause(M:,_)-> 6104 true; 6105 add_generator(Name/Arity,M), 6106 p1_message('included generator'), p_message(SName/Arity)), 6107 fail. 6108add_generator(_M). 6109 6110add_generator(Name/Arity,M):- 6111 make_sname(Name,SName), 6112 functor(SPred,SName,Arity), 6113 find_mode(modeh,Name/Arity,Mode,M), 6114 once(copy_modeterms(Mode,SPred,Arity)), 6115 split_args(Mode,Mode,Input,Output,Constants,M), 6116 range_restrict(Input,SPred,[],B1), 6117 range_restrict(Output,SPred,B1,B2), 6118 range_restrict(Constants,SPred,B2,B3), 6119 list_to_goals(B3,Body), 6120 \+(clause(M:,Body)), 6121 asserta(M:(SPred:-Body)), 6122 fail. 6123add_generator(_,_M). 6124 6125make_sname(Name,SName):- 6126 concat(['*',Name],SName). 6127 6128range_restrict([],_,R,R). 6129range_restrict([Pos/Type|T],Pred,R0,R):- 6130 functor(TCheck,Type,1), 6131 tparg(Pos,Pred,X), 6132 arg(1,TCheck,X), 6133 range_restrict(T,Pred,[TCheck|R0],R). 6134 6135 6136condition(Fact,M):- 6137 slprove(condition,Fact,M), !. 6138condition(_,_M). 6139 6140sample(_,0,[],_M):- !. 6141sample(Name/Arity,N,S,M):- 6142 functor(Pred,Name,Arity), 6143 retractall(M:'$aleph_local'(slp_samplenum,_)), 6144 retractall(M:'$aleph_local'(slp_sample,_)), 6145 asserta(M:'$aleph_local'(slp_samplenum,1)), 6146 repeat, 6147 slprove(stochastic,Pred,M), 6148 asserta(M:'$aleph_local'(slp_sample,Pred)), 6149 retract(M:'$aleph_local'(slp_samplenum,N1)), 6150 N2 is N1 + 1, 6151 asserta(M:'$aleph_local'(slp_samplenum,N2)), 6152 N2 > N, 6153 !, 6154 retract(M:'$aleph_local'(slp_samplenum,N2)), 6155 functor(Fact,Name,Arity), 6156 findall(Fact,(retract(M:'$aleph_local'(slp_sample,Fact))),S). 6157 6158gsample(Name/Arity,_,M):- 6159 make_sname(Name,SName), 6160 functor(SPred,SName,Arity), 6161 clause(M:,Body), 6162 ground((SPred:-Body)), !, 6163 update_gsample(Name/Arity,_,M). 6164gsample(_,0,_M):- !. 6165gsample(Name/Arity,N,M):- 6166 functor(Pred,Name,Arity), 6167 make_sname(Name,SName), 6168 functor(SPred,SName,Arity), 6169 Pred =.. [_|Args], 6170 retractall(M:'$aleph_local'(slp_samplenum,_)), 6171 asserta(M:'$aleph_local'(slp_samplenum,0)), 6172 repeat, 6173 slprove(stochastic,SPred,M), 6174 SPred =..[_|Args], 6175 retract(M:'$aleph_local'(slp_samplenum,N1)), 6176 N2 is N1 + 1, 6177 asserta(M:'$aleph_local'(slp_samplenum,N2)), 6178 assertz(M:example(N2,rand,Pred)), 6179 N2 >= N, 6180 !, 6181 retract(M:'$aleph_local'(slp_samplenum,N2)), 6182 asserta(M:'$aleph_global'(size,size(rand,N))), 6183 asserta(M:'$aleph_global'(last_example,last_example(rand,N))), 6184 asserta(M:'$aleph_global'(atoms,atoms(rand,[1-N]))), 6185 asserta(M:'$aleph_global'(atoms_left,atoms_left(rand,[1-N]))). 6186 6187update_gsample(Name/Arity,_,M):- 6188 functor(Pred,Name,Arity), 6189 make_sname(Name,SName), 6190 functor(SPred,SName,Arity), 6191 retractall(M:'$aleph_global'(gsample,gsample(_))), 6192 retractall(M:'$aleph_local'(slp_samplenum,_)), 6193 asserta(M:'$aleph_local'(slp_samplenum,0)), 6194 SPred =.. [_|Args], 6195 Pred =.. [_|Args], 6196 clause(M:,Body), 6197 ground((SPred:-Body)), 6198 record_example(check,rand,(Pred:-Body),N1,M), 6199 retract(M:'$aleph_local'(slp_samplenum,_)), 6200 asserta(M:'$aleph_local'(slp_samplenum,N1)), 6201 fail. 6202update_gsample(_,N,M):- 6203 M:'$aleph_local'(slp_samplenum,N), 6204 N > 0, !, 6205 retract(M:'$aleph_local'(slp_samplenum,N)), 6206 set(gsamplesize,N,M), 6207 retract(M:'$aleph_global'(atoms,atoms(rand,_))), 6208 retract(M:'$aleph_global'(atoms_left,atoms_left(rand,_))), 6209 retract(M:'$aleph_global'(last_example,last_example(rand,_))), 6210 assert(M:'$aleph_global'(atoms,atoms(rand,[1-N]))), 6211 assert(M:'$aleph_global'(atoms_left,atoms_left(rand,[1-N]))), 6212 assert(M:'$aleph_global'(last_example,last_example(rand,N))). 6213update_gsample(_,_,_M). 6214 6215 6216slprove(_,true,_M):- 6217 !. 6218slprove(Mode,not(Goal),M):- 6219 slprove(Mode,Goal,M), 6220 !, 6221 fail. 6222slprove(Mode,(Goal1,Goal2),M):- 6223 !, 6224 slprove(Mode,Goal1,M), 6225 slprove(Mode,Goal2,M). 6226slprove(Mode,(Goal1;Goal2),M):- 6227 !, 6228 slprove(Mode,Goal1,M); 6229 slprove(Mode,Goal2,M). 6230slprove(_,Goal,_M):- 6231 predicate_property(Goal,built_in), !, 6232 . 6233slprove(stochastic,Goal,M):- 6234 findall(Count/Clause, 6235 (clause(M:,Body),Clause=(Goal:-Body),find_count(Clause,Count,M)), 6236 ClauseCounts), 6237 renormalise(ClauseCounts,Normalised), 6238 aleph_random(X), 6239 rselect_clause(X,Normalised,(Goal:-Body)), 6240 slprove(stochastic,Body,M). 6241slprove(condition,Goal,M):- 6242 functor(Goal,Name,Arity), 6243 functor(Head,Name,Arity), 6244 clause(M:,Body), 6245 \+(\+((Head=Goal,slprove(condition,Body,M)))), 6246 inc_count((Head:-Body),M). 6247 6248renormalise(ClauseCounts,Normalised):- 6249 sum_counts(ClauseCounts,L), 6250 L > 0, 6251 renormalise(ClauseCounts,L,Normalised). 6252 6253sum_counts([],0). 6254sum_counts([N/_|T],C):- 6255 sum_counts(T,C1), 6256 C is N + C1. 6257 6258renormalise([],_,[]). 6259renormalise([Count/Clause|T],L,[Prob/Clause|T1]):- 6260 Prob is Count/L, 6261 renormalise(T,L,T1). 6262 6263rselect_clause(X,[P/C|_],C):- X =< P, !. 6264rselect_clause(X,[P/_|T],C):- 6265 X1 is X - P, 6266 rselect_clause(X1,T,C). 6267 6268 6269find_count(Clause,N,M):- 6270 copy_term(Clause,Clause1), 6271 M:'$aleph_global'(slp_count,Clause1,N), !. 6272find_count(_,1,_M). 6273 6274inc_count(Clause,M):- 6275 retract(M:'$aleph_global'(slp_count,Clause,N)), !, 6276 N1 is N + 1, 6277 asserta(M:'$aleph_global'(slp_count,Clause,N1)). 6278inc_count(Clause,M):- 6279 asserta(M:'$aleph_global'(slp_count,Clause,2)). 6280 6281find_posgain(PCover,P,M):- 6282 M:'$aleph_global'(greedy,set(greedy,true)), !, 6283 interval_count(PCover,P). 6284find_posgain(PCover,P,M):- 6285 M:'$aleph_global'(atoms_left,atoms_left(pos,PLeft)), 6286 intervals_intersection(PLeft,PCover,PC), 6287 interval_count(PC,P). 6288 6289 6290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6291% S E A R C H I / O 6292 6293record_clause(good,Label,Clause,_,M):- 6294 setting(good,true,M), 6295 setting(goodfile_stream,Stream,M), !, 6296 set_output(Stream), 6297 Label = [_,_,L|_], 6298 aleph_writeq('$aleph_good'(L,Label,Clause)), write('.'), nl, 6299 flush_output(Stream), 6300 set_output(user_output). 6301record_clause(Flag,Label,Clause,Nodes,M):- 6302 Flag \= good, 6303 setting(recordfile_stream,Stream,M), !, 6304 set_output(Stream), 6305 show_clause(Flag,Label,Clause,Nodes,M), 6306 flush_output(Stream), 6307 set_output(user_output). 6308record_clause(_,_,_,_,_M). 6309 6310record_theory(Flag,Label,Clauses,Nodes,M):- 6311 setting(recordfile_stream,Stream,M), !, 6312 set_output(Stream), 6313 show_theory(Label,Clauses,Nodes,Flag,M), 6314 flush_output(Stream), 6315 set_output(user_output). 6316record_theory(_,_,_,_,_M). 6317 6318record_theory(Flag,Label,Clauses,Nodes,M):- 6319 setting(recordfile_stream,Stream,M), !, 6320 set_output(Stream), 6321 show_theory(Label,Clauses,Nodes,Flag,M), 6322 flush_output(Stream), 6323 set_output(user_output). 6324record_theory(_,_,_,_,_). 6325 6326record_sat_example(N,M):- 6327 setting(recordfile_stream,Stream,M), !, 6328 set_output(Stream), 6329 p1_message('sat'), p_message(N), 6330 flush_output(Stream), 6331 set_output(user_output). 6332record_sat_example(_,_M). 6333 6334record_search_stats(Clause,Nodes,Time,M):- 6335 setting(recordfile_stream,Stream,M), !, 6336 set_output(Stream), 6337 p1_message('clauses constructed'), p_message(Nodes), 6338 p1_message('search time'), p_message(Time), 6339 p_message('best clause'), 6340 pp_dclause(Clause,M), 6341 % show(hypothesis), 6342 flush_output(Stream), 6343 set_output(user_output). 6344record_search_stats(_,_,_,_M). 6345 6346record_tsearch_stats(Theory,Nodes,Time,M):- 6347 setting(recordfile_stream,Stream,M), !, 6348 set_output(Stream), 6349 p1_message('theories constructed'), p_message(Nodes), 6350 p1_message('search time'), p_message(Time), 6351 p_message('best theory'), 6352 pp_dclauses(Theory,M), 6353 % show(hypothesis), 6354 flush_output(Stream), 6355 set_output(user_output). 6356record_tsearch_stats(_,_,_,_). 6357 6358record_theory(Time,M):- 6359 setting(recordfile_stream,Stream,M), !, 6360 set_output(Stream), 6361 show(theory,M), 6362 p1_message('time taken'), p_message(Time), 6363 nl, 6364 (M:'$aleph_global'(maxcover,set(maxcover,true))-> 6365 show(theory/5,M), nl, 6366 show(max_set/4,M), nl, 6367 show(rules/1,M); 6368 true), 6369 flush_output(Stream), 6370 set_output(user_output). 6371record_theory(_,_M). 6372 6373record_features(Time,M):- 6374 setting(recordfile_stream,Stream,M), !, 6375 set_output(Stream), 6376 show(features,M), 6377 p1_message('time taken'), p_message(Time), 6378 flush_output(Stream), 6379 set_output(user_output). 6380record_features(_,_). 6381 6382record_settings(M):- 6383 setting(recordfile_stream,Stream,M), !, 6384 set_output(Stream), 6385 (M:'$aleph_global'(os,set(os,unix)) -> 6386 execute(date), 6387 execute(hostname); 6388 true), 6389 show(settings,M), 6390 flush_output(Stream), 6391 set_output(user_output). 6392record_settings(_M). 6393 6394show_clause(Flag,Label,Clause,Nodes,M):- 6395 broadcast(clause(Flag,Label,Clause,Nodes)), 6396 p_message('-------------------------------------'), 6397 (Flag=good -> p_message('good clause'); 6398 (Flag=sample-> p_message('selected from sample'); 6399 p_message('found clause'))), 6400 pp_dclause(Clause,M), 6401 (setting(evalfn,Evalfn,M)-> true; Evalfn = coverage), 6402 show_stats(Evalfn,Label), 6403 p1_message('clause label'), p_message(Label), 6404 p1_message('clauses constructed'), p_message(Nodes), 6405 p_message('-------------------------------------'). 6406 6407show_theory(Flag,Label,Clauses,Nodes,M):- 6408 p_message('-------------------------------------'), 6409 (Flag=good -> p_message('good theory'); 6410 (Flag=sample-> p_message('selected from sample'); 6411 p_message('found theory'))), 6412 pp_dclauses(Clauses,M), 6413 (setting(evalfn,Evalfn,M)-> true; Evalfn = accuracy), 6414 show_stats(Evalfn,Label), 6415 p1_message('theory label'), p_message(Label), 6416 p1_message('theories constructed'), p_message(Nodes), 6417 p_message('-------------------------------------'). 6418 6419update_search_stats(N,T,M):- 6420 (retract(M:'$aleph_global'(search_stats,search_stats(N0,T0))) -> 6421 N1 is N0 + N, 6422 T1 is T0 + T; 6423 N1 is N, 6424 T1 is T), 6425 asserta(M:'$aleph_global'(search_stats,search_stats(N1,T1))). 6426 6427record_total_stats(M):- 6428 setting(recordfile_stream,Stream,M), !, 6429 set_output(Stream), 6430 show_total_stats(M), 6431 flush_output(Stream), 6432 set_output(user_output). 6433record_total_stats(_M). 6434 6435record_atoms_left(M):- 6436 setting(recordfile_stream,Stream,M), !, 6437 set_output(Stream), 6438 show_atoms_left(M), 6439 flush_output(Stream), 6440 set_output(user_output). 6441record_atoms_left(_M). 6442 6443show_total_stats(M):- 6444 M:'$aleph_global'(search_stats,search_stats(Nodes,_)), !, 6445 p1_message('total clauses constructed'), p_message(Nodes). 6446show_total_stats(_M). 6447 6448show_atoms_left(M):- 6449 M:'$aleph_global'(atoms_left,atoms_left(pos,PLeft)), 6450 interval_count(PLeft,NLeft), 6451 M:'$aleph_global'(size,size(pos,NPos)), 6452 M:'$aleph_global'(search_stats,search_stats(_,Time)), 6453 EstTime is (Time*NLeft)/(NPos - NLeft), 6454 p1_message('positive examples left'), p_message(NLeft), 6455 p1_message('estimated time to finish (secs)'), p_message(EstTime), !. 6456show_atoms_left(_M). 6457 6458show_stats(Evalfn,[P,N,_,F|_]):- 6459 ((Evalfn = user; Evalfn = entropy; Evalfn = gini) -> 6460 Value is -F; 6461 Value is F 6462 ), 6463 concat(['pos cover = ',P,' neg cover = ',N],Mess), 6464 p1_message(Mess), 6465 print_eval(Evalfn,Value). 6466 6467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6468% A U T O -- R E F I N E 6469% 6470% built-in refinement operator 6471 6472gen_auto_refine(M):- 6473 (setting(autorefine,true,M) -> true; 6474 set(autorefine,true,M), 6475 process_modes(M), 6476 process_determs(M)), 6477 !. 6478gen_auto_refine(_M). 6479 6480 6481process_modes(M):- 6482 once(aleph_abolish('$aleph_link_vars'/2,M)), 6483 once(aleph_abolish('$aleph_has_vars'/3,M)), 6484 once(aleph_abolish('$aleph_has_ovar'/4,M)), 6485 once(aleph_abolish('$aleph_has_ivar'/4,M)), 6486 M:'$aleph_global'(modeb,modeb(_,Mode)), 6487 process_mode(Mode,M), 6488 fail. 6489process_modes(M):- 6490 M:'$aleph_global'(determination,determination(Name/Arity,_)), 6491 find_mode(modeh,Name/Arity,Mode,M), 6492 split_args(Mode,Mode,I,O,_,M), 6493 functor(Lit,Name,Arity), 6494 copy_modeterms(Mode,Lit,Arity), 6495 add_ivars(Lit,I,M), 6496 add_ovars(Lit,O,M), 6497 add_vars(Lit,I,O,M), 6498 fail. 6499process_modes(_M). 6500 6501process_determs(M):- 6502 once(aleph_abolish('$aleph_determination'/2,M)), 6503 M:'$aleph_global'(determination,determination(Name/Arity,Name1/Arity1)), 6504 functor(Pred,Name1,Arity1), 6505 find_mode(modeb,Name1/Arity1,Mode,M), 6506 copy_modeterms(Mode,Pred,Arity1), 6507 Determ = M:'$aleph_determination'(Name/Arity,Pred), 6508 ( -> true; assert(Determ)), 6509 fail. 6510process_determs(_M). 6511 6512process_mode(Mode,M):- 6513 functor(Mode,Name,Arity), 6514 split_args(Mode,Mode,I,O,C,M), 6515 functor(Lit,Name,Arity), 6516 copy_modeterms(Mode,Lit,Arity), 6517 add_ioc_links(Lit,I,O,C,M), 6518 add_ovars(Lit,O,M), 6519 add_vars(Lit,I,O,M). 6520 6521add_ioc_links(Lit,I,O,C,M):- 6522 Clause = ('$aleph_link_vars'(Lit,Lits):- 6523 aleph:var_types(Lits,VT,M), 6524 Body), 6525 get_o_links(O,Lit,VT,true,OGoals,M), 6526 get_i_links(I,Lit,VT,OGoals,IOGoals), 6527 get_c_links(C,Lit,IOGoals,Body), 6528 assert(M:). 6529 6530add_ovars(Lit,O,M):- 6531 aleph_member(Pos/Type,O), 6532 tparg(Pos,Lit,V), 6533 (M:'$aleph_has_ovar'(Lit,V,Type,Pos)->true; 6534 assert(M:'$aleph_has_ovar'(Lit,V,Type,Pos))), 6535 fail. 6536add_ovars(_,_,_M). 6537 6538add_ivars(Lit,I,M):- 6539 aleph_member(Pos/Type,I), 6540 tparg(Pos,Lit,V), 6541 (M:'$aleph_has_ivar'(Lit,V,Type,Pos)->true; 6542 assert(M:'$aleph_has_ivar'(Lit,V,Type,Pos))), 6543 fail. 6544add_ivars(_,_,_M). 6545 6546add_vars(Lit,I,O,M):- 6547 get_var_types(I,Lit,IVarTypes), 6548 get_var_types(O,Lit,OVarTypes), 6549 (M:'$aleph_has_vars'(Lit,IVarTypes,OVarTypes) -> true; 6550 assert(M:'$aleph_has_vars'(Lit,IVarTypes,OVarTypes))). 6551 6552get_var_types([],_,[]). 6553get_var_types([Pos/Type|PlaceTypes],Lit,[Var/Type|Rest]):- 6554 tparg(Pos,Lit,Var), 6555 get_var_types(PlaceTypes,Lit,Rest). 6556 6557get_o_links([],_,_,Goals,Goals,_M). 6558get_o_links([Pos/Type|T],Lit,VarTypes,GoalsSoFar,Goals,M):- 6559 tparg(Pos,Lit,V), 6560 Goal = (aleph:aleph_output_var(V,Type,VarTypes); 6561 aleph:aleph_output_var(V,Type,Lit,Pos,M)), 6562 prefix_lits((Goal),GoalsSoFar,G1), 6563 get_o_links(T,Lit,VarTypes,G1,Goals,M). 6564 6565 6566get_i_links([],_,_,Goals,Goals). 6567get_i_links([Pos/Type|T],Lit,VarTypes,GoalsSoFar,Goals):- 6568 tparg(Pos,Lit,V), 6569 Goal = aleph:aleph_input_var(V,Type,VarTypes), 6570 prefix_lits((Goal),GoalsSoFar,G1), 6571 get_i_links(T,Lit,VarTypes,G1,Goals). 6572 6573get_c_links([],_,Goals,Goals). 6574get_c_links([Pos/Type|T],Lit,GoalsSoFar,Goals):- 6575 tparg(Pos,Lit,V), 6576 TypeFact =.. [Type,C], 6577 Goal = (TypeFact,V=C), 6578 prefix_lits((Goal),GoalsSoFar,G1), 6579 get_c_links(T,Lit,G1,Goals). 6580 6581aleph_input_var(Var,Type,VarTypes):- 6582 aleph_member(Var/Type1,VarTypes), 6583 nonvar(Type1), 6584 Type = Type1. 6585 6586aleph_output_var(Var,Type,VarTypes):- 6587 aleph_member(Var/Type1,VarTypes), 6588 nonvar(Type1), 6589 Type = Type1. 6590aleph_output_var(_,_,_). 6591 6592aleph_output_var(Var,Type,Lit,ThisPos,M):- 6593 M:'$aleph_has_ovar'(Lit,Var,Type,Pos), 6594 Pos @< ThisPos.
6600var_types([Head|Body],VarTypes,M):- 6601 hvar_types(Head,HVarTypes,M), 6602 bvar_types(Body,HVarTypes,BVarTypes,M), 6603 aleph_append(BVarTypes,HVarTypes,VarTypesList), 6604 sort(VarTypesList,VarTypes). 6605 6606hvar_types(Head,HVarTypes,M):- 6607 M:'$aleph_has_vars'(Head,IVarTypes,OVarTypes), 6608 aleph_append(IVarTypes,OVarTypes,HVarTypes). 6609 6610bvar_types([],V,V,_M). 6611bvar_types([Lit|Lits],VTSoFar,BVarTypes,M):- 6612 M:'$aleph_has_vars'(Lit,IVarTypes,OVarTypes),!, 6613 consistent_vartypes(IVarTypes,VTSoFar), 6614 \+ inconsistent_vartypes(OVarTypes,VTSoFar), 6615 aleph_append(OVarTypes,VTSoFar,VT1), 6616 bvar_types(Lits,VT1,BVarTypes,M). 6617bvar_types([not(Lit)|Lits],VTSoFar,BVarTypes,M):- 6618 M:'$aleph_has_vars'(Lit,IVarTypes,OVarTypes), 6619 consistent_vartypes(IVarTypes,VTSoFar), 6620 \+ inconsistent_vartypes(OVarTypes,VTSoFar), 6621 aleph_append(OVarTypes,VTSoFar,VT1), 6622 bvar_types(Lits,VT1,BVarTypes,M). 6623consistent_vartypes([],_). 6624consistent_vartypes([Var/Type|VarTypes],VTSoFar):- 6625 aleph_member2(Var/Type,VTSoFar), 6626 consistent_vartypes(VarTypes,VTSoFar). 6627 6628inconsistent_vartypes([Var/Type|_],VTSoFar):- 6629 aleph_member(Var1/Type1,VTSoFar), 6630 Var == Var1, 6631 Type \== Type1, !. 6632inconsistent_vartypes([_|VarTypes],VTSoFar):- 6633 inconsistent_vartypes(VarTypes,VTSoFar). 6634 6635 6636aleph_get_hlit(Name/Arity,Head,M):- 6637 functor(Head,Name,Arity), 6638 find_mode(modeh,Name/Arity,Mode,M), 6639 once(split_args(Mode,Mode,_,_,C,M)), 6640 copy_modeterms(Mode,Head,Arity), 6641 get_c_links(C,Head,true,Equalities), 6642 M:Equalities. 6643 6644aleph_get_lit(Lit,[H|Lits],M):- 6645 functor(H,Name,Arity), 6646 aleph_get_lit(Lit,Name/Arity,M), 6647 M:'$aleph_link_vars'(Lit,[H|Lits]), 6648 \+(aleph_member2(Lit,[H|Lits])). 6649 6650aleph_get_lit(Lit,Target,M):- 6651 M:'$aleph_determination'(Target,Lit). 6652 6653% aleph_mode_linked(+Lits) 6654% checks to see if a sequence of literals are within mode language 6655% using information compiled by process_modes/0 6656aleph_mode_linked([H|B],M):- 6657 aleph_mode_linked(B,[H],M). 6658 6659aleph_mode_linked([],_,_M):- !. 6660aleph_mode_linked([Lit|Lits],LitsSoFar,M):- 6661 M:'$aleph_link_vars'(Lit,LitsSoFar), 6662 aleph_append([Lit],LitsSoFar,L1), 6663 aleph_mode_linked(Lits,L1,M). 6664 6665auto_refine(aleph_false,Head,M):- 6666 example_saturated(Example,M), 6667 functor(Example,Name,Arity), 6668 aleph_get_hlit(Name/Arity,Head,M), 6669 Head \== aleph_false. 6670auto_refine(aleph_false,Head,M):- 6671 M:'$aleph_global'(modeh,modeh(_,Pred)), 6672 functor(Pred,Name,Arity), 6673 aleph_get_hlit(Name/Arity,Head,M), 6674 Head \== aleph_false. 6675auto_refine((H:-B),(H1:-B1),M):- 6676 !, 6677 goals_to_list((H,B),LitList), 6678 setting(clauselength,L,M), 6679 length(LitList,ClauseLength), 6680 ClauseLength < L, 6681 aleph_get_lit(Lit,LitList,M), 6682 aleph_append([Lit],LitList,LitList1), 6683 list_to_goals(LitList1,(H1,B1)), 6684 \+(M:prune((H1:-B1))), 6685 \+(tautology((H1:-B1),M)), 6686 (setting(language,Lang,M) -> 6687 lang_ok(Lang,H1,B1); 6688 true), 6689 (setting(newvars,NewVars,M) -> 6690 newvars_ok(NewVars,H1,B1); 6691 true). 6692auto_refine(Head,Clause,M):- 6693 auto_refine((Head:-true),Clause,M). 6694 6695% refinement with lookahead 6696auto_refine(1,Clause1,Clause2,M):- 6697 !, 6698 auto_refine(Clause1,Clause2,M). 6699auto_refine(L,Clause1,Clause2,M):- 6700 L1 is L - 1, 6701 auto_refine(L1,Clause1,Clause,M), 6702 (Clause2 = Clause; 6703 auto_refine(Clause,Clause2,M)). 6704 6705auto_extend((H:-B),Lit,(H1:-B1),M):- 6706 !, 6707 goals_to_list((H,B),LitList), 6708 setting(clauselength,L,M), 6709 length(LitList,ClauseLength), 6710 ClauseLength < L, 6711 aleph_get_lit(Lit,LitList,M), 6712 aleph_append([Lit],LitList,LitList1), 6713 list_to_goals(LitList1,(H1,B1)), 6714 (setting(language,Lang,M) -> 6715 lang_ok(Lang,H1,B1); 6716 true), 6717 (setting(newvars,NewVars,M) -> 6718 newvars_ok(NewVars,H1,B1); 6719 true), 6720 \+(tautology((H1:-B1),M)), 6721 \+(M:prune((H1:-B1))). 6722 6723auto_extend((H),Lit,(H1:-B1),M):- 6724 !, 6725 goals_to_list(H,LitList), 6726 setting(clauselength,L,M), 6727 length(LitList,ClauseLength), 6728 ClauseLength < L, 6729 aleph_get_lit(Lit,LitList,M), 6730 aleph_append([Lit],LitList,LitList1), 6731 list_to_goals(LitList1,(H1,B1)), 6732 (setting(language,Lang,M) -> 6733 lang_ok(Lang,H1,B1); 6734 true), 6735 (setting(newvars,NewVars,M) -> 6736 newvars_ok(NewVars,H1,B1); 6737 true), 6738 \+(tautology((H1:-B1),M)), 6739 \+(M:prune((H1:-B1))). 6740 6741tautology((aleph_false:-Body),M):- 6742 !, 6743 in(Body,L1,Rest,M), 6744 in(Rest,not(L2),M), 6745 L1 == L2. 6746tautology((Head:-Body),M):- 6747 in(Body,Lit,M), 6748 Head == Lit, !. 6749 6750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6751% A U T O -- M O D E 6752 6753% automatic inference of mode declarations given a set of 6754% determinations. The procedure works in two parts: (i) finding 6755% equivalence classes of types; and (ii) finding an input/output 6756% assignment. 6757% 6758% Finding equivalence classes of types is similar to 6759% the work of McCreath and Sharma, Proc of the 8th Australian 6760% Joint Conf on AI pages 75-82, 1995. However, unlike there 6761% types in the same equivalence class are given the same name only if 6762% they "overlap" significantly (the overlap of type1 with type2 6763% is the proportion of elements of type1 that are also elements of type2). 6764% Significantly here means an overlap at least some threshold 6765% T (set using typeoverlap, with default 0.95). 6766% Since this may not be perfect, modes are also produced 6767% for equality statements that re-introduce co-referencing amongst 6768% differently named types in the same equivalence class. 6769% The user has to however explicitly include a determination declaration for 6770% the equality predicate. 6771% 6772% The i/o assignment is not straightforward, as we may be dealing 6773% with non-functional definitions. The assignment sought here is one 6774% that maximises the number of input args as this gives the 6775% largest bottom clause. This assignment is 6776% is sought by means of a search procedure over mode sequences. 6777% Suppose we have a mode sequence M = <m1,m2,..m{i-1}> that uses the types T. 6778% An argument of type t in mode m{i} is an input iff t overlaps 6779% significantly (used in the same sense as earlier) with some type in T. 6780% Otherwise the argument is an output. 6781% The utility of each mode sequence M is f(M) = g(M) + h(M) where 6782% g(M) is the number of input args in M; and h(M) is a (lower) estimate 6783% of the number of input args in any mode sequence of which M is a prefix. 6784% The search strategy adopted is a simple hill-climbing one. 6785% 6786% All very complicated: there must be a simpler approach. 6787% Requires generative background predicates. 6788 6789search_modes(M):- 6790 M:'$aleph_global'(targetpred,targetpred(N/A)), 6791 findall(N1/A1,determinations(N/A,N1/A1,M),L), 6792 number_types([N/A|L],0,TypedPreds,Last), 6793 get_type_elements(TypedPreds,M), 6794 interval_to_list(1-Last,Types), 6795 get_type_equivalences(Types,Equiv1,M), 6796 merge_equivalence_classes(Equiv1,Equiv,M), 6797 store_type_equivalences(Equiv,M), 6798 setting(typeoverlap,Thresh,M), 6799 infer_modes(TypedPreds,Thresh,Types,Modes,M), 6800 infer_equalities(EqModes,M), 6801 Modes = [_|BodyModes], 6802 infer_negations(BodyModes,NegModes), 6803 (setting(updateback,Update,M) -> true; Update = true), 6804 p_message('found modes'), 6805 add_inferred_modes(Modes,Update,M), 6806 add_inferred_modes(EqModes,Update,M), 6807 add_inferred_modes(NegModes,Update,M), 6808 fail. 6809search_modes(_M). 6810 6811number_types([],Last,[],Last). 6812number_types([N/A|T],L0,[Pred|T1],L1):- 6813 functor(Pred,N,A), 6814 L is L0 + A, 6815 number_types(A,L,Pred), 6816 number_types(T,L,T1,L1). 6817 6818number_types(0,_,_):- !. 6819number_types(A,N,Pred):- 6820 arg(A,Pred,N), 6821 A1 is A - 1, 6822 N1 is N - 1, 6823 number_types(A1,N1,Pred). 6824 6825get_type_elements([],_M). 6826get_type_elements([Pred|Preds],M):- 6827 functor(Pred,Name,Arity), 6828 functor(Template,Name,Arity), 6829 interval_to_list(1-Arity,AL), 6830 get_type_elements(M:example(_,_,Template),Template,Pred,AL,M), 6831 get_type_elements(Template,Template,Pred,AL,M), 6832 get_type_elements(Preds,M). 6833 6834get_type_elements(Fact,Template,Pred,AL,M):- 6835 aleph_member(Arg,AL), 6836 findall(Val,(M:Fact,ground(Fact),arg(Arg,Template,Val)),Vals), 6837 arg(Arg,Pred,Type), 6838 sort(Vals,SVals), 6839 (retract(M:'$aleph_search'(modes,type(Type,_,OtherVals))) -> 6840 aleph_ord_union(SVals,OtherVals,ArgVals); 6841 ArgVals = SVals), 6842 length(ArgVals,N), 6843 asserta(M:'$aleph_search'(modes,type(Type,N,ArgVals))), 6844 fail. 6845get_type_elements(_,_,_,_,_M). 6846 6847get_type_equivalences([],[],_M). 6848get_type_equivalences([First|Rest],[Class|Classes],M):- 6849 get_type_equivalence(Rest,[First],Class,Left,M), 6850 get_type_equivalences(Left,Classes,M). 6851 6852get_type_equivalence([],Class1,Class,[],_):- 6853 sort(Class1,Class). 6854get_type_equivalence([Type|Rest],Class1,Class,Left,M):- 6855 type_equivalent(Class1,Type,M), !, 6856 get_type_equivalence(Rest,[Type|Class1],Class,Left,M). 6857get_type_equivalence([Type|Rest],Class1,Class,[Type|Left],M):- 6858 get_type_equivalence(Rest,Class1,Class,Left,M). 6859 6860merge_equivalence_classes([Class],[Class],_M):- !. 6861merge_equivalence_classes(Classes1,Classes2,M):- 6862 aleph_delete(Class1,Classes1,Left), 6863 aleph_delete(Class2,Left,Left1), 6864 class_equivalent(Class1,Class2,M), !, 6865 aleph_ord_union(Class1,Class2,NewClass), 6866 merge_equivalence_classes([NewClass|Left1],Classes2,M). 6867merge_equivalence_classes(Classes,Classes,_M). 6868 6869class_equivalent(Class1,Class2,M):- 6870 aleph_member(Type1,Class1), 6871 type_equivalent(Class2,Type1,M), !. 6872 6873type_equivalent([T1|_],T2,M):- 6874 M:'$aleph_search'(modes,type(T1,_,E1)), 6875 M:'$aleph_search'(modes,type(T2,_,E2)), 6876 intersects(E1,E2), !. 6877type_equivalent([_|T],T2,M):- 6878 type_equivalent(T,T2,M). 6879 6880store_type_equivalences([],_M). 6881store_type_equivalences([[CType|Class]|Classes],M):- 6882 length([CType|Class],N), 6883 store_type_equivalence([CType|Class],CType,N,M), 6884 store_type_equivalences(Classes,M). 6885 6886store_type_equivalence([],_,_,_M). 6887store_type_equivalence([Type|Types],CType,Neq,M):- 6888 retract(M:'$aleph_search'(modes,type(Type,N,Elements))), 6889 store_type_overlaps(Types,Type,Elements,N,M), 6890 asserta(M:'$aleph_search'(modes,type(Type,CType,Neq,N,Elements))), 6891 store_type_equivalence(Types,CType,Neq,M). 6892 6893store_type_overlaps([],_,_,_,_M). 6894store_type_overlaps([T1|Types],T,E,N,M):- 6895 M:'$aleph_search'(modes,type(T1,N1,E1)), 6896 aleph_ord_intersection(E1,E,Int), 6897 length(Int,NInt), 6898 O is NInt/N, 6899 O1 is NInt/N1, 6900 asserta(M:'$aleph_search'(modes,typeoverlap(T,T1,O,O1))), 6901 store_type_overlaps(Types,T,E,N,M). 6902 6903infer_modes([Head|Rest],Thresh,Types,[Head1|Rest1],M):- 6904 infer_mode(Head,Thresh,head,[],Head1,Seen,M), 6905 aleph_delete_list(Seen,Types,TypesLeft), 6906 infer_ordered_modes(Rest,Thresh,body,Seen,TypesLeft,Rest1,M). 6907 6908infer_ordered_modes([],_,_,_,_,[],_M):- !. 6909infer_ordered_modes(L,Thresh,Loc,Seen,Left,[Mode|Rest],M):- 6910 score_modes(L,Thresh,Seen,Left,ScoredPreds,M), 6911 keysort(ScoredPreds,[_-Pred|_]), 6912 infer_mode(Pred,Thresh,Loc,Seen,Mode,Seen1,M), 6913 aleph_delete(Pred,L,L1), 6914 aleph_delete_list(Seen1,Left,Left1), 6915 infer_ordered_modes(L1,Thresh,Loc,Seen1,Left1,Rest,M). 6916 6917score_modes([],_,_,_,[],_M). 6918score_modes([Pred|Preds],Thresh,Seen,Left,[Cost-Pred|Rest],M):- 6919 Pred =.. [_|Types], 6920 evaluate_backward(Types,Thresh,Seen,G,M), 6921 aleph_delete_list(Types,Left,Left1), 6922 estimate_forward(Seen,Thresh,Left1,H0,M), 6923 estimate_forward(Types,Thresh,Left1,H1,M), 6924 Diff is H1 - H0, 6925 (Diff < 0 -> H is 0; H is Diff), 6926 Cost is -(G + H), 6927 score_modes(Preds,Thresh,Seen,Left,Rest,M). 6928 6929evaluate_backward([],_,_,0.0,_M). 6930evaluate_backward([Type|Types],Thresh,Seen,Score,M):- 6931 best_overlap(Seen,Type,_,Overlap,M), 6932 (Overlap >= Thresh -> Score1 = 1.0; Score1 = 0.0), 6933 evaluate_backward(Types,Thresh,Seen,Score2,M), 6934 Score is Score1 + Score2. 6935 6936estimate_forward([],_,_,0.0,_M). 6937estimate_forward([Type|Types],Thresh,Left,Score,M):- 6938 estimate_forward1(Left,Thresh,Type,S1,M), 6939 estimate_forward(Types,Thresh,Left,S2,M), 6940 Score is S1 + S2. 6941 6942estimate_forward1([],_,_,0.0,_M). 6943estimate_forward1([T1|Types],Thresh,T,Score,M):- 6944 type_overlap(T1,T,O1,M), 6945 (O1 >= Thresh -> S1 is 1.0; S1 is 0.0), 6946 estimate_forward1(Types,Thresh,T,S2,M), 6947 Score is S1 + S2. 6948 6949infer_mode(Pred,Thresh,Loc,Seen0,InferredMode,Seen,M):- 6950 Pred =.. [Name|Types], 6951 infer_mode1(Types,Thresh,Loc,Seen0,Modes,M), 6952 Mode =.. [Name|Modes], 6953 length(Types,Arity), 6954 (M:'$aleph_global'(targetpred,targetpred(Name/Arity)) -> 6955 InferredMode = modeh(*,Mode); 6956 InferredMode = mode(*,Mode)), 6957 aleph_ord_union(Seen0,Types,Seen). 6958 6959infer_mode1([],_,_,_,[],_M). 6960infer_mode1([Type|Types],Thresh,Loc,Seen,[Mode|Modes],M):- 6961 best_overlap(Seen,Type,Best,Overlap,M), 6962 (Overlap >= Thresh -> 6963 M:'$aleph_search'(modes,typemapped(Best,_,NewType)), 6964 asserta(M:'$aleph_search'(modes,typemapped(Type,Best,NewType))), 6965 concat([type,NewType],Name), 6966 Mode = +Name; 6967 (Overlap > 0.0 -> 6968 asserta(M:'$aleph_search'(modes,typemapped(Type,Best,Type))); 6969 asserta(M:'$aleph_search'(modes,typemapped(Type,Type,Type)))), 6970 concat([type,Type],Name), 6971 (Loc = head -> Mode = +Name; Mode = -Name) 6972 ), 6973 infer_mode1(Types,Thresh,Loc,Seen,Modes,M). 6974 6975 6976best_overlap([T1],T,T1,O,M):- 6977 !, 6978 type_overlap(T,T1,O,M). 6979best_overlap([T1|Types],T,Best,O,M):- 6980 type_overlap(T,T1,O1,M), 6981 best_overlap(Types,T,T2,O2,M), 6982 (O2 > O1 -> O is O2, Best = T2; O is O1, Best = T1). 6983best_overlap([],T,T,0.0,_M). 6984 6985type_overlap(T,T1,O,M):- 6986 T > T1, !, 6987 (M:'$aleph_search'(modes,typeoverlap(T1,T,_,O)) -> true; O = 0.0). 6988type_overlap(T,T1,O,M):- 6989 (M:'$aleph_search'(modes,typeoverlap(T,T1,O,_)) -> true; O = 0.0). 6990 6991 6992infer_equalities(EqModes,M):- 6993 findall(mode(1,(Eq)),(pairwise_equality(Eq,M);grounding_equality(Eq,M)), 6994 EqL), 6995 sort(EqL,EqModes). 6996 6997infer_negations([],[]). 6998infer_negations([mode(_,Pred)|Modes],NegModes):- 6999 Pred =.. [_|Args], 7000 aleph_member1(-_,Args), !, 7001 infer_negations(Modes,NegModes). 7002infer_negations([mode(_,Pred)|Modes],[mode(1,not(Pred))|NegModes]):- 7003 infer_negations(Modes,NegModes). 7004 7005 7006pairwise_equality((+N1 = +N2),M):- 7007 M:'$aleph_search'(modes,typemapped(_,Best,T1)), 7008 M:'$aleph_search'(modes,typemapped(Best,_,T2)), 7009 T1 \== T2, 7010 concat([type,T1],N1), 7011 concat([type,T2],N2). 7012grounding_equality((+N1 = #N1),M):- 7013 M:'$aleph_search'(modes,typemapped(T1,_,T1)), 7014 concat([type,T1],N1). 7015 7016add_inferred_modes([],_,_M). 7017add_inferred_modes([Mode|Modes],Flag,M):- 7018 write(Mode), nl, 7019 (Flag = true -> M:Mode; true), 7020 add_inferred_modes(Modes,Flag,M). 7021 7022 7023%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7024% S T O C H A S T I C S E A R C H 7025 7026% sample_clauses(+N,-Clauses) 7027% return sample of at most N legal clauses from hypothesis space 7028% If a bottom clause exists then 7029% Each clause is drawn randomly. The length of the clause is 7030% determined by: 7031% (a) user-specified distribution over clauselengths 7032% using set(clauselength_distribution,Distribution); 7033% Distribution is a list of the form p1-1, p2-2,... 7034% specifying that clauselength 1 has prob p1, etc. 7035% Note: sum pi must = 1. This is not checked; or 7036% (b) uniform distribution over all legal clauses. 7037% (if clauselength_distribution is not set) 7038% this uses a Monte-Carlo estimate of the number of 7039% legal clauses in the hypothesis space 7040% If a bottom clause does not exist, then legal clauses are constructed 7041% using the mode declarations. Only option (a) is allowed. If 7042% clauselength_distribution is not set, then a uniform distribution over 7043% lengths is assumed. 7044% Each element of Clauses is of the form L-[E,T,Lits,Clause] where 7045% L is the clauselength; E,T are example number and type (pos, neg) used 7046% to build the bottom clause; Lits contains the literal numbers in the 7047% bottom clause for Clause. If no bottom clause then E,T = 0 and Lits = [] 7048% Clauses is in ascending order of clause length 7049sample_clauses(N,Clauses,M):- 7050 setting(construct_bottom,Bottom,M), 7051 sample_nclauses(Bottom,N,Clauses,M). 7052 7053sample_nclauses(false,N,Clauses,M):- 7054 !, 7055 gen_auto_refine(M), 7056 (setting(clauselength_distribution,D,M) -> true; 7057 setting(clauselength,CL,M), 7058 Uniform is 1.0/CL, 7059 distrib(1-CL,Uniform,D)), 7060 sample_nclauses_using_modes(N,D,CList,M), 7061 remove_alpha_variants(CList,CList1), 7062 keysort(CList1,Clauses). 7063sample_nclauses(_,N,Clauses,M):- 7064 retractall(M:'$aleph_sat'(random,rselect(_))), 7065 (M:'$aleph_sat'(example,example(_,_)) -> true; rsat(M)), 7066 setting(clauselength,CL,M), 7067 (setting(clauselength_distribution,Universe,M) -> 7068 Sample is N; 7069 estimate_numbers(CL,1,400,Universe,M), 7070 (N > Universe -> Sample is Universe; Sample is N)), 7071 get_clause_sample(Sample,Universe,CL,CList,M), 7072 keysort(CList,Clauses). 7073 7074% sample_nclauses_using_modes(+N,+D,-Clauses) 7075% get upto N legal clauses using mode declarations 7076% and distribution D over clauselengths 7077 7078sample_nclauses_using_modes(0,_,[],_M):- !. 7079sample_nclauses_using_modes(N,D,[Clause|Rest],M):- 7080 legal_clause_using_modes(100,D,Clause,M), 7081 N1 is N - 1, 7082 sample_nclauses_using_modes(N1,D,Rest,M). 7083 7084% legal_clause_using_modes(+N,+D,-Clause,M) 7085% make at most N attempts to obtain a legal clause Clause 7086% from mode language using distribution D over clauselengths 7087% if all N attempts fail, then just return most general clause 7088legal_clause_using_modes(N,D,L-[0,0,[],Clause],M):- 7089 N > 0, 7090 sample_clause_using_modes(D,L,Clause,M), 7091 \+(M:prune(Clause)), 7092 split_clause(Clause,Head,Body), 7093 (setting(language,Lang,M) -> 7094 lang_ok(Lang,Head,Body); 7095 true), 7096 (setting(newvars,NewVars,M) -> 7097 newvars_ok(NewVars,Head,Body); 7098 true), 7099 !. 7100legal_clause_using_modes(N,D,Clause,M):- 7101 N > 1, 7102 N1 is N - 1, 7103 legal_clause_using_modes(N1,D,Clause,M), !. 7104legal_clause_using_modes(_,_,1-[0,0,[],Clause],M):- 7105 sample_clause_using_modes([1.0-1],1,Clause,M). 7106 7107sample_clause_using_modes(D,L,Clause,M):- 7108 findall(H,auto_refine(aleph_false,H,M),HL), 7109 HL \= [], 7110 random_select(Head,HL,_), 7111 draw_element(D,L), 7112 (L = 1 -> Clause = Head; 7113 L1 is L - 1, 7114 sample_clause_using_modes(L1,Head,Clause,M)). 7115 7116sample_clause_using_modes(N,ClauseSoFar,Clause,M):- 7117 findall(C,auto_refine(ClauseSoFar,C,M),CL), 7118 CL \= [], !, 7119 (N = 1 -> random_select(Clause,CL,_); 7120 random_select(C1,CL,_), 7121 N1 is N - 1, 7122 sample_clause_using_modes(N1,C1,Clause,M)). 7123sample_clause_using_modes(_,Clause,Clause,_M). 7124 7125 7126% get_clause_sample(+N,+U,+CL,-Clauses,M) 7127% get upto N legal clauses of at most length CL drawn from universe U 7128% U is either the total number of legal clauses 7129% or a distribution over clauselengths 7130% the clauses are constructed by drawing randomly from bottom 7131get_clause_sample(0,_,_,[],_):- !. 7132get_clause_sample(N,Universe,CL,[L-[E,T,C1,C]|Clauses],M):- 7133 (number(Universe) -> 7134 get_rrandom(Universe,ClauseNum), 7135 num_to_length(ClauseNum,CL,L,M), 7136 UpperLim is CL; 7137 draw_element(Universe,L), 7138 UpperLim is L), 7139 draw_legalclause_wo_repl(L,UpperLim,C,C1,M), !, 7140 M:'$aleph_sat'(example,example(E,T)), 7141 N1 is N - 1, 7142 get_clause_sample(N1,Universe,CL,Clauses,M). 7143get_clause_sample(N,Universe,CL,Clauses,M):- 7144 N1 is N - 1, 7145 get_clause_sample(N1,Universe,CL,Clauses,M). 7146 7147% draw_legalclause_wo_repl(+L,+CL,-C,-Lits,M) 7148% randomly draw without replacement a legal clause of length >= L and =< CL 7149% also returns literals from bottom used to construct clause 7150draw_legalclause_wo_repl(L,CL,C,C1,M):- 7151 L =< CL, 7152 randclause_wo_repl(L,C,legal,C1,M), !. 7153draw_legalclause_wo_repl(L,CL,C,C1,M):- 7154 L < CL, 7155 L1 is L + 1, 7156 draw_legalclause_wo_repl(L1, CL,C,C1,M). 7157 7158% estimate_clauselength_distribution(+L,+T,+K,-D,M) 7159% for each clauselength l <= L, estimate the probability of 7160% drawing a good clause 7161% here, a ``good clause'' is one that is in the top K-percentile of clauses 7162% estimation is by Monte Carlo using at most T trials 7163% probabilities are normalised to add to 1 7164estimate_clauselength_distribution(L,T,K,D,M):- 7165 M:'$aleph_sat'(example,example(Type,Example)), 7166 M:'$aleph_sat'(random,clauselength_distribution(Type,Example,L,T,K,D)), !. 7167estimate_clauselength_distribution(L,T,K,D,M):- 7168 setting(evalfn,Evalfn,M), 7169 estimate_clauselength_scores(L,T,Evalfn,[],S,M), 7170 select_good_clauses(S,K,Good), 7171 estimate_frequency(L,Good,Freq), 7172 normalise_distribution(Freq,D), 7173 (M:'$aleph_sat'(example,example(Type,Example)) -> 7174 asserta(M:'$aleph_sat'(random,clauselength_distribution(Type, 7175 Example,L,T,K,D))); 7176 true). 7177 7178estimate_clauselength_scores(0,_,_,S,S,_):- !. 7179estimate_clauselength_scores(L,T,Evalfn,S1,S,M):- 7180 set(clauselength_distribution,[1.0-L],M), 7181 p1_message('Estimate scores of clauses with length'), p_message(L), 7182 sample_clauses(T,Clauses,M), 7183 estimate_scores(Clauses,Evalfn,S1,S2,M), 7184 L1 is L - 1, 7185 estimate_clauselength_scores(L1,T,Evalfn,S2,S,M). 7186 7187estimate_scores([],_,S,S,_M):- !. 7188estimate_scores([L-[_,_,_,C]|Rest],Evalfn,S1,S,M):- 7189 label_create(C,Label,M), 7190 extract_count(pos,Label,PC), 7191 extract_count(neg,Label,NC), 7192 complete_label(Evalfn,C,[PC,NC,L],[_,_,_,Val|_],M), 7193 estimate_scores(Rest,Evalfn,[-Val-L|S1],S,M). 7194 7195% ``good'' clauses are defined to be those in the top K-percentile 7196% policy on ties is to include them 7197select_good_clauses(S,K,Good):- 7198 keysort(S,S1), 7199 length(S1,Total), 7200 N is integer(K*Total/100), 7201 select_good_clauses(S1,N,[],Good). 7202 7203select_good_clauses([],_,Good,Good):- !. 7204select_good_clauses(_,N,Good,Good):- N =< 0, !. 7205select_good_clauses([Score-X|T],N,GoodSoFar,Good):- 7206 select_good_clauses(T,Score,N,[Score-X|GoodSoFar],N0,Good1,T1), 7207 N1 is N0 - 1, 7208 select_good_clauses(T1,N1,Good1,Good). 7209 7210select_good_clauses([],_,N,G,N,G,[]):- !. 7211select_good_clauses([Score-X|T],Score,N,GoodSoFar,N0,Good1,T1):- 7212 !, 7213 N1 is N - 1, 7214 select_good_clauses(T,Score,N1,[Score-X|GoodSoFar],N0,Good1,T1). 7215select_good_clauses(L,_,N,G,N,G,L). 7216 7217estimate_frequency(0,_,[]). 7218estimate_frequency(L,Good,[N-L|T]):- 7219 count_frequency(Good,L,N), 7220 L1 is L - 1, 7221 estimate_frequency(L1,Good,T). 7222 7223count_frequency([],_,0). 7224count_frequency([Entry|T],X,N):- 7225 count_frequency(T,X,N1), 7226 (Entry = _-X -> N is N1 + 1; N is N1). 7227 7228% estimate total number of legal clauses in space 7229% bounded by bot 7230estimate_numbers(Total,M):- 7231 (M:'$aleph_sat'(example,example(_,_)) -> true; rsat), 7232 setting(clauselength,CL,M), 7233 estimate_numbers(CL,1,400,Total,M). 7234 7235% estimate_numbers(+L,+Trials,+Sample,-T,M) 7236% estimate total number of legal clauses of length <= L in space 7237% bounded by bot 7238% estimated number is cached for future use 7239% estimation is by Monte Carlo, averaged over Trials trials 7240% with given sample size 7241estimate_numbers(L,Trials,Sample,Total,M):- 7242 M:'$aleph_sat'(example,example(Type,Example)), 7243 M:'$aleph_sat'(random,sample(Type,Example,L,Trials,Sample)), 7244 M:'$aleph_sat'(random,hypothesis_space(Total)), !. 7245estimate_numbers(L,Trials,Sample,Total,M):- 7246 retractall(M:'$aleph_sat'(random,sample(_,_,_,_,_))), 7247 retractall(M:'$aleph_sat'(random,hypothesis_space(_))), 7248 estimate_numbers(L,Trials,Sample,0,Total,M), 7249 asserta(M:'$aleph_sat'(random,hypothesis_space(Total))), 7250 M:'$aleph_sat'(example,example(Type,Example)), 7251 asserta(M:'$aleph_sat'(random,sample(Type,Example,L,Trials,Sample))). 7252 7253% estimate_numbers(+L,+Trials,+Sample,+TotalSoFar,-Total) 7254% estimate the number of legal clauses of length <= L 7255% estimated number of legal clauses at each length are cached for future use 7256% TotalSoFar is an accumulator of the number legal clauses so far 7257% Total is the cumulative total of the number of legal clauses 7258estimate_numbers(0,_,_,T,T,_M):- !. 7259estimate_numbers(L,Trials,Sample,TotalSoFar,T,M):- 7260 retractall(M:'$aleph_sat'(random,number_of_clauses(L,_))), 7261 estimate_number(Trials,Sample,L,T0,M), 7262 asserta(M:'$aleph_sat'(random,number_of_clauses(L,T0))), 7263 L1 is L - 1, 7264 T1 is T0 + TotalSoFar, 7265 estimate_numbers(L1,Trials,Sample,T1,T,M). 7266 7267% estimate_number(+T,+S,+L,-N,M) 7268% monte carlo estimate of number of legal clauses of length L 7269% estimate formed from average over T trials with sample S 7270estimate_number(_,_,L,0,M):- 7271 M:'$aleph_sat'(lastlit,Last), 7272 Last < L, !. 7273estimate_number(T,S,L,N,M):- 7274 T > 0, 7275 p1_message('Estimate legal clauses with length'), p_message(L), 7276 estimate_number(T,S,0,L,Total,M), 7277 N is float(Total/T), 7278 concat(['trials=',T,' sample=', S, ' estimate=', N],Mess), 7279 p_message(Mess). 7280 7281estimate_number(1,S,Total,L,N,M):- 7282 !, 7283 estimate_number(L,S,N1,M), 7284 N is Total + N1. 7285estimate_number(T,S,Total,L,N,M):- 7286 p_message('New Trial'), 7287 estimate_number(L,S,N1,M), 7288 Total1 is Total + N1, 7289 T1 is T - 1, 7290 estimate_number(T1,S,Total1,L,N,M). 7291 7292% estimate_number(+L,+S,-N) 7293% estimate the number of legal clauses of length L in the search space 7294% estimation based on sample size S 7295estimate_number(1,_,1,_M):- !. 7296estimate_number(L,S,N,M):- 7297 estimate_proportion(S,L,legal,P,_,M), 7298 M:'$aleph_sat'(lastlit,Last), 7299 total_clauses(L,Last,Total), 7300 N is float(P*Total). 7301 7302% estimate_proportion(+N,+L,+S,-P,-Clauses,M) 7303% estimate prop. of at most N random clauses of length L and status S 7304% clauses are generated without replacement 7305% S is one of legal or illegal depending on whether C is inside or 7306% outside the mode language provided 7307% Clauses is the list of at most N def. clauses 7308% If S is a variable then clauses can be legal or illegal 7309% Thus estimate_proportion(10000,2,S,P,C,M) returns the 7310% proportion and list of 2 literal clauses which are either 7311% legal or illegal in a sample of at most 10000 7312% Keeps legal clauses obtained in rselect_legal for later use 7313estimate_proportion(0,_,_,0,[],_M):- !. 7314estimate_proportion(N,L,S,P,Clauses,M):- 7315 retractall(M:'$aleph_sat'(random,rselect(_))), 7316 retractall(M:'$aleph_sat'(random,rselect_legal(L,_,_,_,_))), 7317 get_random_wo_repl(N,L,Clauses,M), 7318 length(Clauses,Total), 7319 count_clause_status(Clauses,S,A,_), 7320 (Total = 0 -> P = 0; P is A/Total), 7321 M:'$aleph_sat'(example,example(E,T)), 7322 retractall(M:'$aleph_sat'(random,rselect(_))), 7323 store_legal_clauses(Clauses,L,E,T,M). 7324 7325% get_random_wo_repl(+N,+L,-List,M) 7326% randomly construct at most N definite clauses of length L 7327% returns Status/Clause list where Status is one of legal/illegal 7328get_random_wo_repl(0,_,[],_,_M):- !. 7329get_random_wo_repl(N,L,[S/[C,C1]|Clauses],M):- 7330 randclause_wo_repl(L,C,S,C1,M), !, 7331 N1 is N - 1, 7332 get_random_wo_repl(N1,L,Clauses,M). 7333get_random_wo_repl(_,_,[],_M). 7334 7335% print_distribution 7336print_distribution(M):- 7337 write('Clause Length'), tab(8), write('Estimated number of clauses'), nl, 7338 write('_____________'), tab(8), write('___________________________'), nl, 7339 findall(L-N,M:'$aleph_sat'(random,number_of_clauses(L,N)),List), 7340 sort(List,List1), 7341 aleph_member(L-N,List1), 7342 write(L), tab(20), write(N), nl, 7343 fail. 7344print_distribution(M):- 7345 nl, 7346 write('Estimated size of hypothesis space = '), 7347 (M:'$aleph_sat'(random,hypothesis_space(S)) -> true; S = 0), 7348 write(S), write(' clauses'), nl. 7349 7350% count_clause_status(+List,+Status,-C1,-C2) 7351% count number of clauses in List with status Status 7352% C1 is the number of such clauses 7353% C2 is the number of clauses with some other status 7354count_clause_status(_,S,_,0):- 7355 var(S), !. 7356count_clause_status(Clauses,S,A,B):- 7357 count_clause_status1(Clauses,S,A,B). 7358 7359count_clause_status1([],_,0,0):- !. 7360count_clause_status1([S1/_|T],S,A,B):- 7361 count_clause_status1(T,S,A1,B1), 7362 (S == S1 -> A is A1 + 1, B is B1; A is A1, B is B1 + 1). 7363 7364% store_legal_clauses(+List,+L,+E,+T) 7365% store all legal clauses of length L obtained with bottom clause for 7366% example E of type T 7367% useful later when a random legal clause of length L is required 7368store_legal_clauses([],_,_,_,_M). 7369store_legal_clauses([S/[C,C1]|Clauses],L,E,T,M):- 7370 (S == legal -> 7371 asserta(M:'$aleph_sat'(random,rselect_legal(L,E,T,C,C1))); 7372 true), 7373 store_legal_clauses(Clauses,L,E,T,M). 7374 7375% randclause_wo_repl(+L,-C,-S,-Lits) 7376% as randclause/4 but ensures that clause obtained is without replacement 7377% only makes at most 100 attempts to find such a clause 7378% also returns lits from bottom clause selected 7379% if all attempts fail, then return the most general clause 7380randclause_wo_repl(L,C,S,C1,M):- 7381 randclause_wo_repl(100,L,C,S,C1,M). 7382 7383randclause_wo_repl(N,L,C,S,C1,M):- 7384 N > 0, 7385 randclause(L,C,S,C1,M), % if not accounting for variable renamings 7386 % copy_term(C,C1), % if accounting for variable renamings 7387 % numbervars(C1,0,_), % if accounting for variable renamings 7388 \+(M:prune(C)), 7389 split_clause(C,Head,Body), 7390 (setting(language,Lang,M) -> 7391 lang_ok(Lang,Head,Body); 7392 true), 7393 (setting(newvars,NewVars,M) -> 7394 newvars_ok(NewVars,Head,Body); 7395 true), 7396 \+(M:'$aleph_sat'(random,rselect(C1))), !, 7397 asserta(M:'$aleph_sat'(random,rselect(C1))). 7398randclause_wo_repl(N,L,C,S,C1,M):- 7399 N > 0, 7400 N1 is N - 1, 7401 randclause_wo_repl(N1,L,C,S,C1,M), !. 7402randclause_wo_repl(_,1,C,S,C1,M):- 7403 randclause(1,C,S,C1,M). % if not accounting for variable renamings 7404 % copy_term(C,C1), % if accounting for variable renamings 7405 % numbervars(C1,0,_), % if accounting for variable renamings 7406 7407% randclause(+L,-C,-S,-Lits,M) 7408% returns definite clause C of length L with status S comprised of Lits 7409% drawn at random from the bottom clause 7410% also returns the literals in the bottom clause that were selected 7411% body literals of C are randomly selected from the bottom clause 7412% S is one of legal or illegal depending on whether C is inside or 7413% outside the mode language provided 7414% needs a bottom clause to be constructed before it is meaningful 7415% this can be done with the sat predicate for eg: sat(1) 7416% if set(store_bottom,true) then use stored bottom clause instead 7417% if S is legal, then checks to see if previously generated legal 7418% clauses exist for this bottom clause (these would have been generated 7419% when trying to estimate the number of legal clause at each length) 7420randclause(1,C,legal,[1],M):- 7421 !, 7422 bottom_key(_,_,Key,_,M), 7423 (Key = false -> 7424 get_pclause([1],[],C,_,_,_,M); 7425 get_pclause([1],Key,[],C,_,_,_,M)). 7426randclause(L,C,Status,Lits,M):- 7427 Status == legal, 7428 M:'$aleph_sat'(example,example(E,T)), 7429 retract(M:'$aleph_sat'(random,rselect_legal(L,E,T,C,Lits))). 7430% can do things more efficiently if we want to generate legal clauses only 7431randclause(L,C,Status,Lits,M):- 7432 Status == legal, !, 7433 bottom_key(_,_,Key,_,M), 7434 (Key = false -> 7435 M:'$aleph_sat_litinfo'(1,_,_,_,_,D); 7436 M:'$aleph_sat_litinfo'(1,Key,_,_,_,_,D)), 7437 L1 is L - 1, 7438 repeat, 7439 randselect1(L1,Key,D,[1],BodyLits,M), 7440 Lits = [1|BodyLits], 7441 clause_status(Lits,Key,[],legal,legal,M), !, 7442 (Key = false -> 7443 get_pclause(Lits,[],C,_,_,_,M); 7444 get_pclause(Lits,Key,[],C,_,_,_,M)). 7445randclause(L,C,Status,Lits,M):- 7446 L1 is L - 1, 7447 bottom_key(_,_,Key,_,M), 7448 (Key = false -> 7449 M:'$aleph_sat'(lastlit,Last); 7450 M:'$aleph_sat'(lastlit,Key,Last)), 7451 repeat, 7452 randselect(L1,Last,Key,[],BodyLits,M), 7453 aleph_append(BodyLits,[1],Lits), 7454 clause_status(Lits,Key,[],legal,Status1,M), 7455 Status1 = Status, !, 7456 (Key = false -> 7457 get_pclause(Lits,[],C,_,_,_,M); 7458 get_pclause(Lits,Key,[],C,_,_,_,M)). 7459 7460% clause_status(+Lits,+LitsSoFar,+StatusSoFar,-Status,M) 7461% compute status of a clause 7462% Lits is the lits left to add to the clause 7463% LitsSoFar is the lits in the clause so far 7464% StatusSoFar is the Status of the clause so far 7465% if a literal to be added contains unbound input vars then 7466% status is illegal 7467clause_status(Lits,LitsSoFar,Status1,Status2,M):- 7468 bottom_key(_,_,Key,_,M), 7469 clause_status(Lits,Key,LitsSoFar,Status1,Status2,M). 7470 7471clause_status([],_,_,S,S,_M):- !. 7472clause_status([Lit|Lits],Key,LitsSoFar,S,S1,M):- 7473 get_ovars(LitsSoFar,Key,[],OVars,M), 7474 get_ivars([Lit],Key,[],IVars,M), 7475 aleph_subset1(IVars,OVars), !, 7476 aleph_append([Lit],LitsSoFar,Lits1), 7477 clause_status(Lits,Key,Lits1,S,S1,M). 7478clause_status(_,_,_,_,illegal,_M). 7479 7480 7481% randselect(+L,+Last,+Key,+LitsSoFar,-Lits,M) 7482% randomly select L distinct literals to give Lits 7483% Last is the last literal number in the bottom clause 7484% LitsSoFar is the literals selected so far 7485randselect(0,_,_,_,[],_M):- !. 7486randselect(_,Last,_,LitsSoFar,[],_M):- 7487 length(LitsSoFar,L1), 7488 L1 is Last - 1, !. 7489randselect(L,Last,Key,LitsSoFar,[LitNum|Lits],M):- 7490 get_rand_lit(Last,Key,LitsSoFar,LitNum,M), 7491 L1 is L - 1, 7492 randselect(L1,Last,Key,[LitNum|LitsSoFar],Lits,M). 7493 7494% randselect1(+L,+Key,+Avail,+LitsSoFar,-Lits,M) 7495% randomly select L distinct literals from Avail to give Lits 7496% LitsSoFar is the literals selected so far 7497randselect1(0,_,_,_,[],_M):- !. 7498randselect1(_,_,[],_,[],_M):- !. 7499randselect1(L,Key,Avail,LitsSoFar,[LitNum|Lits],M):- 7500 random_select(LitNum,Avail,Left), 7501 (Key = false -> 7502 M:'$aleph_sat_litinfo'(LitNum,_,_,_,_,D); 7503 M:'$aleph_sat_litinfo'(LitNum,Key,_,_,_,_,D)), 7504 update_list(D,Left,Left1), 7505 aleph_delete_list([LitNum|LitsSoFar],Left1,Avail1), 7506 L1 is L - 1, 7507 randselect1(L1,Key,Avail1,[LitNum|LitsSoFar],Lits,M). 7508 7509% get_rand_lit(+Last,+Key,+LitsSoFar,-LitNum,M) 7510% randomly select a literal number from 2 - Last 7511% and not in list LitsSoFar 7512% 2 because 1 is reserved for head literal 7513get_rand_lit(Last,Key,LitsSoFar,LitNum,M):- 7514 repeat, 7515 get_rand_lit(Last,Key,LitNum,M), 7516 \+(aleph_member(LitNum,LitsSoFar)), 7517 !. 7518 7519% have to use repeat/0 in case literal number from random no generator 7520% no longer exists in lits database 7521get_rand_lit(Last,Key,LitNum,M):- 7522 repeat, 7523 get_random(Last,LitNum), 7524 LitNum > 1, 7525 (Key = false -> 7526 M:'$aleph_sat_litinfo'(LitNum,_,_,_,_,_); 7527 M:'$aleph_sat_litinfo'(LitNum,Key,_,_,_,_,_)), !. 7528 7529% total_clauses(+L,+N1,-N2) 7530% total number of clauses of length L is N2 7531% constructed from bottom clause of length N1 7532total_clauses(1,_,1.0):- !. 7533total_clauses(L,Bot,N):- 7534 L1 is L - 1, 7535 Bot1 is Bot - 1, 7536 total_clauses(L1,Bot1,N1), 7537 N is N1*Bot1. 7538 7539% num_to_length(+N,+CL,-L,M) 7540% find length of clause numbered N 7541% clause length should be =< CL 7542 7543num_to_length(N,_,1,_M):- N =< 1.0, !. 7544num_to_length(N,CL,L,M):- 7545 num_to_length1(2,CL,N,1.0,L,M). 7546 7547num_to_length1(L,CL,_,_,CL,_M):- 7548 L >= CL, !. 7549num_to_length1(L,CL,N,TotalSoFar,Length,M):- 7550 M:'$aleph_sat'(random,number_of_clauses(L,T)), 7551 NClauses is TotalSoFar + T, 7552 (N =< NClauses -> 7553 (T < 1.0 -> Length is L - 1; Length = L) ; 7554 L1 is L + 1, 7555 num_to_length1(L1,CL,N,NClauses,Length,M)). 7556 7557% refinement operator for randomised local search 7558% Type is one of clauses or theories 7559rls_refine(clauses,_-[_,_,_,aleph_false],Clause,M):- 7560 !, 7561 sample_clauses(1,[Clause],M), 7562 \+(old_move(clauses,Clause,M)). 7563rls_refine(clauses,Clause1,Clause2,M):- 7564 setting(moves,Max,M), 7565 MaxMoves is Max, 7566 once(retract(M:'$aleph_search'(rls_move,Mov))), 7567 Mov =< MaxMoves, 7568 p1_message('move'), p_message(Mov), 7569 Mov1 is Mov + 1, 7570 asserta(M:'$aleph_search'(rls_move,Mov1)), 7571 clause_move(Move,Clause1,Clause2,M), 7572 p_message(Move), 7573 \+(old_move(clauses,Clause2,M)). 7574 7575rls_refine(theories,[_-[_,_,_,aleph_false]],Theory,M):- 7576 !, 7577 once(theory_move(add_clause,[],Theory,M)), 7578 \+(old_move(theories,Theory,M)). 7579rls_refine(theories,Theory1,Theory2,M):- 7580 setting(moves,MaxMoves,M), 7581 once(retract(M:'$aleph_search'(rls_move,M))), 7582 M =< MaxMoves, 7583 p1_message('move'), p_message(M), 7584 M1 is M + 1, 7585 asserta(M:'$aleph_search'(rls_move,M1)), 7586 theory_move(_,Theory1,Theory2,M), 7587 \+(old_move(theories,Theory2,M)). 7588 7589% clause_move(+Type,+C1,-C2,M) 7590% local moves from clause C1 to give C2 7591% A move is: 7592% a) delete a literal from C1 (Type = delete_lit) 7593% b) add a legal literal to C1 (Type = add_lit) 7594clause_move(delete_lit,C1,C2,M):- 7595 C1 = L-[E,T,Lits,Clause], 7596 (Lits = [H|Rest] -> 7597 aleph_delete(_,Rest,Left), 7598 Lits1 = [H|Left], 7599 bottom_key(E,T,Key,_,M), 7600 clause_status(Lits1,Key,[],legal,legal,M), 7601 L1 is L - 1, 7602 (Key = false -> 7603 get_pclause(Lits1,[],Clause1,_,_,_,M); 7604 get_pclause(Lits1,Key,[],Clause1,_,_,_,M)), 7605 \+(M:prune(Clause1)) ; 7606 clause_to_list(Clause,[Head|Body]), 7607 aleph_delete(_,Body,Left), 7608 aleph_mode_linked([Head|Left],M), 7609 list_to_clause([Head|Left],Clause1), 7610 \+(M:prune(Clause1)), 7611 L1 is L - 1, 7612 Lits1 = []), 7613 C2 = L1-[E,T,Lits1,Clause1]. 7614clause_move(add_lit,C1,C2,M):- 7615 C1 = L-[E,T,Lits,Clause], 7616 setting(clauselength,CL,M), 7617 L < CL, 7618 (Lits = [] -> 7619 auto_refine(Clause,Clause1,M), 7620 L1 is L + 1, 7621 Lits1 = []; 7622 aleph_delete(Lit,Lits,Left), 7623 bottom_key(E,T,Key,_,M), 7624 (Key = false -> 7625 M:'$aleph_sat_litinfo'(Lit,_,_,_,_,D); 7626 M:'$aleph_sat_litinfo'(Lit,Key,_,_,_,_,D)), 7627 aleph_member(Lit1,D), 7628 \+(aleph_member(Lit1,Left)), 7629 aleph_append([Lit1],Lits,Lits1), 7630 clause_status(Lits1,Key,[],legal,legal,M), 7631 L1 is L + 1, 7632 (Key = false -> 7633 get_pclause(Lits1,[],Clause1,_,_,_,M); 7634 get_pclause(Lits1,Key,[],Clause1,_,_,_,M)), 7635 \+(M:prune(Clause1))), 7636 C2 = L1-[E,T,Lits1,Clause1]. 7637 7638% theory_move(+Type,+T1,-T2,M) 7639% local moves from theory T1 to give T2 7640% A move is: 7641% a) delete a clause from T1 (Type = delete_clause) 7642% b) add a legal clause to T1 (Type = add_clause) 7643% c) delete a literal from a clause in T1 (Type = delete_lit) 7644% d) add a legal literal to a clause in T1 (Type = add_lit) 7645theory_move(delete_clause,T1,T2,_M):- 7646 aleph_delete(_,T1,T2), 7647 T2 \= []. 7648theory_move(add_clause,T1,T2,M):- 7649 setting(clauses,Max,M), 7650 length(T1,L), 7651 L < Max, 7652 sample_clauses(1,[Clause],M), 7653 aleph_append([Clause],T1,T2). 7654theory_move(delete_lit,T1,T2,M):- 7655 aleph_delete(Clause,T1,T), 7656 clause_move(delete_lit,Clause,Clause1,M), 7657 aleph_append([Clause1],T,T2). 7658theory_move(add_lit,T1,T2,M):- 7659 aleph_delete(Clause,T1,T), 7660 clause_move(add_lit,Clause,Clause1,M), 7661 aleph_append([Clause1],T,T2). 7662 7663old_move(clauses,N-[_,_,L,C],M):- 7664 (setting(cache_clauselength,N1,M) -> true; N1 = 3), 7665 N =< N1, 7666 (L = [] -> 7667 clause_to_list(C,C1), 7668 sort(C1,Hash), 7669 numbervars(Hash,0,_); 7670 sort(L,Hash)), 7671 (M:'$aleph_search_seen'(N,Hash) -> 7672 p_message('old move'), 7673 true; 7674 asserta(M:'$aleph_search_seen'(N,Hash)), !, 7675 fail). 7676old_move(theories,T,M):- 7677 % remove_alpha_variants(T,T1), 7678 numbervars(T,0,_), 7679 length(T,N), 7680 (M:'$aleph_search_seen'(N,_Hash) -> 7681 p_message('old move'), 7682 true; 7683 asserta(M:'$aleph_search_seen'(N,_Hash)), !, 7684 fail). 7685 7686extract_clauses_with_length([],[]). 7687extract_clauses_with_length([L-[_,_,_,C]|T],[L-C|T1]):- 7688 extract_clauses_with_length(T,T1). 7689 7690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7691% U T I L I T I E S 7692 7693% concatenate elements of a list into an atom 7694 7695concat([Atom],Atom):- !. 7696concat([H|T],Atom):- 7697 concat(T,AT), 7698 name(AT,L2), 7699 name(H,L1), 7700 aleph_append(L2,L1,L), 7701 name(Atom,L). 7702 7703 7704split_clause((Head:-true),Head,true):- !. 7705split_clause((Head:-Body1),Head,Body2):- !, Body1 = Body2. 7706split_clause([Head|T],Head,T):- !. 7707split_clause([Head],Head,[true]):- !. 7708split_clause(Head,Head,true). 7709 7710strip_true((Head:-true),Head):- !. 7711strip_true(Clause,Clause). 7712 7713% pretty print a definite clause 7714pp_dclause(Clause,M):- 7715 (M:'$aleph_global'(portray_literals,set(portray_literals,true))-> 7716 pp_dclause(Clause,true,M); 7717 pp_dclause(Clause,false,M)). 7718 7719% pretty print a set of definite clauses 7720pp_dclauses(Theory,M):- 7721 aleph_member(_-[_,_,_,Clause],Theory), 7722 pp_dclause(Clause,M), 7723 fail. 7724pp_dclauses(_,_M):- nl. 7725 7726pp_dclause((H:-true),Pretty,M):- 7727 !, 7728 pp_dclause(H,Pretty,M). 7729pp_dclause((H:-B),Pretty,M):- 7730 !, 7731 copy_term((H:-B),(Head:-Body)), 7732 numbervars((Head:-Body),0,_), 7733 aleph_portray(Head,Pretty,M), 7734 (Pretty = true -> 7735 write(' if:'); 7736 write(' :-')), 7737 nl, 7738 M:'$aleph_global'(print,set(print,N)), 7739 print_lits(Body,Pretty,1,N,M). 7740 7741pp_dclause((Lit),Pretty,M):- 7742 copy_term(Lit,Lit1), 7743 numbervars(Lit1,0,_), 7744 aleph_portray(Lit1,Pretty,M), 7745 write('.'), nl. 7746 7747% pretty print a definite clause list: head of list is + literal 7748pp_dlist([],_M):- !. 7749pp_dlist(Clause,M):- 7750 (M:'$aleph_global'(portray_literals,set(portray_literals,true))-> 7751 pp_dlist(Clause,true,M); 7752 pp_dlist(Clause,false,M)). 7753 7754pp_dlist(Clause,Pretty,M):- 7755 copy_term(Clause,[Head1|Body1]), 7756 numbervars([Head1|Body1],0,_), 7757 aleph_portray(Head1,Pretty,M), 7758 (Body1 = [] -> 7759 write('.'), nl; 7760 (Pretty = true -> 7761 write(' if:'); 7762 write(' :-')), 7763 nl, 7764 M:'$aleph_global'(print,set(print,N)), 7765 print_litlist(Body1,Pretty,1,N,M)). 7766 7767print_litlist([],_,_,_,_M). 7768print_litlist([Lit],Pretty,LitNum,_,M):- 7769 !, 7770 print_lit(Lit,Pretty,LitNum,LitNum,'.',_,M). 7771print_litlist([Lit|Lits],Pretty,LitNum,LastLit,M):- 7772 print_lit(Lit,Pretty,LitNum,LastLit,', ',NextLit,M), 7773 print_litlist(Lits,Pretty,NextLit,LastLit,M). 7774 7775print_lits((Lit,Lits),Pretty,LitNum,LastLit,M):- 7776 !, 7777 (Pretty = true -> 7778 Sep = ' and '; 7779 Sep = ', '), 7780 print_lit(Lit,Pretty,LitNum,LastLit,Sep,NextLit,M), 7781 print_lits(Lits,Pretty,NextLit,LastLit,M). 7782print_lits((Lit),Pretty,LitNum,_,M):- 7783 print_lit(Lit,Pretty,LitNum,LitNum,'.',_,M). 7784 7785print_lit(Lit,Pretty,LitNum,LastLit,Sep,NextLit,M):- 7786 (LitNum = 1 -> tab(3);true), 7787 aleph_portray(Lit,Pretty,M), write(Sep), 7788 (LitNum=LastLit-> nl,NextLit=1; NextLit is LitNum + 1). 7789 7790p1_message(Mess):- 7791 write('['), write(Mess), write('] '). 7792 7793p_message(Mess):- 7794 write('['), write(Mess), write(']'), nl. 7795 7796err_message(Mess):- 7797 p1_message('error'), p_message(Mess). 7798 7799aleph_delete_all(_,[],[]). 7800aleph_delete_all(X,[Y|T],T1):- 7801 X == Y, !, 7802 aleph_delete_all(X,T,T1). 7803aleph_delete_all(X,[Y|T],[Y|T1]):- 7804 aleph_delete_all(X,T,T1). 7805 7806aleph_delete_list([],L,L). 7807aleph_delete_list([H1|T1],L1,L):- 7808 aleph_delete(H1,L1,L2), !, 7809 aleph_delete_list(T1,L2,L). 7810aleph_delete_list([_|T1],L1,L):- 7811 aleph_delete_list(T1,L1,L).
7818aleph_delete(H,[H|T],T). 7819aleph_delete(H,[H1|T],[H1|T1]):- 7820 aleph_delete(H,T,T1). 7821 7822aleph_delete1(H,[H|T],T):- !. 7823aleph_delete1(H,[H1|T],[H1|T1]):- 7824 aleph_delete1(H,T,T1). 7825 7826aleph_delete0(_,[],[]). 7827aleph_delete0(H,[H|T],T):- !. 7828aleph_delete0(H,[H1|T],[H1|T1]):- 7829 aleph_delete0(H,T,T1). 7830 7831aleph_append(A,[],A):-!. 7832aleph_append(A,[H|T],[H|T1]):- 7833 aleph_append(A,T,T1). 7834 7835% aleph_remove_nth(+N,+List1,-Elem,-List2) 7836% remove the nth elem from a List 7837aleph_remove_nth(1,[H|T],H,T):- !. 7838aleph_remove_nth(N,[H|T],X,[H|T1]):- 7839 N1 is N - 1, 7840 aleph_remove_nth(N1,T,X,T1). 7841 7842% aleph_remove_n(+N,+List1,-List2,-List3) 7843% remove the n elems from List1 into List2. List3 is the rest of List1 7844aleph_remove_n(0,L,[],L):- !. 7845aleph_remove_n(_,[],[],[]):- !. 7846aleph_remove_n(N,[H|T],[H|T1],L):- 7847 N1 is N - 1, 7848 aleph_remove_n(N1,T,T1,L). 7849 7850% aleph_rpermute(+List1,-List2) 7851% randomly permute the elements of List1 into List2 7852aleph_rpermute(List1,List2):- 7853 length(List1,N1), 7854 aleph_rpermute(List1,N1,List2). 7855 7856aleph_rpermute([],0,[]):- !. 7857aleph_rpermute(L1,N1,[X|Rest]):- 7858 get_random(N1,R), 7859 aleph_remove_nth(R,L1,X,L2), 7860 N2 is N1 - 1, 7861 aleph_rpermute(L2,N2,Rest). 7862 7863% aleph_rsample(+N,+List1,-List2) 7864% randomly sample N elements from List1 into List2 7865aleph_rsample(N,List1,List2):- 7866 length(List1,N1), 7867 aleph_rsample(N,N1,List1,List2). 7868 7869aleph_rsample(N,N1,L,L):- N >= N1, !. 7870aleph_rsample(SampleSize,Total,[X|L1],[X|L2]):- 7871 get_random(Total,R), 7872 R =< SampleSize, !, 7873 SampleSize0 is SampleSize - 1, 7874 Total0 is Total - 1, 7875 aleph_rsample(SampleSize0,Total0,L1,L2). 7876aleph_rsample(SampleSize,Total,[_|L1],L2):- 7877 Total0 is Total - 1, 7878 aleph_rsample(SampleSize,Total0,L1,L2). 7879 7880% get_first_n(+N,+List1,-List2) 7881% get the first n elements in List1 7882get_first_n(0,_,[]):- !. 7883get_first_n(_,[],[]):- !. 7884get_first_n(N,[H|T],[H|T1]):- 7885 N1 is N - 1, 7886 get_first_n(N1,T,T1). 7887 7888% erase_refs(+List) 7889% erase database references: only works for Yap 7890erase_refs([]). 7891erase_refs([DbRef|DbRefs]):- 7892 erase(DbRef), 7893 erase_refs(DbRefs). 7894 7895 7896% max_in_list(+List,-Max) 7897% return largest element in a list 7898max_in_list([X],X):- !. 7899max_in_list([X|T],Z):- 7900 max_in_list(T,Y), 7901 (X @> Y -> Z = X; Z = Y). 7902 7903% min_in_list(+List,-Max) 7904% return largest element in a list 7905min_in_list([X],X):- !. 7906min_in_list([X|T],Z):- 7907 min_in_list(T,Y), 7908 (X @> Y -> Z = Y; Z = X). 7909 7910% remove_alpha_variants(+List1,-List2):- 7911% remove alphabetic variants from List1 to give List2 7912remove_alpha_variants([],[]). 7913remove_alpha_variants([X|Y],L):- 7914 aleph_member(X1,Y), 7915 alphabetic_variant(X,X1), !, 7916 remove_alpha_variants(Y,L). 7917remove_alpha_variants([X|Y],[X|L]):- 7918 remove_alpha_variants(Y,L). 7919 7920% alphabetic_variant(+Term1,+Term2) 7921% true if Term1 is the alphabetic variant of Term2 7922alphabetic_variant(Term1,Term2):- 7923 copy_term(Term1/Term2,T1/T2), 7924 numbervars(T1,0,_), 7925 numbervars(T2,0,_), 7926 T1 = T2. 7927 7928% tparg(+TermPlace,+Term1,?Term2) 7929% return Term2 at position specified by TermPlace in Term1 7930tparg([Place],Term,Arg):- 7931 !, 7932 arg(Place,Term,Arg). 7933tparg([Place|Places],Term,Arg):- 7934 arg(Place,Term,Term1), 7935 tparg(Places,Term1,Arg). 7936 7937 7938aleph_member1(H,[H|_]):- !. 7939aleph_member1(H,[_|T]):- 7940 aleph_member1(H,T). 7941 7942aleph_member2(X,[Y|_]):- X == Y, !. 7943aleph_member2(X,[_|T]):- 7944 aleph_member2(X,T). 7945 7946aleph_member3(A,A-B):- A =< B. 7947aleph_member3(X,A-B):- 7948 A < B, 7949 A1 is A + 1, 7950 aleph_member3(X,A1-B). 7951 7952aleph_member(X,[X|_]). 7953aleph_member(X,[_|T]):- 7954 aleph_member(X,T). 7955 7956aleph_reverse(L1, L2) :- revzap(L1, [], L2). 7957 7958revzap([X|L], L2, L3) :- revzap(L, [X|L2], L3). 7959revzap([], L, L). 7960 7961goals_to_clause((Head,Body),(Head:-Body)):- !. 7962goals_to_clause(Head,Head).
7969clause_to_list((Head:-true),[Head]):- !. 7970clause_to_list((Head:-Body),[Head|L]):- 7971 !, 7972 goals_to_list(Body,L). 7973clause_to_list(Head,[Head]). 7974 7975extend_clause(false,Lit,(Lit)):- !. 7976extend_clause((Head:-Body),Lit,(Head:-Body1)):- 7977 !, 7978 app_lit(Lit,Body,Body1). 7979extend_clause(Head,Lit,(Head:-Lit)). 7980 7981app_lit(L,(L1,L2),(L1,L3)):- 7982 !, 7983 app_lit(L,L2,L3). 7984app_lit(L,L1,(L1,L)). 7985 7986prefix_lits(L,true,L):- !. 7987prefix_lits(L,L1,((L),L1)). 7988 7989get_goaldiffs((G1,G2),(G1,G3),Diffs):- 7990 !, 7991 get_goaldiffs(G2,G3,Diffs). 7992get_goaldiffs(true,G,G):- !. 7993get_goaldiffs(G1,(G1,G2),G2). 7994 7995nlits((_:-B),N):- 7996 !, 7997 nlits(B,N1), 7998 N is N1 + 1. 7999nlits((_,Lits),N):- 8000 !, 8001 nlits(Lits,N1), 8002 N is N1 + 1. 8003nlits(_,1). 8004 8005 8006list_to_clause([Goal],(Goal:-true)):- !. 8007list_to_clause([Head|Goals],(Head:-Body)):- 8008 list_to_goals(Goals,Body). 8009 8010list_to_goals([Goal],Goal):- !. 8011list_to_goals([Goal|Goals],(Goal,Goals1)):- 8012 list_to_goals(Goals,Goals1).
/
8020goals_to_list((true,Goals),T):- 8021 !, 8022 goals_to_list(Goals,T). 8023goals_to_list((Goal,Goals),[Goal|T]):- 8024 !, 8025 goals_to_list(Goals,T). 8026goals_to_list(true,[]):- !. 8027goals_to_list(Goal,[Goal]). 8028 8029% get_litnums(+First,+Last,-LitNums,M) 8030% get list of Literal numbers in the bottom clause 8031get_litnums(LitNum,Last,[],_M):- 8032 LitNum > Last, !. 8033get_litnums(LitNum,Last,[LitNum|LitNums],M):- 8034 M:'$aleph_sat_litinfo'(LitNum,_,_,_,_,_), !, 8035 NextLit is LitNum + 1, 8036 get_litnums(NextLit,Last,LitNums,M). 8037get_litnums(LitNum,Last,LitNums,M):- 8038 NextLit is LitNum + 1, 8039 get_litnums(NextLit,Last,LitNums,M). 8040 8041get_clause(LitNum,Last,_,[],_M):- 8042 LitNum > Last, !. 8043get_clause(LitNum,Last,TVSoFar,[FAtom|FAtoms],M):- 8044 M:'$aleph_sat_litinfo'(LitNum,_,Atom,_,_,_), !, 8045 get_flatatom(Atom,TVSoFar,FAtom,TV1), 8046 NextLit is LitNum + 1, 8047 get_clause(NextLit,Last,TV1,FAtoms,M). 8048get_clause(LitNum,Last,TVSoFar,FAtoms,M):- 8049 NextLit is LitNum + 1, 8050 get_clause(NextLit,Last,TVSoFar,FAtoms,M). 8051 8052get_flatatom(not(Atom),TVSoFar,not(FAtom),TV1):- 8053 !, 8054 get_flatatom(Atom,TVSoFar,FAtom,TV1). 8055get_flatatom(Atom,TVSoFar,FAtom,TV1):- 8056 functor(Atom,Name,Arity), 8057 functor(FAtom,Name,Arity), 8058 flatten_args(Arity,Atom,FAtom,TVSoFar,TV1). 8059 8060get_pclause([LitNum],TVSoFar,Clause,TV,Length,LastDepth,M):- 8061 !, 8062 get_pclause1([LitNum],TVSoFar,TV,Clause,Length,LastDepth,M). 8063get_pclause([LitNum|LitNums],TVSoFar,Clause,TV,Length,LastDepth,M):- 8064 get_pclause1([LitNum],TVSoFar,TV1,Head,Length1,_,M), 8065 get_pclause1(LitNums,TV1,TV,Body,Length2,LastDepth,M), 8066 Clause = (Head:-Body), 8067 Length is Length1 + Length2. 8068 8069get_pclause1([LitNum],TVSoFar,TV1,Lit,Length,LastDepth,M):- 8070 !, 8071 M:'$aleph_sat_litinfo'(LitNum,LastDepth,Atom,_,_,_), 8072 get_flatatom(Atom,TVSoFar,Lit,TV1), 8073 functor(Lit,Name,_), 8074 (Name = '='-> Length = 0; Length = 1). 8075get_pclause1([LitNum|LitNums],TVSoFar,TV2,(Lit,Lits1),Length,LastDepth,M):- 8076 M:'$aleph_sat_litinfo'(LitNum,_,Atom,_,_,_), 8077 get_flatatom(Atom,TVSoFar,Lit,TV1), 8078 get_pclause1(LitNums,TV1,TV2,Lits1,Length1,LastDepth,M), 8079 functor(Lit,Name,_), 8080 (Name = '='-> Length = Length1; Length is Length1 + 1). 8081 8082get_pclause([LitNum],Key,TVSoFar,Clause,TV,Length,LastDepth,M):- 8083 !, 8084 get_pclause1([LitNum],Key,TVSoFar,TV,Clause,Length,LastDepth,M). 8085get_pclause([LitNum|LitNums],Key,TVSoFar,Clause,TV,Length,LastDepth,M):- 8086 get_pclause1([LitNum],Key,TVSoFar,TV1,Head,Length1,_,M), 8087 get_pclause1(LitNums,Key,TV1,TV,Body,Length2,LastDepth,M), 8088 Clause = (Head:-Body), 8089 Length is Length1 + Length2. 8090 8091get_pclause1([LitNum],Key,TVSoFar,TV1,Lit,Length,LastDepth,M):- 8092 !, 8093 M:'$aleph_sat_litinfo'(LitNum,Key,LastDepth,Atom,_,_,_), 8094 get_flatatom(Atom,TVSoFar,Lit,TV1), 8095 functor(Lit,Name,_), 8096 (Name = '='-> Length = 0; Length = 1). 8097get_pclause1([LitNum|LitNums],Key,TVSoFar,TV2,(Lit,Lits1),Length,LastDepth,M):- 8098 M:'$aleph_sat_litinfo'(LitNum,Key,_,Atom,_,_,_), 8099 get_flatatom(Atom,TVSoFar,Lit,TV1), 8100 get_pclause1(LitNums,Key,TV1,TV2,Lits1,Length1,LastDepth,M), 8101 functor(Lit,Name,_), 8102 (Name = '='-> Length = Length1; Length is Length1 + 1). 8103 8104 8105flatten_args(0,_,_,TV,TV):- !. 8106flatten_args(Arg,Atom,FAtom,TV,TV1):- 8107 arg(Arg,Atom,Term), 8108 Arg1 is Arg - 1, 8109 (Term = aleph_const(Const) -> 8110 arg(Arg,FAtom,Const), 8111 flatten_args(Arg1,Atom,FAtom,TV,TV1); 8112 (integer(Term) -> 8113 update(TV,Term/Var,TV0), 8114 arg(Arg,FAtom,Var), 8115 flatten_args(Arg1,Atom,FAtom,TV0,TV1); 8116 (functor(Term,Name,Arity), 8117 functor(FTerm,Name,Arity), 8118 arg(Arg,FAtom,FTerm), 8119 flatten_args(Arity,Term,FTerm,TV,TV0), 8120 flatten_args(Arg1,Atom,FAtom,TV0,TV1) 8121 ) 8122 ) 8123 ). 8124 8125 8126% returns intersection of S1, S2 and S1-Intersection 8127intersect1(Elems,[],[],Elems):- !. 8128intersect1([],_,[],[]):- !. 8129intersect1([Elem|Elems],S2,[Elem|Intersect],ElemsLeft):- 8130 aleph_member1(Elem,S2), !, 8131 intersect1(Elems,S2,Intersect,ElemsLeft). 8132intersect1([Elem|Elems],S2,Intersect,[Elem|ElemsLeft]):- 8133 intersect1(Elems,S2,Intersect,ElemsLeft). 8134 8135aleph_subset1([],_). 8136aleph_subset1([Elem|Elems],S):- 8137 aleph_member1(Elem,S), !, 8138 aleph_subset1(Elems,S). 8139 8140aleph_subset2([X|Rest],[X|S]):- 8141 aleph_subset2(Rest,S). 8142aleph_subset2(S,[_|S1]):- 8143 aleph_subset2(S,S1). 8144aleph_subset2([],[]). 8145 8146% two sets are equal 8147 8148equal_set([],[]). 8149equal_set([H|T],S):- 8150 aleph_delete1(H,S,S1), 8151 equal_set(T,S1), !. 8152 8153uniq_insert(_,X,[],[X]). 8154uniq_insert(descending,H,[H1|T],[H,H1|T]):- 8155 H @> H1, !. 8156uniq_insert(ascending,H,[H1|T],[H,H1|T]):- 8157 H @< H1, !. 8158uniq_insert(_,H,[H|T],[H|T]):- !. 8159uniq_insert(Order,H,[H1|T],[H1|T1]):- 8160 !, 8161 uniq_insert(Order,H,T,T1). 8162 8163quicksort(_,[],[]). 8164quicksort(Order,[X|Tail],Sorted):- 8165 partition(X,Tail,Small,Big), 8166 quicksort(Order,Small,SSmall), 8167 quicksort(Order,Big,SBig), 8168 (Order=ascending-> aleph_append([X|SBig],SSmall,Sorted); 8169 aleph_append([X|SSmall],SBig,Sorted)). 8170 8171partition(_,[],[],[]). 8172partition(X,[Y|Tail],[Y|Small],Big):- 8173 X @> Y, !, 8174 partition(X,Tail,Small,Big). 8175partition(X,[Y|Tail],Small,[Y|Big]):- 8176 partition(X,Tail,Small,Big). 8177 8178update_list([],L,L). 8179update_list([H|T],L,Updated):- 8180 update(L,H,L1), !, 8181 update_list(T,L1,Updated). 8182 8183update([],H,[H]). 8184update([H|T],H,[H|T]):- !. 8185update([H1|T],H,[H1|T1]):- 8186 update(T,H,T1). 8187 8188% checks if 2 sets intersect 8189intersects(S1,S2):- 8190 aleph_member(Elem,S1), aleph_member1(Elem,S2), !. 8191 8192% checks if bitsets represented as lists of intervals intersect 8193intervals_intersects([L1-L2|_],I):- 8194 intervals_intersects1(L1-L2,I), !. 8195intervals_intersects([_|I1],I):- 8196 intervals_intersects(I1,I). 8197 8198intervals_intersects1(L1-_,[M1-M2|_]):- 8199 L1 >= M1, L1 =< M2, !. 8200intervals_intersects1(L1-L2,[M1-_|_]):- 8201 M1 >= L1, M1 =< L2, !. 8202intervals_intersects1(L1-L2,[_|T]):- 8203 intervals_intersects1(L1-L2,T). 8204 8205% checks if bitsets represented as lists of intervals intersect 8206% returns first intersection 8207intervals_intersects([L1-L2|_],I,I1):- 8208 intervals_intersects1(L1-L2,I,I1), !. 8209intervals_intersects([_|ILeft],I,I1):- 8210 intervals_intersects(ILeft,I,I1). 8211 8212intervals_intersects1(I1,[I2|_],I):- 8213 interval_intersection(I1,I2,I), !. 8214intervals_intersects1(I1,[_|T],I):- 8215 intervals_intersects1(I1,T,I). 8216 8217interval_intersection(L1-L2,M1-M2,L1-L2):- 8218 L1 >= M1, L2 =< M2, !. 8219interval_intersection(L1-L2,M1-M2,M1-M2):- 8220 M1 >= L1, M2 =< L2, !. 8221interval_intersection(L1-L2,M1-M2,L1-M2):- 8222 L1 >= M1, M2 >= L1, M2 =< L2, !. 8223interval_intersection(L1-L2,M1-M2,M1-L2):- 8224 M1 >= L1, M1 =< L2, L2 =< M2, !. 8225 8226%most of the time no intersection, so optimise on that 8227% optimisation by James Cussens 8228intervals_intersection([],_,[]). 8229intervals_intersection([A-B|T1],[C-D|T2],X) :- 8230 !, 8231 (A > D -> 8232 intervals_intersection([A-B|T1],T2,X); 8233 (C > B -> 8234 intervals_intersection(T1,[C-D|T2],X); 8235 (B > D -> 8236 (C > A -> 8237 X=[C-D|Y]; 8238 X=[A-D|Y] 8239 ), 8240 intervals_intersection([A-B|T1],T2,Y); 8241 (C > A -> 8242 X=[C-B|Y]; 8243 X=[A-B|Y] 8244 ), 8245 intervals_intersection(T1,[C-D|T2],Y) 8246 ) 8247 ) 8248 ). 8249intervals_intersection(_,[],[]). 8250 8251 8252% finds length of intervals in a list 8253interval_count([],0). 8254interval_count([L1-L2|T],N):- 8255 N1 is L2 - L1 + 1, 8256 interval_count(T,N2), 8257 N is N1 + N2. 8258interval_count(I/_,N):- 8259 interval_count(I,N). 8260 8261% interval_select(+N,+List1,-Elem) 8262% select the Nth elem from an interval list 8263interval_select(N,[A-B|_],X):- 8264 N =< B - A + 1, !, 8265 X is A + N - 1. 8266interval_select(N,[A-B|T],X):- 8267 N1 is N - (B - A + 1), 8268 interval_select(N1,T,X). 8269 8270% interval_sample(+N,List1,-List2) 8271% get a random sample of N elements from List1 8272interval_sample(N,List1,List2):- 8273 intervals_to_list(List1,L1), 8274 aleph_rsample(N,L1,L2), 8275 list_to_intervals(L2,List2). 8276 8277% convert list to intervals 8278list_to_intervals(List,Intervals):- 8279 sort(List,List1), 8280 list_to_intervals1(List1,Intervals). 8281 8282list_to_intervals1([],[]). 8283list_to_intervals1([Start|T],[Start-Finish|I1]):- 8284 list_to_interval(Start,T,Finish,T1), 8285 list_to_intervals1(T1,I1). 8286 8287list_to_interval(Finish,[],Finish,[]). 8288list_to_interval(Finish,[Next|T],Finish,[Next|T]):- 8289 Next - Finish > 1, 8290 !. 8291list_to_interval(_,[Start|T],Finish,Rest):- 8292 list_to_interval(Start,T,Finish,Rest). 8293 8294% converts an interval-list into a list of (sorted) numbers 8295intervals_to_list(L,L1):- 8296 intervals_to_list(L,[],L0), 8297 sort(L0,L1), !. 8298 8299intervals_to_list([],L,L). 8300intervals_to_list([Interval|Intervals],L1,L2):- 8301 interval_to_list(Interval,L1,L), 8302 intervals_to_list(Intervals,L,L2). 8303 8304% converts an interval into a list 8305interval_to_list(Start-Finish,[]):- 8306 Start > Finish, !. 8307interval_to_list(Start-Finish,[Start|T]):- 8308 Start1 is Start+1, 8309 interval_to_list(Start1-Finish,T). 8310 8311% converts an interval into a list 8312% with an accumulator list. Result will be in reverse order 8313interval_to_list(Start-Finish,L,L):- 8314 Start > Finish, !. 8315interval_to_list(Start-Finish,L,L1):- 8316 Start1 is Start+1, 8317 interval_to_list(Start1-Finish,[Start|L],L1). 8318 8319% interval_subsumes(+I1,+I2) 8320% checks to see if interval I1 subsumes I2 8321interval_subsumes(Start1-Finish1,Start2-Finish2):- 8322 Start1 =< Start2, 8323 Finish1 >= Finish2. 8324 8325interval_subtract(Start1-Finish1,Start1-Finish1,[]):- !. 8326interval_subtract(Start1-Finish1,Start1-Finish2,[S2-Finish1]):- 8327 !, 8328 S2 is Finish2 + 1. 8329interval_subtract(Start1-Finish1,Start2-Finish1,[Start1-S1]):- 8330 !, 8331 S1 is Start2 - 1. 8332interval_subtract(Start1-Finish1,Start2-Finish2,[Start1-S1,S2-Finish1]):- 8333 S1 is Start2 - 1, 8334 S2 is Finish2 + 1, 8335 S1 >= Start1, Finish1 >= S2, !. 8336 8337 8338% code for set manipulation utilities 8339% taken from the Yap library 8340% aleph_ord_subtract(+Set1,+Set2,?Difference) 8341% is true when Difference contains all and only the elements of Set1 8342% which are not also in Set2. 8343aleph_ord_subtract(Set1,[],Set1) :- !. 8344aleph_ord_subtract([],_,[]) :- !. 8345aleph_ord_subtract([Head1|Tail1],[Head2|Tail2],Difference) :- 8346 compare(Order,Head1,Head2), 8347 aleph_ord_subtract(Order,Head1,Tail1,Head2,Tail2,Difference). 8348 8349aleph_ord_subtract(=,_, Tail1,_, Tail2,Difference) :- 8350 aleph_ord_subtract(Tail1,Tail2,Difference). 8351aleph_ord_subtract(<,Head1,Tail1,Head2,Tail2,[Head1|Difference]) :- 8352 aleph_ord_subtract(Tail1,[Head2|Tail2],Difference). 8353aleph_ord_subtract(>,Head1,Tail1,_, Tail2,Difference) :- 8354 aleph_ord_subtract([Head1|Tail1],Tail2,Difference). 8355 8356% aleph_ord_disjoint(+Set1,+Set2) 8357% is true when the two ordered sets have no element in common. If the 8358% arguments are not ordered,I have no idea what happens. 8359aleph_ord_disjoint([],_) :- !. 8360aleph_ord_disjoint(_,[]) :- !. 8361aleph_ord_disjoint([Head1|Tail1],[Head2|Tail2]) :- 8362 compare(Order,Head1,Head2), 8363 aleph_ord_disjoint(Order,Head1,Tail1,Head2,Tail2). 8364 8365aleph_ord_disjoint(<,_,Tail1,Head2,Tail2) :- 8366 aleph_ord_disjoint(Tail1,[Head2|Tail2]). 8367aleph_ord_disjoint(>,Head1,Tail1,_,Tail2) :- 8368 aleph_ord_disjoint([Head1|Tail1],Tail2). 8369 8370 8371% aleph_ord_union(+Set1,+Set2,?Union) 8372% is true when Union is the union of Set1 and Set2. Note that when 8373% something occurs in both sets,we want to retain only one copy. 8374aleph_ord_union(Set1,[],Set1) :- !. 8375aleph_ord_union([],Set2,Set2) :- !. 8376aleph_ord_union([Head1|Tail1],[Head2|Tail2],Union) :- 8377 compare(Order,Head1,Head2), 8378 aleph_ord_union(Order,Head1,Tail1,Head2,Tail2,Union). 8379 8380aleph_ord_union(=,Head, Tail1,_, Tail2,[Head|Union]) :- 8381 aleph_ord_union(Tail1,Tail2,Union). 8382aleph_ord_union(<,Head1,Tail1,Head2,Tail2,[Head1|Union]) :- 8383 aleph_ord_union(Tail1,[Head2|Tail2],Union). 8384aleph_ord_union(>,Head1,Tail1,Head2,Tail2,[Head2|Union]) :- 8385 aleph_ord_union([Head1|Tail1],Tail2,Union). 8386 8387% aleph_ord_union(+Set1,+Set2,?Union,?Difference) 8388% is true when Union is the union of Set1 and Set2 and Difference is the 8389% difference between Set2 and Set1. 8390aleph_ord_union(Set1,[],Set1,[]) :- !. 8391aleph_ord_union([],Set2,Set2,Set2) :- !. 8392aleph_ord_union([Head1|Tail1],[Head2|Tail2],Union,Diff) :- 8393 compare(Order,Head1,Head2), 8394 aleph_ord_union(Order,Head1,Tail1,Head2,Tail2,Union,Diff). 8395 8396aleph_ord_union(=,Head, Tail1,_, Tail2,[Head|Union],Diff) :- 8397 aleph_ord_union(Tail1,Tail2,Union,Diff). 8398aleph_ord_union(<,Head1,Tail1,Head2,Tail2,[Head1|Union],Diff) :- 8399 aleph_ord_union(Tail1,[Head2|Tail2],Union,Diff). 8400aleph_ord_union(>,Head1,Tail1,Head2,Tail2,[Head2|Union],[Head2|Diff]) :- 8401 aleph_ord_union([Head1|Tail1],Tail2,Union,Diff). 8402 8403aleph_ord_intersection(_,[],[]) :- !. 8404aleph_ord_intersection([],_,[]) :- !. 8405aleph_ord_intersection([Head1|Tail1],[Head2|Tail2],Intersection) :- 8406 compare(Order,Head1,Head2), 8407 aleph_ord_intersection(Order,Head1,Tail1,Head2,Tail2,Intersection). 8408 8409aleph_ord_intersection(=,Head,Tail1,_,Tail2,[Head|Intersection]) :- 8410 aleph_ord_intersection(Tail1,Tail2,Intersection). 8411aleph_ord_intersection(<,_,Tail1,Head2,Tail2,Intersection) :- 8412 aleph_ord_intersection(Tail1,[Head2|Tail2],Intersection). 8413aleph_ord_intersection(>,Head1,Tail1,_,Tail2,Intersection) :- 8414 aleph_ord_intersection([Head1|Tail1],Tail2,Intersection). 8415 8416aleph_ord_subset([], _) :- !. 8417aleph_ord_subset([Head1|Tail1], [Head2|Tail2]) :- 8418 compare(Order, Head1, Head2), 8419 aleph_ord_subset(Order, Head1, Tail1, Head2, Tail2). 8420 8421aleph_ord_subset(=, _, Tail1, _, Tail2) :- 8422 aleph_ord_subset(Tail1, Tail2). 8423aleph_ord_subset(>, Head1, Tail1, _, Tail2) :- 8424 aleph_ord_subset([Head1|Tail1], Tail2). 8425 8426vars_in_term([],Vars,Vars1):- sort(Vars,Vars1), !. 8427vars_in_term([Var|T],VarsSoFar,Vars):- 8428 var(Var), !, 8429 vars_in_term(T,[Var|VarsSoFar],Vars). 8430vars_in_term([Term|T],VarsSoFar,Vars):- 8431 Term =.. [_|Terms], !, 8432 vars_in_term(Terms,VarsSoFar,V1), 8433 vars_in_term(T,V1,Vars). 8434vars_in_term([_|T],VarsSoFar,Vars):- 8435 vars_in_term(T,VarsSoFar,Vars). 8436 8437occurs_in(Vars,(Lit,_)):- 8438 occurs_in(Vars,Lit), !. 8439occurs_in(Vars,(_,Lits)):- 8440 !, 8441 occurs_in(Vars,Lits). 8442occurs_in(Vars,Lit):- 8443 functor(Lit,_,Arity), 8444 occurs1(Vars,Lit,1,Arity). 8445 8446occurs1(Vars,Lit,Argno,MaxArgs):- 8447 Argno =< MaxArgs, 8448 arg(Argno,Lit,Term), 8449 vars_in_term([Term],[],Vars1), 8450 aleph_member(X,Vars), aleph_member(Y,Vars1), 8451 X == Y, !. 8452occurs1(Vars,Lit,Argno,MaxArgs):- 8453 Argno < MaxArgs, 8454 Next is Argno + 1, 8455 occurs1(Vars,Lit,Next,MaxArgs). 8456 8457 8458declare_dynamic(Name/Arity,M):- 8459 M:dynamic(Name/Arity). 8460 8461aleph_abolish(Name/Arity,M):- 8462 functor(Pred,Name,Arity), 8463 (predicate_property(M:Pred,dynamic) -> 8464 retractall(M:); 8465 abolish(M:Name/Arity)). 8466% AXO: Tolto perché infastidisce e non serve 8467aleph_open(File,read,Stream):- 8468 !, 8469 (exists(File) -> 8470 open(File,read,Stream); 8471 fail). 8472aleph_open(File,Mode,Stream):- 8473 open(File,Mode,Stream). 8474 8475clean_up(M):- 8476 clean_up_init(M), 8477 clean_up_sat(M), 8478 clean_up_reduce(M). 8479 8480clean_up_init(M):- 8481 aleph_abolish('$aleph_good'/3,M), 8482 retractall(M:'$aleph_search'(last_good,_)), 8483 aleph_abolish('$aleph_feature'/2,M). 8484 8485 8486clean_up_sat(M):- 8487 aleph_abolish('$aleph_sat'/2,M), 8488 aleph_abolish('$aleph_local'/2,M), 8489 aleph_abolish('$aleph_sat_atom'/2,M), 8490 aleph_abolish('$aleph_sat_ovars'/2,M), 8491 aleph_abolish('$aleph_sat_ivars'/2,M), 8492 aleph_abolish('$aleph_sat_varscopy'/3,M), 8493 aleph_abolish('$aleph_sat_varequiv'/3,M), 8494 aleph_abolish('$aleph_sat_terms'/4,M), 8495 aleph_abolish('$aleph_sat_vars'/4,M), 8496 aleph_abolish('$aleph_sat_litinfo'/6,M), 8497 retractall(M:'$aleph_search'(pclause,_)), 8498 garbage_collect. 8499 8500clean_up_reduce(M):- 8501 aleph_abolish('$aleph_local'/2,M), 8502 clean_up_search(M), 8503 retractall(M:'$aleph_search'(pclause,_)), 8504 garbage_collect. 8505 8506clean_up_search(M):- 8507 retractall(M:'$aleph_search'(bad,_)), 8508 retractall(M:'$aleph_search'(best,_)), 8509 retractall(M:'$aleph_search'(best_label,_)), 8510 retractall(M:'$aleph_search'(clauseprior,_)), 8511 retractall(M:'$aleph_search'(covers,_)), 8512 retractall(M:'$aleph_search'(coversn,_)), 8513 retractall(M:'$aleph_search'(current,_)), 8514 retractall(M:'$aleph_search'(label,_)), 8515 retractall(M:'$aleph_search'(modes,_)), 8516 retractall(M:'$aleph_search'(nextnode,_)), 8517 retractall(M:'$aleph_search'(openlist,_)), 8518 retractall(M:'$aleph_search'(pclause,_)), 8519 retractall(M:'$aleph_search'(selected,_)), 8520 retractall(M:'$aleph_search_seen'(_,_)), 8521 retractall(M:'$aleph_search_expansion'(_,_,_,_)), 8522 retractall(M:'$aleph_search_gain'(_,_,_,_)), 8523 retractall(M:'$aleph_search_node'(_,_,_,_,_,_,_,_)). 8524 8525 8526clean_up_examples(M):- 8527 clean_up_examples(pos,M), 8528 clean_up_examples(neg,M), 8529 clean_up_examples(rand,M). 8530 8531clean_up_tre(M):- 8532 retractall(M:'$aleph_search'(tree,_)), 8533 retractall(M:'$aleph_search'(tree_startdistribution,_)), 8534 retractall(M:'$aleph_search'(tree_leaf,_)), 8535 retractall(M:'$aleph_search'(tree_lastleaf,_)), 8536 retractall(M:'$aleph_search'(tree_newleaf,_)), 8537 retractall(M:'$aleph_search'(tree_besterror,_)), 8538 retractall(M:'$aleph_search'(tree_gain,_)). 8539 8540clean_up_examples(Type,M):- 8541 retractall(M:'$aleph_global'(size,size(Type,_))), 8542 retractall(M:'$aleph_global'(atoms,atoms(Type,_))), 8543 retractall(M:'$aleph_global'(atoms_left,atoms_left(Type,_))), 8544 retractall(M:'$aleph_global'(last_example,last_example(Type,_))). 8545 8546clean_up_hypothesis(M):- 8547 retractall(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))). 8548 8549depth_bound_call(G,M):- 8550 M:'$aleph_global'(depth,set(depth,D)), 8551 call_with_depth_bound(G,D,M). 8552 8553call_with_depth_bound((H:-B),D,M):- 8554 !, 8555 call_with_depth_bound((H,B),D,M). 8556call_with_depth_bound((A,B),D,M):- 8557 !, 8558 depth_bound_call(A,D,M), 8559 call_with_depth_bound(B,D,M). 8560call_with_depth_bound(A,D,M):- 8561 depth_bound_call(A,D,M). 8562 8563binom_lte(_,_,O,0.0):- O < 0, !. 8564binom_lte(N,P,O,Prob):- 8565 binom(N,P,O,Prob1), 8566 O1 is O - 1, 8567 binom_lte(N,P,O1,Prob2), 8568 Prob is Prob1 + Prob2, !. 8569 8570binom(N,_,O,0.0):- O > N, !. 8571binom(N,P,O,Prob):- 8572 aleph_choose(N,O,C), 8573 E1 is P^O, 8574 P2 is 1 - P, 8575 O2 is N - O, 8576 E2 is P2^O2, 8577 Prob is C*E1*E2, !. 8578 8579aleph_choose(N,I,V):- 8580 NI is N-I, 8581 (NI > I -> pfac(N,NI,I,V) ; pfac(N,I,NI,V)). 8582 8583pfac(0,_,_,1). 8584pfac(1,_,_,1). 8585pfac(N,N,_,1). 8586pfac(N,I,C,F):- 8587 N1 is N-1, 8588 C1 is C-1, 8589 pfac(N1,I,C1,N1F), 8590 F1 is N/C, 8591 F is N1F*F1. 8592 8593% record_example(+Check,+Type,+Example,-N) 8594% records Example of type Type 8595% if Check = check, then checks to see if example exists 8596% also updates number of related databases accordingly 8597% if Check = nocheck then no check is done 8598% returns example number N and Flag 8599% if Flag = new then example is a new example of Type 8600record_example(check,Type,Example,N1,M):- 8601 (once(M:example(N1,Type,Example)) -> true; 8602 record_example(nocheck,Type,Example,N1,M), 8603 (retract(M:'$aleph_global'(atoms,atoms(Type,Atoms))) -> 8604 true; 8605 Atoms = []), 8606 (retract(M:'$aleph_global'(atoms_left,atoms_left(Type,AtomsLeft)))-> 8607 true; 8608 AtomsLeft = []), 8609 (retract(M:'$aleph_global'(last_example,last_example(Type,_))) -> 8610 true; 8611 true), 8612 update(Atoms,N1-N1,NewAtoms), 8613 update(AtomsLeft,N1-N1,NewAtomsLeft), 8614 asserta(M:'$aleph_global'(atoms,atoms(Type,NewAtoms))), 8615 asserta(M:'$aleph_global'(atoms_left,atoms_left(Type, 8616 NewAtomsLeft))), 8617 asserta(M:'$aleph_global'(last_example,last_example(Type,N1)))), 8618 !. 8619record_example(nocheck,Type,Example,N1,M):- 8620 (retract(M:'$aleph_global'(size,size(Type,N)))-> 8621 true; 8622 N is 0), 8623 N1 is N + 1, 8624 asserta(M:'$aleph_global'(size,size(Type,N1))), 8625 (Type \= neg -> 8626 setting(skolemvars,Sk1,M), 8627 skolemize(Example,Fact,Body,Sk1,SkolemVars), 8628 record_skolemized(Type,N1,SkolemVars,Fact,Body,M), 8629 (Sk1 = SkolemVars -> true; 8630 set(skolemvars,SkolemVars,M)); 8631 split_clause(Example,Head,Body), 8632 record_nskolemized(Type,N1,Head,Body,M)), !. 8633 8634 8635record_targetpred(M):- 8636 retract(M:'$aleph_local'(backpred,Name/Arity)), 8637 once(M:'$aleph_global'(determination,determination(Name/Arity,_))), 8638 asserta(M:'$aleph_global'(targetpred,targetpred(Name/Arity))), 8639 record_testclause(Name/Arity,M), 8640 fail. 8641record_targetpred(_M). 8642 8643check_recursive_calls(M):- 8644 M:'$aleph_global'(targetpred,targetpred(Name/Arity)), 8645 M:'$aleph_global'(determination,determination(Name/Arity,Name/Arity)), 8646 record_recursive_sat_call(Name/Arity,M), 8647 set(recursion,true,M), 8648 fail. 8649check_recursive_calls(_M). 8650 8651check_posonly(M):- 8652 M:'$aleph_global'(size,size(rand,N)), 8653 N > 0, !. 8654check_posonly(M):- 8655 setting(evalfn,posonly,M), 8656 \+(M:'$aleph_global'(modeh,modeh(_,_))), 8657 p1_message('error'), 8658 p_message('missing modeh declaration in posonly mode'), !, 8659 fail. 8660check_posonly(M):- 8661 retractall(M:'$aleph_global'(slp_count,_,_)), 8662 retractall(M:'$aleph_local'(slp_sample,_)), 8663 retractall(M:'$aleph_local'(slp_samplenum,_)), 8664 setting(evalfn,posonly,M), 8665 setting(gsamplesize,S,M), 8666 condition_target(M), 8667 M:'$aleph_global'(targetpred,targetpred(Name/Arity)), 8668 gsample(Name/Arity,S,M), !. 8669check_posonly(_M). 8670 8671check_prune_defs(M):- 8672 clause(M:prune(_),_), !, 8673 set(prune_defs,true,M). 8674check_prune_defs(_M). 8675 8676check_auto_refine(M):- 8677 (setting(construct_bottom,reduction,M);setting(construct_bottom,false,M)), 8678 \+(setting(autorefine,true,M)), !, 8679 (setting(refine,user,M) -> true; set(refine,auto,M)). 8680check_auto_refine(_M). 8681 8682check_user_search(M):- 8683 setting(evalfn,user,M), 8684 \+(cost_cover_required(M)), 8685 set(lazy_on_cost,true,M), !. 8686check_user_search(_M). 8687 8688check_abducibles(M):- 8689 M:'$aleph_global'(abducible,abducible(Name/Arity)), 8690 record_testclause(Name/Arity,M), 8691 record_abclause(Name/Arity,M), 8692 fail. 8693check_abducibles(_M). 8694 8695cost_cover_required(M):- 8696 clause(M:cost(_,Label,Cost),Body), 8697 vars_in_term([Label],[],Vars), 8698 (occurs_in(Vars,p(Cost)); occurs_in(Vars,Body)), !. 8699 8700set_lazy_recalls(M):- 8701 M:'$aleph_global'(lazy_evaluate,lazy_evaluate(Name/Arity)), 8702 functor(Pred,Name,Arity), 8703 % asserta('$aleph_global'(lazy_recall,lazy_recall(Name/Arity,1))), 8704 asserta(M:'$aleph_global'(lazy_recall,lazy_recall(Name/Arity,0))), 8705 M:'$aleph_global'(mode,mode(Recall,Pred)), 8706 M:'$aleph_global'(lazy_recall,lazy_recall(Name/Arity,N)), 8707 (Recall = '*' -> RecallNum = 100; RecallNum = Recall), 8708 RecallNum > N, 8709 retract(M:'$aleph_global'(lazy_recall,lazy_recall(Name/Arity,N))), 8710 asserta(M:'$aleph_global'(lazy_recall,lazy_recall(Name/Arity,RecallNum))), 8711 fail. 8712set_lazy_recalls(_M). 8713 8714set_lazy_on_contradiction(_,_,M):- 8715 M:'$aleph_global'(lazy_on_contradiction,set(lazy_on_contradiction,false)), !. 8716set_lazy_on_contradiction(P,N,M):- 8717 Tot is P + N, 8718 Tot >= 100, !, 8719 set(lazy_on_contradiction,true,M). 8720set_lazy_on_contradiction(_,_,_M). 8721 8722% The "pclause" trick: much more effective with the use of recorded/3 8723% clause for testing partial clauses obtained in search 8724% only needed when learning recursive theories or 8725% proof_strategy is not restricted_sld. 8726record_testclause(Name/Arity,M):- 8727 functor(Head,Name,Arity), 8728 Clause = (Head:- 8729 '$aleph_search'(pclause,pclause(Head,Body)), 8730 Body, !), 8731 assertz(M:). 8732 8733% The "pclause" trick for abducible predicates 8734record_abclause(Name/Arity,M):- 8735 functor(Head,Name,Arity), 8736 Clause = (Head:- 8737 '$aleph_search'(abduced,pclause(Head,Body)), 8738 Body, !), 8739 assertz(M:). 8740 8741% clause for incorporating recursive calls into bottom clause 8742% this is done by allowing calls to the positive examples 8743record_recursive_sat_call(Name/Arity,M):- 8744 functor(Head,Name,Arity), 8745 Clause = (Head:- 8746 '$aleph_global'(stage,set(stage,saturation)), 8747 '$aleph_sat'(example,example(Num,Type)), 8748 example(Num1,Type,Head), 8749 Num1 \= Num, !), % to prevent tautologies 8750 assertz(M:). 8751 8752skolemize((Head:-Body),SHead,SBody,Start,SkolemVars):- 8753 !, 8754 copy_term((Head:-Body),(SHead:-Body1)), 8755 numbervars((SHead:-Body1),Start,SkolemVars), 8756 goals_to_list(Body1,SBody). 8757skolemize(UnitClause,Lit,[],Start,SkolemVars):- 8758 copy_term(UnitClause,Lit), 8759 numbervars(Lit,Start,SkolemVars). 8760skolemize(UnitClause,Lit):- 8761 skolemize(UnitClause,Lit,[],0,_). 8762 8763record_nskolemized(Type,N1,Head,true,M):- 8764 !, 8765 assertz(M:example(N1,Type,Head)). 8766record_nskolemized(Type,N1,Head,Body,M):- 8767 assertz(M:(example(N1,Type,Head):-Body)). 8768 8769record_skolemized(Type,N1,SkolemVars,Head,Body,M):- 8770 assertz(M:example(N1,Type,Head)), 8771 functor(Head,Name,Arity), 8772 update_backpreds(Name/Arity,M), 8773 add_backs(Body,M), 8774 add_skolem_types(SkolemVars,Head,Body,M). 8775 8776add_backs([],_M). 8777add_backs([Lit|Lits],M):- 8778 asserta(M:'$aleph_global'(back,back(Lit))), 8779 functor(Lit,Name,Arity), 8780 declare_dynamic(Name/Arity,M), 8781 assertz(M:), 8782 add_backs(Lits,M). 8783 8784add_skolem_types(10000,_,_,_M):- !. % no new skolem variables 8785add_skolem_types(_,Head,Body,M):- 8786 add_skolem_types([Head],M), 8787 add_skolem_types(Body,M). 8788 8789add_skolem_types([],_M). 8790add_skolem_types([Lit|Lits],M):- 8791 functor(Lit,PSym,Arity), 8792 get_modes(PSym/Arity,L,M), 8793 add_skolem_types1(L,Lit,M), 8794 add_skolem_types(Lits,M). 8795 8796add_skolem_types1([],_,_M). 8797add_skolem_types1([Lit|Lits],Fact,M):- 8798 split_args(Lit,_,I,O,C,M), 8799 add_skolem_types2(I,Fact,M), 8800 add_skolem_types2(O,Fact,M), 8801 add_skolem_types2(C,Fact,M), 8802 add_skolem_types1(Lits,Fact,M). 8803 8804add_skolem_types2([],_,_M). 8805add_skolem_types2([Pos/Type|Rest],Literal,M):- 8806 tparg(Pos,Literal,Arg), 8807 SkolemType =.. [Type,Arg], 8808 (M:'$aleph_global'(back,back(SkolemType))-> true; 8809 asserta(M:'$aleph_global'(back,back(SkolemType))), 8810 asserta(M:)), 8811 add_skolem_types2(Rest,Literal,M). 8812 8813 8814copy_args(_,_,Arg,Arity):- 8815 Arg > Arity, !. 8816copy_args(Lit,Lit1,Arg,Arity):- 8817 arg(Arg,Lit,T), 8818 arg(Arg,Lit1,T), 8819 NextArg is Arg + 1, 8820 copy_args(Lit,Lit1,NextArg,Arity). 8821 8822copy_iargs(0,_,_,_):- !. 8823copy_iargs(Arg,Old,New,Arg):- 8824 !, 8825 Arg1 is Arg - 1, 8826 copy_iargs(Arg1,Old,New,Arg). 8827copy_iargs(Arg,Old,New,Out):- 8828 arg(Arg,Old,Val), 8829 arg(Arg,New,Val), 8830 Arg1 is Arg - 1, 8831 copy_iargs(Arg1,Old,New,Out). 8832 8833 8834index_clause((Head:-true),NextClause,(Head),M):- 8835 !, 8836 retract(M:'$aleph_global'(last_clause,last_clause(ClauseNum))), 8837 NextClause is ClauseNum + 1, 8838 asserta(M:'$aleph_global'(last_clause,last_clause(NextClause))). 8839index_clause(Clause,NextClause,Clause,M):- 8840 retract(M:'$aleph_global'(last_clause,last_clause(ClauseNum))), 8841 NextClause is ClauseNum + 1, 8842 asserta(M:'$aleph_global'(last_clause,last_clause(NextClause))). 8843 8844update_backpreds(Name/Arity,M):- 8845 M:'$aleph_local'(backpred,Name/Arity), !. 8846update_backpreds(Name/Arity,M):- 8847 assertz(M:'$aleph_local'(backpred,Name/Arity)). 8848 8849reset_counts(M):- 8850 retractall(M:'$aleph_sat'(lastterm,_)), 8851 retractall(M:'$aleph_sat'(lastvar,_)), 8852 asserta(M:'$aleph_sat'(lastterm,0)), 8853 asserta(M:'$aleph_sat'(lastvar,0)), !. 8854 8855% reset the number of successes for a literal: cut to avoid useless backtrack 8856reset_succ(M):- 8857 retractall(M:'$aleph_local'(last_success,_)), 8858 asserta(M:'$aleph_local'(last_success,0)), !. 8859 8860skolem_var(Var,_M):- 8861 atomic(Var), !, 8862 name(Var,[36|_]). 8863skolem_var(Var,M):- 8864 gen_var(Num,M), 8865 name(Num,L), 8866 name(Var,[36|L]). 8867 8868gen_var(Var1,M):- 8869 retract(M:'$aleph_sat'(lastvar,Var0)), !, 8870 Var1 is Var0 + 1, 8871 asserta(M:'$aleph_sat'(lastvar,Var1)). 8872gen_var(0,M):- 8873 asserta(M:'$aleph_sat'(lastvar,0)). 8874 8875copy_var(OldVar,NewVar,Depth,M):- 8876 gen_var(NewVar,M), 8877 M:'$aleph_sat_vars'(OldVar,TNo,_,_), 8878 asserta(M:'$aleph_sat_vars'(NewVar,TNo,[],[])), 8879 asserta(M:'$aleph_sat_varscopy'(NewVar,OldVar,Depth)). 8880 8881gen_litnum(Lit1,M):- 8882 retract(M:'$aleph_sat'(lastlit,Lit0)), !, 8883 Lit1 is Lit0 + 1, 8884 asserta(M:'$aleph_sat'(lastlit,Lit1)). 8885gen_litnum(0,M):- 8886 asserta(M:'$aleph_sat'(lastlit,0)). 8887 8888gen_nlitnum(Lit1,M):- 8889 retract(M:'$aleph_sat'(lastnlit,Lit0)), !, 8890 Lit1 is Lit0 - 1, 8891 asserta(M:'$aleph_sat'(lastnlit,Lit1)). 8892gen_nlitnum(-1,M):- 8893 asserta(M:'$aleph_sat'(lastnlit,-1)). 8894 8895% generate a new feature number 8896% provided it is less than the maximum number of features allowed 8897gen_featurenum(Feature1,M):- 8898 M:'$aleph_feature'(last_feature,Feature0), !, 8899 Feature1 is Feature0 + 1, 8900 setting(max_features,FMax,M), 8901 Feature1 =< FMax, 8902 retract(M:'$aleph_feature'(last_feature,Feature0)), 8903 asserta(M:'$aleph_feature'(last_feature,Feature1)). 8904gen_featurenum(1,M):- 8905 asserta(M:'$aleph_feature'(last_feature,1)). 8906 8907gen_lits([],[],_M). 8908gen_lits([Lit|Lits],[LitNum|Nums],M):- 8909 gen_litnum(LitNum,M), 8910 asserta(M:'$aleph_sat_litinfo'(LitNum,0,Lit,[],[],[])), 8911 gen_lits(Lits,Nums,M). 8912 8913update_theory(ClauseIndex,M):- 8914 retract(M:'$aleph_global'(hypothesis,hypothesis(OldLabel,Hypothesis, 8915 OldPCover,OldNCover))), 8916 index_clause(Hypothesis,ClauseIndex,Clause,M), 8917 (M:'$aleph_global'(example_selected,example_selected(_,Seed))-> true; 8918 PCover = [Seed-_|_]), 8919 (setting(lazy_on_cost,true,M) -> 8920 nlits(Clause,L), 8921 label_create(Clause,Label,M), 8922 extract_pos(Label,PCover), 8923 extract_neg(Label,NCover), 8924 interval_count(PCover,PC), 8925 interval_count(NCover,NC), 8926 setting(evalfn,Evalfn,M), 8927 complete_label(Evalfn,Clause,[PC,NC,L],NewLabel,M), 8928 assertz(M:'$aleph_global'(theory,theory(ClauseIndex, 8929 NewLabel/Seed,Clause, 8930 PCover,NCover))); 8931 assertz(M:'$aleph_global'(theory,theory(ClauseIndex, 8932 OldLabel/Seed,Clause, 8933 OldPCover,OldNCover)))), 8934 add_clause_to_background(ClauseIndex,M). 8935 8936add_clause_to_background(ClauseIndex,M):- 8937 M:'$aleph_global'(theory,theory(ClauseIndex,Label/_,Clause,_,_)), 8938 (setting(minpos,PMin,M) -> true; PMin = 1), 8939 Label = [PC,_,_,F|_], 8940 PC >= PMin, 8941 setting(minscore,MinScore,M), 8942 F >= MinScore, !, 8943 (retract(M:'$aleph_global'(rules,rules(Rules)))-> 8944 asserta(M:'$aleph_global'(rules,rules([ClauseIndex|Rules]))); 8945 asserta(M:'$aleph_global'(rules,rules([ClauseIndex])))), 8946 (setting(updateback,Update,M) -> true; Update = true), 8947 (Update = true -> assertz(M:); true), !. 8948add_clause_to_background(_,_M). 8949 8950 8951rm_seeds(M):- 8952 update_theory(ClauseIndex,M), !, 8953 M:'$aleph_global'(theory,theory(ClauseIndex,_,_,PCover,NCover)), 8954 rm_seeds(pos,PCover,M), 8955 (setting(evalfn,posonly,M) -> rm_seeds(rand,NCover,M); true), 8956 M:'$aleph_global'(atoms_left,atoms_left(pos,PLeft)), 8957 interval_count(PLeft,PL), 8958 p1_message('atoms left'), p_message(PL), 8959 !. 8960rm_seeds(_M). 8961 8962rm_seeds(pos,PCover,M):- 8963 setting(construct_features,true,M), 8964 setting(feature_construction,exhaustive,M), !, 8965 retract(M:'$aleph_global'(atoms_left,atoms_left(pos,OldIntervals))), 8966 (M:'$aleph_global'(example_selected,example_selected(_,Seed))-> true; 8967 PCover = [Seed-_|_]), 8968 rm_seeds1([Seed-Seed],OldIntervals,NewIntervals), 8969 assertz(M:'$aleph_global'(atoms_left,atoms_left(pos,NewIntervals))). 8970rm_seeds(Type,RmIntervals,M) :- 8971 retract(M:'$aleph_global'(atoms_left,atoms_left(Type,OldIntervals))), 8972 rm_seeds1(RmIntervals,OldIntervals,NewIntervals), 8973 assertz(M:'$aleph_global'(atoms_left,atoms_left(Type,NewIntervals))). 8974 8975rm_seeds1([],Done,Done). 8976rm_seeds1([Start-Finish|Rest],OldIntervals,NewIntervals) :- 8977 rm_interval(Start-Finish,OldIntervals,MidIntervals),!, 8978 rm_seeds1(Rest,MidIntervals,NewIntervals). 8979 8980% update lower estimate on maximum size cover set for an atom 8981update_coverset(Type,_,M):- 8982 M:'$aleph_global'(hypothesis,hypothesis(Label,_,PCover,_)), 8983 Label = [_,_,_,GainE|_], 8984 arithmetic_expression_value(GainE,Gain), 8985 worse_coversets(PCover,Type,Gain,Worse,M), 8986 (Worse = [] -> true; 8987 update_theory(NewClause,M), 8988 update_coversets(Worse,NewClause,Type,Label,M)). 8989 8990% revise coversets of previous atoms 8991worse_coversets(_,_,_,[],M):- 8992 \+(M:'$aleph_global'(maxcover,set(maxcover,true))), !. 8993worse_coversets([],_,_,[],_M). 8994worse_coversets([Interval|Intervals],Type,Gain,Worse,M):- 8995 worse_coversets1(Interval,Type,Gain,W1,M), 8996 worse_coversets(Intervals,Type,Gain,W2,M), 8997 aleph_append(W2,W1,Worse), !. 8998 8999worse_coversets1(Start-Finish,_,_,[],_M):- 9000 Start > Finish, !. 9001worse_coversets1(Start-Finish,Type,Gain,Rest,M):- 9002 M:'$aleph_global'(max_set,max_set(Type,Start,Label1,_)), 9003 Label1 = [_,_,_,Gain1E|_], 9004 arithmetic_expression_value(Gain1E,Gain1), 9005 Gain1 >= Gain, !, 9006 Next is Start + 1, 9007 worse_coversets1(Next-Finish,Type,Gain,Rest,M), !. 9008worse_coversets1(Start-Finish,Type,Gain,[Start|Rest],M):- 9009 Next is Start + 1, 9010 worse_coversets1(Next-Finish,Type,Gain,Rest,M), !. 9011 9012update_coversets([],_,_,_,_M). 9013update_coversets([Atom|Atoms],ClauseNum,Type,Label,M):- 9014 (retract(M:'$aleph_global'(max_set,max_set(Type,Atom,_,_)))-> 9015 true; 9016 true), 9017 asserta(M:'$aleph_global'(max_set,max_set(Type,Atom,Label,ClauseNum))), 9018 update_coversets(Atoms,ClauseNum,Type,Label,M), !. 9019 9020rm_intervals([],I,I). 9021rm_intervals([I1|I],Intervals,Result):- 9022 rm_interval(I1,Intervals,Intervals1), 9023 rm_intervals(I,Intervals1,Result), !. 9024 9025rm_interval(_,[],[]). 9026rm_interval(I1,[Interval|Rest],Intervals):- 9027 interval_intersection(I1,Interval,I2), !, 9028 interval_subtract(Interval,I2,I3), 9029 rm_interval(I1,Rest,I4), 9030 aleph_append(I4,I3,Intervals). 9031rm_interval(I1,[Interval|Rest],[Interval|Intervals]):- 9032 rm_interval(I1,Rest,Intervals). 9033 9034% gen_sample(+Type,+N,M) 9035% select N random samples from the set of examples uncovered. Type is one of pos/neg 9036% if N = 0 returns first example in Set 9037% resamples the same example R times where set(resample,R) 9038gen_sample(Type,0,M):- 9039 !, 9040 M:'$aleph_global'(atoms_left,atoms_left(Type,[ExampleNum-_|_])), 9041 retractall(M:'$aleph_global'(example_selected,example_selected(_,_))), 9042 p1_message('select example'), p_message(ExampleNum), 9043 (setting(resample,Resample,M) -> true; Resample = 1), 9044 gen_sample(Resample,Type,ExampleNum,M). 9045gen_sample(Type,SampleSize,M):- 9046 M:'$aleph_global'(atoms_left,atoms_left(Type,Intervals)), 9047 % p1_message('select from'), p_message(Intervals), 9048 interval_count(Intervals,AtomsLeft), 9049 N is min(AtomsLeft,SampleSize), 9050 assertz(M:'$aleph_local'(sample_num,0)), 9051 retractall(M:'$aleph_global'(example_selected,example_selected(_,_))), 9052 (setting(resample,Resample,M) -> true; Resample = 1), 9053 repeat, 9054 M:'$aleph_local'(sample_num,S1), 9055 S is S1 + 1, 9056 (S =< N -> 9057 get_random(AtomsLeft,INum), 9058 select_example(INum,0,Intervals,ExampleNum), 9059 \+(M:'$aleph_global'(example_selected, 9060 example_selected(Type,ExampleNum))), 9061 p1_message('select example'), p_message(ExampleNum), 9062 retract(M:'$aleph_local'(sample_num,S1)), 9063 assertz(M:'$aleph_local'(sample_num,S)), 9064 gen_sample(Resample,Type,ExampleNum,M), 9065 fail; 9066 retract(M:'$aleph_local'(sample_num,S1))), !. 9067 9068gen_sample(0,_,_,_M):- !. 9069gen_sample(R,Type,ExampleNum,M):- 9070 assertz(M:'$aleph_global'(example_selected, 9071 example_selected(Type,ExampleNum))), 9072 R1 is R - 1, 9073 gen_sample(R1,Type,ExampleNum,M). 9074 9075select_example(Num,NumberSoFar,[Start-Finish|_],ExampleNum):- 9076 Num =< NumberSoFar + Finish - Start + 1, !, 9077 ExampleNum is Num - NumberSoFar + Start - 1. 9078select_example(Num,NumberSoFar,[Start-Finish|Rest],ExampleNum):- 9079 N1 is NumberSoFar + Finish - Start + 1, 9080 select_example(Num,N1,Rest,ExampleNum). 9081 9082% get_random(+Last,-Num) 9083% get a random integer between 1 and Last 9084get_random(Last,INum):- 9085 aleph_random(X), 9086 INum1 is integer(X*Last + 0.5), 9087 (INum1 = 0 -> 9088 INum = 1; 9089 (INum1 > Last -> 9090 INum = Last; 9091 INum = INum1 9092 ) 9093 ). 9094 9095% get_rrandom(+Last,-Num) 9096% get a random floating point number between 1 and Last 9097get_rrandom(Last,Num):- 9098 aleph_random(X), 9099 Num is X*Last. 9100 9101% distrib(+Interval,+Prob,-Distrib) 9102% generate discrete distribution Distrib 9103% by assigning all elements in Interval the probability Prob 9104distrib(X-Y,_,[]):- X > Y, !. 9105distrib(X-Y,P,[P-X|D]):- 9106 X1 is X + 1, 9107 distrib(X1-Y,P,D). 9108 9109% draw_element(+D,-E) 9110% draw element E using distribution D 9111% D is a list specifying the probability of each element E 9112% in the form p1-e1, p2-e2, ... ,pn-en 9113% proportions pi are normalised to add to 1 9114draw_element(D,E):- 9115 normalise_distribution(D,Distr), 9116 aleph_random(X), 9117 draw_element(Distr,0,X,E). 9118 9119draw_element([P1-E1|T],CumProb,X,E):- 9120 CumProb1 is CumProb + P1, 9121 (X =< CumProb1 -> E = E1; 9122 draw_element(T,CumProb1,X,E)). 9123 9124normalise_distribution(D,Distr):- 9125 key_sum(D,Sum), 9126 (0.0 is float(Sum) -> Distr = D; 9127 normalise_distribution(D,Sum,D1), 9128 keysort(D1,Distr)). 9129 9130key_sum([],0.0). 9131key_sum([K1-_|T],Sum):- 9132 key_sum(T,S1), 9133 Sum is float(K1 + S1). 9134 9135normalise_distribution([],_,[]). 9136normalise_distribution([K1-X1|T],Sum,[K2-X1|T1]):- 9137 K2 is K1/Sum, 9138 normalise_distribution(T,Sum,T1). 9139 9140% random_select(-Num,+List1,-List2) 9141% randomly remove an element Num from List1 to give List2 9142random_select(X,[X],[]):- !. 9143random_select(X,L,Left):- 9144 length(L,N), 9145 N > 0, 9146 get_random(N,I), 9147 aleph_remove_nth(I,L,X,Left). 9148 9149% random_nselect(+Num,+List1,-List2) 9150% randomly remove Num elements from List1 to give List2 9151random_nselect(0,_,[]):- !. 9152random_nselect(_,[],[]):- !. 9153random_nselect(N,List1,[X|List2]):- 9154 random_select(X,List1,Left), 9155 N1 is N - 1, 9156 random_nselect(N1,Left,List2). 9157 9158% random_select_from_intervals(-Num,+IList) 9159% randomly select an element from an interval list 9160random_select_from_intervals(N,IList):- 9161 interval_count(IList,L), 9162 get_random(L,X), 9163 interval_select(X,IList,N). 9164 9165 9166normal(Mean,Sigma,X):- 9167 std_normal(X1), 9168 X is Mean + Sigma*X1. 9169 9170get_normal(0,_,_,[]):- !. 9171get_normal(N,Mean,Sigma,[X|Xs]):- 9172 N > 0, 9173 normal(Mean,Sigma,X), 9174 N1 is N - 1, 9175 get_normal(N1,Mean,Sigma,Xs). 9176 9177% Polar method for generating random variates 9178% from a standard normal distribution. 9179% From A.M. Law and W.D. Kelton, "Simulation Modeling and Analysis", 9180% McGraw-Hill,2000 9181std_normal(X):- 9182 aleph_random(U1), 9183 aleph_random(U2), 9184 V1 is 2*U1 - 1, 9185 V2 is 2*U2 - 1, 9186 W is V1^2 + V2^2, 9187 (W > 1 -> std_normal(X); 9188 Y is sqrt((-2.0*log(W))/W), 9189 X is V1*Y). 9190 9191% Approximate method for computing the chi-square value 9192% given the d.f. and probability (to the right). Uses 9193% a normal approximation and Monte-Carlo simulation. 9194% The normal approximation used is the one proposed by 9195% E.B. Wilson and M.M. Hilferty (1931). "The distribution of chi-square" 9196% PNAS, 17, 684. 9197% Monte-Carlo simulation uses 1000 trials. 9198chi_square(DF,Prob,ChisqVal):- 9199 DF > 0, 9200 Mean is 1 - 2/(9*DF), 9201 Sigma is sqrt(2/(9*DF)), 9202 NTrials is 1000, 9203 get_normal(NTrials,Mean,Sigma,X), 9204 sort(X,Z), 9205 ProbLeft is 1.0 - Prob, 9206 Index is integer(ProbLeft*NTrials), 9207 (Index > NTrials -> 9208 aleph_remove_nth(NTrials,Z,Val,_); 9209 aleph_remove_nth(Index,Z,Val,_)), 9210 ChisqVal is DF*(Val^3). 9211 9212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9213% L A B E L S A N D E V A L F N S 9214% 9215 9216label_create(Clause,Label,M):- 9217 M:'$aleph_global'(last_example,last_example(pos,Last1)), 9218 Type1 = pos, 9219 (setting(evalfn,posonly,M) -> 9220 M:'$aleph_global'(last_example,last_example(rand,Last2)), 9221 Type2 = rand; 9222 M:'$aleph_global'(last_example,last_example(neg,Last2)), 9223 Type2 = neg), 9224 label_create(Clause,Type1,[1-Last1],Type2,[1-Last2],Label,M). 9225 9226label_create(Type,Clause,Label,M):- 9227 M:'$aleph_global'(last_example,last_example(Type,Last)), 9228 label_create(Clause,Type,[1-Last],Label,M). 9229 9230label_create(Clause,Type1,Set1,Type2,Set2,Label,M):- 9231 split_clause(Clause,Head,Body), 9232 nlits((Head,Body),Length), 9233 assertz(M:'$aleph_search'(pclause,pclause(Head,Body))), 9234 setting(depth,Depth,M), 9235 setting(prooftime,Time,M), 9236 setting(proof_strategy,Proof,M), 9237 prove(Depth/Time/Proof,Type1,(Head:-Body),Set1,Cover1,_,M), 9238 prove(Depth/Time/Proof,Type2,(Head:-Body),Set2,Cover2,_,M), 9239 retractall(M:'$aleph_search'(pclause,_)), 9240 assemble_label(Cover1,Cover2,Length,Label), !. 9241 9242label_create(Clause,Type,Set,Label,M):- 9243 split_clause(Clause,Head,Body), 9244 assertz(M:'$aleph_search'(pclause,pclause(Head,Body))), 9245 setting(depth,Depth,M), 9246 setting(prooftime,Time,M), 9247 setting(proof_strategy,Proof,M), 9248 prove(Depth/Time/Proof,Type,(Head:-Body,M),Set,Cover,_,M), 9249 retractall(M:'$aleph_search'(pclause,_)), 9250 (Type = pos -> 9251 assemble_label(Cover,unknown,unknown,Label); 9252 assemble_label(unknown,Cover,unknown,Label)). 9253 9254label_pcover(Label,P):- 9255 extract_cover(pos,Label,P). 9256label_ncover(Label,N):- 9257 extract_cover(neg,Label,N). 9258 9259label_union([],Label,Label):- !. 9260label_union(Label,[],Label):- !. 9261label_union(Label1,Label2,Label):- 9262 extract_cover(pos,Label1,Pos1), 9263 extract_cover(pos,Label2,Pos2), 9264 extract_cover(neg,Label1,Neg1), 9265 extract_cover(neg,Label2,Neg2), 9266 extract_length(Label1,L1), 9267 extract_length(Label2,L2), 9268 update_list(Pos2,Pos1,Pos), 9269 update_list(Neg2,Neg1,Neg), 9270 Length is L1 + L2, 9271 list_to_intervals(Pos,PCover), 9272 list_to_intervals(Neg,NCover), 9273 assemble_label(PCover,NCover,Length,Label). 9274 9275label_print_examples(Type,Label,M):- 9276 extract_cover(Type,Label,C), 9277 examples(Type,C,M). 9278 9279label_print_eval([],_M):- !. 9280label_print_eval(Label,M):- 9281 Eval = coverage, 9282 evalfn(Eval,Label,Val,M), 9283 print_eval(Eval,Val). 9284 9285print_eval(Evalfn,Val):- 9286 evalfn_name(Evalfn,Name), 9287 p1_message(Name), p_message(Val). 9288 9289 9290eval_rule(0,Label,M):- 9291 M:'$aleph_global'(hypothesis,hypothesis(_,Clause,_,_)), !, 9292 label_create(Clause,Label,M), 9293 p_message('Rule 0'), 9294 pp_dclause(Clause,M), 9295 extract_count(pos,Label,PC), 9296 extract_count(neg,Label,NC), 9297 extract_length(Label,L), 9298 label_print_eval([PC,NC,L],M), 9299 nl. 9300eval_rule(ClauseNum,Label,M):- 9301 integer(ClauseNum), 9302 ClauseNum > 0, 9303 M:'$aleph_global'(theory,theory(ClauseNum,_,Clause,_,_)), 9304 !, 9305 label_create(Clause,Label,M), 9306 extract_count(pos,Label,PC), 9307 extract_count(neg,Label,NC), 9308 concat(['Rule ',ClauseNum],RuleTag), 9309 (setting(evalfn,posonly,M) -> 9310 concat(['Pos cover = ',PC,' Rand cover = ',NC],CoverTag); 9311 concat(['Pos cover = ',PC,' Neg cover = ',NC],CoverTag)), 9312 p1_message(RuleTag), p_message(CoverTag), 9313 pp_dclause(Clause,M), 9314 setting(verbosity,V,M), 9315 (V >= 2 -> 9316 p_message('positive examples covered'), 9317 label_print_examples(pos,Label,M), 9318 p_message('negative examples covered'), 9319 label_print_examples(neg,Label,M); 9320 true), 9321 nl. 9322eval_rule(_,_,_M). 9323 9324 9325evalfn(Label,Val,M):- 9326 (setting(evalfn,Eval,M)->true;Eval=coverage,), 9327 evalfn(Eval,Label,Val,M). 9328 9329evalfn_name(compression,'compression'). 9330evalfn_name(coverage,'pos-neg'). 9331evalfn_name(accuracy,'accuracy'). 9332evalfn_name(wracc,'novelty'). 9333evalfn_name(laplace,'laplace estimate'). 9334evalfn_name(pbayes,'pseudo-bayes estimate'). 9335evalfn_name(auto_m,'m estimate'). 9336evalfn_name(mestimate,'m estimate'). 9337evalfn_name(mse,'mse'). 9338evalfn_name(posonly,'posonly bayes estimate'). 9339evalfn_name(entropy,'entropy'). 9340evalfn_name(gini,'gini value'). 9341evalfn_name(sd,'standard deviation'). 9342evalfn_name(user,'user defined cost'). 9343 9344evalfn(compression,[P,N,L|_],Val,_M):- 9345 (P = -inf -> Val is -inf; 9346 Val is P - N - L + 1), !. 9347evalfn(coverage,[P,N,_|_],Val,_M):- 9348 (P = -inf -> Val is -inf; 9349 Val is P - N), !. 9350evalfn(laplace,[P,N|_],Val,_M):- 9351 (P = -inf -> Val is 0.5; 9352 Val is (P + 1) / (P + N + 2)), !. 9353% the evaluation function below is due to Steve Moyle's implementation 9354% of the work by Lavrac, Flach and Zupan 9355evalfn(wracc,[P,N|_],Val,M):- 9356 (M:'$aleph_search'(clauseprior,Total-[P1-pos,_]) -> 9357 Val is P/Total - (P1/Total)*((P+N)/Total); 9358 Val is -0.25), !. 9359evalfn(entropy,[P,N|_],Val,_M):- 9360 (P = -inf -> Val is 1.0; 9361 ((P is 0); (N is 0) -> Val is 0.0; 9362 Total is P + N, 9363 P1 is P/Total, 9364 Q1 is 1-P1, 9365 Val is -(P1*log(P1) + Q1*log(Q1))/log(2) 9366 ) 9367 ), !. 9368evalfn(gini,[P,N|_],Val,_M):- 9369 (P = -inf -> Val is 1.0; 9370 Total is P + N, 9371 P1 is P/Total, 9372 Val is 2*P1*(1-P1)), !. 9373evalfn(accuracy,[P,N|_],Val,_M):- 9374 ((P = -inf; P+N =:= 0) -> Val is 0.5; 9375 Val is P / (P + N)), !. 9376% the evaluation functions below are due to James Cussens 9377evalfn(pbayes,[P,N|_],Val,M):- 9378 (P = -inf -> Val is 0.5; 9379 Acc is P/(P+N), 9380 setting(prior,PriorD,M), 9381 normalise_distribution(PriorD,NPriorD), 9382 aleph_member1(Prior-pos,NPriorD), 9383 (0 is Prior-Acc -> 9384 Val=Prior; 9385 K is (Acc*(1 - Acc)) / ((Prior-Acc)^2 ), 9386 Val is (P + K*Prior) / (P + N + K))), !. 9387evalfn(posonly,[P,0,L|_],Val,M):- 9388 M:'$aleph_global'(size,size(rand,RSize)), 9389 Val is log(P) + log(RSize+2.0) - (L+1)/P, !. 9390evalfn(auto_m,[P,N|_],Val,M):- 9391 (P = -inf -> Val is 0.5; 9392 Cover is P + N, 9393 setting(prior,PriorD,M), 9394 normalise_distribution(PriorD,NPriorD), 9395 aleph_member1(Prior-pos,NPriorD), 9396 K is sqrt(Cover), 9397 Val is (P + K*Prior) / (Cover+K)), !. 9398evalfn(mestimate,[P,N|_],Val,M):- 9399 (P = -inf -> Val is 0.5; 9400 Cover is P + N, 9401 setting(prior,PriorD,M), 9402 normalise_distribution(PriorD,NPriorD), 9403 aleph_member1(Prior-pos,NPriorD), 9404 (setting(m,MM,M) -> K = MM; K is sqrt(Cover)), 9405 Val is (P + K*Prior) / (Cover+K)), !. 9406evalfn(_,_,X,_M):- X is -inf. 9407 9408 9409assemble_label(P,N,L,[P,N,L]). 9410 9411extract_cover(pos,[P,_,_],P1):- 9412 intervals_to_list(P,P1), !. 9413extract_cover(neg,[_,N,_],N1):- 9414 intervals_to_list(N,N1),!. 9415extract_cover(_,[]). 9416 9417extract_count(pos,[P,_,_],P1):- 9418 interval_count(P,P1), !. 9419extract_count(neg,[_,N,_],N1):- 9420 interval_count(N,N1), !. 9421extract_count(neg,_,0). 9422 9423 9424extract_pos([P|_],P). 9425extract_neg([_,N|_],N). 9426extract_length([_,_,L|_],L). 9427 9428get_start_label(_,[0,0,0,F],M):- 9429 (setting(interactive,true,M); setting(search,ic,M)), !, 9430 F is -inf. 9431get_start_label(user,[1,0,2,F],_M):- !, F is -inf. 9432get_start_label(entropy,[1,0,2,-0.5],_M):- !. 9433get_start_label(gini,[1,0,2,-0.5],_M):- !. 9434get_start_label(wracc,[1,0,2,-0.25],_M):- !. 9435get_start_label(Evalfn,[1,0,2,Val],M):- 9436 evalfn(Evalfn,[1,0,2],Val,M). 9437 9438 9439%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9440% I / O S T U F F 9441 9442% read_all(+Prefix) 9443% read background and examples 9444read_all(M:Prefix):- 9445 initialize(M), 9446 read_all(Prefix,Prefix,Prefix,M). 9447 9448% read_all/2 and read_all/3 largely 9449% provided by Stasinos Konstantopoulos and Mark Reid 9450read_all(BPrefix,EPrefix):- 9451 read_all(BPrefix,EPrefix,EPrefix). 9452 9453read_all(Back,Pos,Neg,M):- 9454 clean_up(M), 9455 reset(M), 9456 read_background(Back,M), 9457 read_examples(Pos,Neg,M), 9458 record_targetpred(M), 9459 check_recursive_calls(M), 9460 check_prune_defs(M), 9461 check_user_search(M), 9462 check_posonly(M), 9463 check_auto_refine(M), 9464 check_abducibles(M). 9465 9466read_background(Back,M):- 9467 construct_name(background,Back,File,M), 9468 consult(M:File), 9469 broadcast(background(loaded)). 9470 9471read_examples(Pos,Neg,M):- 9472 (setting(train_pos,PosF,M) -> 9473 set(use_file_extensions,false,M), 9474 read_examples_files(pos,PosF,_,M), 9475 noset(use_file_extensions,M); 9476 read_examples_files(pos,Pos,PosF,M), 9477 set(train_pos,PosF,M) 9478 ), 9479 (setting(train_neg,NegF,M) -> 9480 set(use_file_extensions,false,M), 9481 read_examples_files(neg,NegF,_,M), 9482 noset(use_file_extensions,M); 9483 read_examples_files(neg,Neg,NegF,M), 9484 set(train_neg,NegF,M) 9485 ), 9486 M:'$aleph_global'(size,size(pos,P)), 9487 M:'$aleph_global'(size,size(neg,N)), 9488 set_lazy_recalls(M), 9489 (setting(prior,_,M) -> true; 9490 normalise_distribution([P-pos,N-neg],Prior), 9491 set(prior,Prior,M) 9492 ), 9493 reset_counts(M), 9494 asserta(M:'$aleph_global'(last_clause,last_clause(0))), 9495 broadcast(examples(loaded)). 9496 9497aleph_read_pos_examples(Type,M) :- 9498 broadcast(background(loaded)), 9499 clean_up_examples(Type,M), 9500 asserta(M:'$aleph_global'(size,size(Type,0))), 9501 M:'$aleph_global'(size,size(Type,N)), 9502 (N > 0 -> Ex = [1-N]; Ex = []), 9503 asserta(M:'$aleph_global'(atoms,atoms(Type,Ex))), 9504 asserta(M:'$aleph_global'(atoms_left,atoms_left(Type,Ex))), 9505 asserta(M:'$aleph_global'(last_example,last_example(Type,N))). 9506aleph_read_neg_examples(Type,M) :- 9507 clean_up_examples(Type,M), 9508 asserta(M:'$aleph_global'(size,size(Type,0))), 9509 /* 9510 record_example(nocheck,neg,eastbound(west1),_), 9511 record_example(nocheck,neg,eastbound(west2),_), 9512 record_example(nocheck,neg,eastbound(west3),_), 9513 record_example(nocheck,neg,eastbound(west4),_), 9514 record_example(nocheck,neg,eastbound(west5),N1), 9515 */ 9516 %my_record_examples(Type), 9517 %findall(C,M:inc(C),L), 9518 M:'$aleph_global'(size,size(Type,N)), 9519 (N > 0 -> Ex = [1-N]; Ex = []), 9520 asserta(M:'$aleph_global'(atoms,atoms(Type,Ex))), 9521 asserta(M:'$aleph_global'(atoms_left,atoms_left(Type,Ex))), 9522 asserta(M:'$aleph_global'(last_example,last_example(Type,N))). 9523read_examples_files(Type,Name,F,M):- 9524 clean_up_examples(Type,M), 9525 asserta(M:'$aleph_global'(size,size(Type,0))), 9526 (Name = [_|_] -> 9527 read_examples_from_files(Name,Type,F,M); 9528 read_examples_from_file(Type,Name,F,M)), 9529 M:'$aleph_global'(size,size(Type,N)), 9530 (N > 0 -> Ex = [1-N]; Ex = []), 9531 asserta(M:'$aleph_global'(atoms,atoms(Type,Ex))), 9532 asserta(M:'$aleph_global'(atoms_left,atoms_left(Type,Ex))), 9533 asserta(M:'$aleph_global'(last_example,last_example(Type,N))). 9534 9535read_examples_from_files([],_,[],_M). 9536read_examples_from_files([Name|Files],Type,[FileName|FileNames],M):- 9537 read_examples_from_file(Type,Name,FileName,M), 9538 read_examples_from_files(Files,Type,FileNames,M). 9539 9540read_examples_from_file(Type,Name,File,M):- 9541 construct_name(Type,Name,File,M), 9542 (aleph_open(File,read,Stream) -> 9543 concat(['consulting ',Type, ' examples'],Mess), 9544 p1_message(Mess), p_message(File); 9545 p1_message('cannot open'), p_message(File), 9546 fail), 9547 repeat, 9548 read(Stream,Example), 9549 (Example=end_of_file-> close(Stream); 9550 record_example(nocheck,Type,Example,_,M), 9551 fail), 9552 !. 9553read_examples_from_file(_,_,'?',_M). 9554 9555construct_name(_,Name,Name,M):- 9556 setting(use_file_extensions,false,M), !. 9557construct_name(Type,Prefix,Name,_M):- 9558 name(Prefix,PString), 9559 file_extension(Type,SString), 9560 aleph_append(SString,PString,FString), 9561 name(Name,FString). 9562 9563file_extension(pos,Suffix):- name('.f',Suffix). 9564file_extension(neg,Suffix):- name('.n',Suffix). 9565file_extension(background,Suffix):- name('.b',Suffix). 9566 9567 9568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9569% M I S C. D E F I N I T I O N S 9570 9571execute(C):- 9572 system(C), !. 9573execute(_). 9574 9575% store critical values of current search state 9576store(searchstate,M):- 9577 !, 9578 retractall(M:'$aleph_global'(save,save(searchstate,_))), 9579 (M:'$aleph_global'(atoms_left,atoms_left(pos,PosLeft)) -> 9580 asserta(M:'$aleph_global'(save, 9581 save(searchstate,atoms_left(pos,PosLeft)))); 9582 true), 9583 (M:'$aleph_global'(atoms_left,atoms_left(neg,NegLeft)) -> 9584 asserta(M:'$aleph_global'(save, 9585 save(searchstate,atoms_left(neg,NegLeft)))); 9586 true), 9587 (M:'$aleph_global'(size,size(pos,PSize)) -> 9588 asserta(M:'$aleph_global'(save, 9589 save(searchstate,size(pos,PSize)))); 9590 true), 9591 (M:'$aleph_global'(size,size(neg,NSize)) -> 9592 asserta(M:'$aleph_global'(save, 9593 save(searchstate,size(neg,NSize)))); 9594 true), 9595 (M:'$aleph_global'(noise,set(noise,Noise)) -> 9596 asserta(M:'$aleph_global'(save, 9597 save(searchstate,set(noise,Noise)))); 9598 true), 9599 (M:'$aleph_global'(minacc,set(minacc,MinAcc)) -> 9600 asserta(M:'$aleph_global'(save, 9601 save(searchstate,set(minacc,MinAcc)))); 9602 true). 9603 9604% store current bottom clause 9605store(bottom,M):- 9606 !, 9607 (M:'$aleph_global'(store_bottom,set(store_bottom,true)) -> 9608 store_bottom; 9609 true). 9610 9611store(Parameter,M):- 9612 (M:'$aleph_global'(Parameter,set(Parameter,Value)) -> true; Value = unknown), 9613 retractall(M:'$aleph_global'(save,save(Parameter,_))), 9614 asserta(M:'$aleph_global'(save,save(Parameter,Value))). 9615 9616% store values of a list of parameters 9617store_values([],_M). 9618store_values([Parameter|T],M):- 9619 store(Parameter,M), 9620 store_values(T,M). 9621 9622% store all relevant info related to current bottom 9623% details are stored in 5 idbs: 9624% 1. bottom: points to 2 other idbs sat_X_n and lits_X_N 9625% 2. sat_X_N: where X is the type of the current example and N the number 9626% this contains misc stuff recorded by sat/2 for use by reduce/1 9627% 3. lits_X_N: contains the lits in bottom 9628% 4. ovars_X_N: contains output vars of lits in bottom 9629% 5. ivars_X_N: contains input vars of lits in bottom 9630store_bottom(M):- 9631 bottom_key(Num,Type,Key,true,M), 9632 asserta(M:'$aleph_sat'(stored,stored(Num,Type,Key))), 9633 '$aleph_sat'(lastterm,LastTerm), 9634 asserta(M:'$aleph_sat'(lasterm,Key,LastTerm)), 9635 '$aleph_sat'(lastvar,LastVar), 9636 asserta(M:'$aleph_sat'(lastvar,Key,LastVar)), 9637 '$aleph_sat'(botsize,BotSize), 9638 asserta(M:'$aleph_sat'(botsize,Key,BotSize)), 9639 '$aleph_sat'(lastlit,LastLit), 9640 asserta(M:'$aleph_sat'(lastlit,Key,LastLit)), 9641 '$aleph_sat'(hovars,HOVars), 9642 asserta(M:'$aleph_sat'(hovars,Key,HOVars)), 9643 '$aleph_sat'(hivars,HIVars), 9644 asserta(M:'$aleph_sat'(hivars,Key,HIVars)), 9645 '$aleph_sat'(eq,Eq), 9646 asserta(M:'$aleph_sat'(eq,Key,Eq)), 9647 '$aleph_sat_ivars'(Lit,IVars), 9648 asserta(M:'$aleph_sat_ivars'(Lit,Key,IVars)), 9649 '$aleph_sat_ovars'(Lit,OVars), 9650 asserta(M:'$aleph_sat_ovars'(Lit,Key,OVars)), 9651 '$aleph_sat_litinfo'(Lit,Depth,Atom,I,O,D), 9652 asserta(M:'$aleph_sat_litinfo'(Lit,Key,Depth,Atom,I,O,D)), 9653 fail. 9654store_bottom(_M). 9655 9656 9657reinstate(searchstate,M):- 9658 !, 9659 retractall(M:'$aleph_global'(atoms_left,atoms_left(_,_))), 9660 retractall(M:'$aleph_global'(size,size(_,_))), 9661 (M:'$aleph_global'(save,save(searchstate,atoms_left(pos,PosLeft))) -> 9662 asserta(M:'$aleph_global'(atoms_left,atoms_left(pos,PosLeft))); 9663 true), 9664 (M:'$aleph_global'(save,save(searchstate,atoms_left(neg,NegLeft))) -> 9665 asserta(M:'$aleph_global'(atoms_left,atoms_left(neg,NegLeft))); 9666 true), 9667 (M:'$aleph_global'(save,save(searchstate,size(pos,PSize))) -> 9668 asserta(M:'$aleph_global'(size,size(pos,PSize))); 9669 true), 9670 (M:'$aleph_global'(save,save(searchstate,size(neg,NSize))) -> 9671 asserta(M:'$aleph_global'(size,size(neg,NSize))); 9672 true), 9673 (M:'$aleph_global'(save,save(searchstate,set(noise,Noise))) -> 9674 set(noise,Noise,M); 9675 true), 9676 (M:'$aleph_global'(save,save(searchstate,set(minacc,MinAcc))) -> 9677 set(minacc,MinAcc,M); 9678 true), 9679 retractall(M:'$aleph_global'(save,save(searchstate,_))). 9680reinstate(Parameter,M):- 9681 retract(M:'$aleph_global'(save,save(Parameter,Value))), !, 9682 (Value = unknown -> noset(Parameter,M); set(Parameter,Value,M)). 9683reinstate(_,_M). 9684 9685% reinstate list of values of parameters 9686reinstate_values([],_M). 9687reinstate_values([Parameter|T],M):- 9688 reinstate(Parameter,M), 9689 reinstate_values(T,M). 9690 9691% reinstate all saved values 9692reinstate_values(M):- 9693 reinstate_file_streams(M), 9694 M:'$aleph_global'(save,save(_,_)), 9695 repeat, 9696 retract(M:'$aleph_global'(save,save(Parameter,Value))), 9697 (Value = unknown -> noset(Parameter,M) ; set(Parameter,Value,M)), 9698 \+(M:'$aleph_global'(save,save(_,_))), 9699 !. 9700reinstate_values(_M). 9701 9702reinstate_file_streams(M):- 9703 setting(recordfile,File,M), 9704 set(recordfile,File,M), 9705 fail. 9706reinstate_file_streams(M):- 9707 setting(goodfile,File,M), 9708 set(goodfile,File,M), 9709 fail. 9710reinstate_file_streams(_M). 9711 9712 9713% bottom_key(?N,?T,-Key,-Flag) 9714% returns key that indexes bottom clause info for example N of type T 9715% Flag is one of "true" or "false" depending on whether bottom 9716% requires storing 9717bottom_key(N,T,Key,Flag,M):- 9718 ((var(N),var(T)) -> 9719 M:'$aleph_sat'(example,example(N,T)); 9720 true), 9721 (setting(store_bottom,true,M) -> 9722 (M:'$aleph_sat'(stored,stored(N,T,Key)) -> 9723 Flag = false; 9724 concat([T,'_',N],Key), 9725 Flag = true 9726 ); 9727 Key = false, 9728 Flag = false).
9735aleph_set(M:Variable,Value):- 9736 set(Variable,Value,M). 9737 9738 9739set(Variable,Value,M):- 9740 check_setting(Variable,Value), 9741 (Value = inf -> V is inf; 9742 (Value = +inf -> V is inf; 9743 (Value = -inf -> V is -inf; V = Value) 9744 ) 9745 ), 9746 retractall(M:'$aleph_global'(Variable,set(Variable,_))), 9747 assertz(M:'$aleph_global'(Variable,set(Variable,V))), 9748 broadcast(set(Variable,V)), 9749 special_consideration(Variable,Value,M).
9755aleph_setting(M:Variable,Value):- 9756 setting(Variable,Value,M). 9757 9758setting(Variable,Value,M):- 9759 nonvar(Variable), 9760 M:'$aleph_global'(Variable,set(Variable,Value1)), !, 9761 Value = Value1. 9762setting(Variable,Value,_M):- 9763 default_setting(Variable,Value). 9764 9765noset(M:Variable):- 9766 noset(Variable,M). 9767 9768noset(Variable,M):- 9769 nonvar(Variable), 9770 retract(M:'$aleph_global'(Variable,set(Variable,Value))), !, 9771 rm_special_consideration(Variable,Value,M), 9772 set_default(Variable,M). 9773noset(_,_M).
/
9781man(M):- 9782 aleph_manual(M). 9783 9784determinations(Pred1,Pred2,M):- 9785 M:'$aleph_global'(determination,determination(Pred1,Pred2)). 9786 9787determination(Pred1,Pred2,M):- 9788 nonvar(Pred1), 9789 M:'$aleph_global'(determination,determination(Pred1,Pred2)), !. 9790determination(Pred1,Pred2,M):- 9791 noset(autorefine,M), 9792 assertz(M:'$aleph_global'(determination,determination(Pred1,Pred2))), 9793 (nonvar(Pred1) -> 9794 update_backpreds(Pred1,M); 9795 true).
9803abducible(M:Name/Arity):- 9804 abducible(Name/Arity,M). 9805 9806abducible(Name/Arity,M):- 9807 assertz(M:'$aleph_global'(abducible,abducible(Name/Arity))).
9815commutative(M:Name/Arity):- 9816 commutative(Name/Arity,M). 9817 9818commutative(Name/Arity,M):- 9819 assertz(M:'$aleph_global'(commutative,commutative(Name/Arity))).
9826symmetric(M:Name/Arity):- 9827 symmetric(Name/Arity,M). 9828 9829symmetric(Name/Arity,M):- 9830 assertz(M:'$aleph_global'(symmetric,symmetric(Name/Arity))).
9848lazy_evaluate(M:Name/Arity):- 9849 lazy_evaluate(Name/Arity,M). 9850 9851lazy_evaluate(Name/Arity,M):- 9852 assertz(M:'$aleph_global'(lazy_evaluate,lazy_evaluate(Name/Arity))).
9862model(M:Name/Arity):- 9863 model(Name/Arity,M). 9864 9865model(Name/Arity,M):- 9866 assertz(M:'$aleph_global'(model,model(Name/Arity))).
9876positive_only(M:Name/Arity):- 9877 positive_only(Name/Arity,M). 9878 9879positive_only(Name/Arity,M):- 9880 assertz(M:'$aleph_global'(positive_only,positive_only(Name/Arity))).
9886mode(M:Recall,Pred):- 9887 mode(Recall,Pred,M). 9888 9889mode(Recall,Pred,M):- 9890 modeh(Recall,Pred,M), 9891 modeb(Recall,Pred,M). 9892 9893modes(N/A,Mode,M):- 9894 Mode = modeh(_,Pred), 9895 M:'$aleph_global'(modeh,Mode), 9896 functor(Pred,N,A). 9897modes(N/A,Mode,M):- 9898 Mode = modeb(_,Pred), 9899 M:'$aleph_global'(modeb,Mode), 9900 functor(Pred,N,A).
9907modeh(M:Recall,Pred):- 9908 modeh(Recall,Pred,M). 9909 9910modeh(Recall,Pred,M):- 9911 (M:'$aleph_global'(mode,mode(Recall,Pred)) -> true; 9912 noset(autorefine,M), 9913 assertz(M:'$aleph_global'(modeh,modeh(Recall,Pred))), 9914 assertz(M:'$aleph_global'(mode,mode(Recall,Pred))), 9915 functor(Pred,Name,Arity), 9916 update_backpreds(Name/Arity,M)).
9923modeb(M:Recall,Pred):- 9924 modeb(Recall,Pred,M). 9925 9926modeb(Recall,Pred,M):- 9927 (M:'$aleph_global'(modeb,modeb(Recall,Pred)) -> true; 9928 noset(autorefine,M), 9929 assertz(M:'$aleph_global'(modeb,modeb(Recall,Pred))), 9930 (M:'$aleph_global'(mode,mode(Recall,Pred)) -> true; 9931 assertz(M:'$aleph_global'(mode,mode(Recall,Pred))))). 9932 9933% add_determinations(+PSym,Stratified) 9934% add determination declarations for a background predicate 9935% these are obtained from the determinations of the target predicate 9936% If Stratified is true then only stratified definitions are allowed 9937add_determinations(PSym,Stratified,M):- 9938 M:'$aleph_global'(targetpred,targetpred(Target)), 9939 determinations(Target,OtherPred,M), 9940 (Stratified = true -> OtherPred \= Target; true), 9941 determination(PSym,OtherPred,M), 9942 fail. 9943add_determinations(_,_,_M). 9944 9945% add_modes(+PSym) 9946% add modes declarations for a (new) predicate 9947% these are obtained from the modes of the target predicate 9948add_modes(Name/_,M):- 9949 M:'$aleph_global'(targetpred,targetpred(Target)), 9950 modes(Target,Mode,M), 9951 Mode =.. [ModeType,Recall,TargetMode], 9952 TargetMode =.. [_|Args], 9953 PredMode =.. [Name|Args], 9954 NewMode =.. [ModeType,Recall,PredMode,M], 9955 call(NewMode), 9956 fail. 9957add_modes(_,_M). 9958 9959feature(Id,Feature,M):- 9960 M:'$aleph_feature'(feature,feature(Id,_,_,Template,Body)), 9961 Feature = (Template:-Body). 9962 9963gen_feature(Feature,Label,Class,M):- 9964 nonvar(Feature), !, 9965 gen_featurenum(Id,M), 9966 split_clause(Feature,Template,Body), 9967 assertz(M:'$aleph_feature'(feature,feature(Id,Label,Class,Template,Body))).
portray(search)
)./
9997show(M:S):- 9998 show(S,M). 9999 10000show(settings,M):- 10001 nl, 10002 p_message('settings'), 10003 findall(P-V,M:'$aleph_global'(P,set(P,V)),L), 10004 sort(L,L1), 10005 aleph_member(Parameter-Value,L1), 10006 tab(8), write(Parameter=Value), nl, 10007 fail. 10008show(determinations,M):- 10009 nl, 10010 p_message('determinations'), 10011 show_global(determination,determination(_,_),M). 10012show(modes,M):- 10013 nl, 10014 p_message('modes'), 10015 show_global(mode,mode(_,_),M). 10016show(modehs,M):- 10017 nl, 10018 p_message('modehs'), 10019 show_global(modeh,modeh(_,_),M). 10020show(modebs,M):- 10021 nl, 10022 p_message('modebs'), 10023 show_global(modeb,modeb(_,_),M). 10024show(sizes,M):- 10025 nl, 10026 p_message('sizes'), 10027 show_global(size,size(_,_),M). 10028show(bottom,M):- 10029 nl, 10030 p_message('bottom clause'), 10031 setting(verbosity,V,M), 10032 V > 0, 10033 M:'$aleph_sat'(lastlit,Last), 10034 get_clause(1,Last,[],FlatClause,M), 10035 pp_dlist(FlatClause,M). 10036show(theory,M):- 10037 nl, 10038 p_message('theory'), 10039 nl, 10040 M:'$aleph_global'(rules,rules(L)), 10041 aleph_reverse(L,L1), 10042 aleph_member(ClauseNum,L1), 10043 M:'$aleph_global'(theory,theory(ClauseNum,_,_,_,_)), 10044 eval_rule(ClauseNum,_,M), 10045 % pp_dclause(Clause), 10046 fail. 10047show(theory,M):- 10048 get_performance(M). 10049show(pos,M):- 10050 nl, 10051 p_message('positives'), 10052 store(greedy,M), 10053 examples(pos,_,M), 10054 reinstate(greedy,M), 10055 fail. 10056show(posleft,M):- 10057 nl, 10058 p_message('positives left'), 10059 M:example(_,pos,Atom), 10060 \+(), 10061 write(Atom), write('.'), nl, 10062 fail. 10063show(neg,M):- 10064 nl, 10065 p_message('negatives'), 10066 store(greedy,M), 10067 examples(neg,_,M), 10068 reinstate(greedy,M), 10069 fail. 10070show(rand,M):- 10071 nl, 10072 p_message('random'), 10073 examples(rand,_,M), 10074 fail. 10075show(uspec,M):- 10076 nl, 10077 p_message('uspec'), 10078 examples(uspec,_,M), 10079 fail. 10080show(gcws,M):- 10081 nl, 10082 p_message('gcws hypothesis'), 10083 M:'$aleph_search'(gcwshyp,hypothesis(_,C,_,_)), 10084 pp_dclause(C,M), 10085 fail. 10086show(abgen,M):- 10087 nl, 10088 p_message('abduced hypothesis'), 10089 M:'$aleph_search'(abgenhyp,hypothesis(_,AbGen,_,_)), 10090 aleph_member(C,AbGen), 10091 pp_dclause(C,M), 10092 fail. 10093show(hypothesis,M):- 10094 setting(portray_hypothesis,Pretty,M), 10095 aleph_portray(hypothesis,Pretty,M), 10096 fail. 10097show(search,M):- 10098 setting(portray_search,Pretty,M), 10099 aleph_portray(search,Pretty,M). 10100show(good,M):- 10101 setting(good,true,M), 10102 nl, 10103 p_message('good clauses'), 10104 (setting(minscore,FMin,M) -> true; FMin is -inf), 10105 setting(evalfn,Evalfn,M), 10106 M:'$aleph_good'(_,Label,Clause), 10107 Label = [_,_,_,F|_], 10108 F >= FMin, 10109 pp_dclause(Clause,M), 10110 show_stats(Evalfn,Label), 10111 fail. 10112show(good,M):- 10113 setting(good,true,M), 10114 setting(goodfile,File,M), 10115 aleph_open(File,read,Stream), 10116 (setting(minscore,FMin,M) -> true; FMin is -inf), 10117 setting(evalfn,Evalfn,M), 10118 repeat, 10119 read(Stream,Fact), 10120 (Fact = M:'$aleph_good'(_,Label,Clause) -> 10121 Label = [_,_,_,F|_], 10122 F >= FMin, 10123 show_stats(Evalfn,Label), 10124 pp_dclause(Clause,M), 10125 fail; 10126 close(Stream), ! 10127 ). 10128show(features,M):- 10129 setting(evalfn,Evalfn,M), 10130 (M:'$aleph_feature'(feature,_) -> true; 10131 gen_features(M)), 10132 p_message('features from good clauses'), 10133 M:'$aleph_feature'(feature,feature(Id,Label,_,Head,Body)), 10134 show_stats(Evalfn,Label), 10135 pp_dclause(feature(Id,(Head:-Body)),M), 10136 fail. 10137show(constraints,M):- 10138 setting(good,true,M), 10139 nl, 10140 p_message('constraints'), 10141 setting(noise,N,M), 10142 FMin is -N, 10143 M:'$aleph_good'(_,Label,Clause), 10144 split_clause(Clause,false,_), 10145 Label = [_,_,_,F], 10146 F >= FMin, 10147 pp_dclause(Clause,M), 10148 show_stats(coverage,Label), 10149 fail. 10150show(constraints,M):- 10151 show(aleph_false/0,M). 10152show(Name/Arity,M):- 10153 functor(Pred,Name,Arity), 10154 %current_predicate(M:Name,Pred), 10155 nl, 10156 p1_message('definition'), p_message(Name/Arity), 10157 clause(M:,Body), 10158 \+(in(Body,'$aleph_search'(pclause,pclause(_,_)),M)), 10159 pp_dclause((Pred:-Body),M), 10160 fail. 10161show(train_pos,M):- 10162 setting(portray_examples,Pretty,M), 10163 aleph_portray(train_pos,Pretty,M). 10164show(train_neg,M):- 10165 setting(portray_examples,Pretty,M), 10166 aleph_portray(train_neg,Pretty,M). 10167show(test_pos,M):- 10168 setting(portray_examples,Pretty,M), 10169 aleph_portray(test_pos,Pretty,M). 10170show(test_neg,M):- 10171 setting(portray_examples,Pretty,M), 10172 aleph_portray(test_neg,Pretty,M). 10173show(_,_M). 10174 10175settings(M):- 10176 show(settings,M).
10184good_clauses(M:GC):- 10185 good_clauses(GC,M). 10186 10187good_clauses(GC,M):- 10188 (setting(minscore,FMin,M) -> true; FMin is -inf), 10189 findall(Clause, 10190 (M:'$aleph_good'(_,Label,Clause), 10191 Label = [_,_,_,F|_], 10192 F >= FMin),GC). 10193 10194% examples(?Type,?List) 10195% show all examples numbers in List of Type 10196examples(Type,List,M):- 10197 setting(portray_literals,Pretty,M), 10198 M:example(Num,Type,Atom), 10199 aleph_member1(Num,List), 10200 aleph_portray(Atom,Pretty,M), write('.'), nl, 10201 fail. 10202examples(_,_,_M).
10209bottom(M:Clause):- 10210 bottom(Clause,M). 10211 10212bottom(Clause,M):- 10213 M:'$aleph_sat'(lastlit,Last), 10214 get_clause(1,Last,[],ClauseList,M), 10215 list_to_clause(ClauseList,Clause). 10216 10217% posleft(-List) 10218% returns positive examples left to be covered 10219posleft(PList,M):- 10220 M:'$aleph_global'(atoms_left,atoms_left(pos,PosLeft)), 10221 intervals_to_list(PosLeft,PList). 10222 10223% write_rules/0 due to Mark Reid 10224write_rules(M):- 10225 setting(rulefile,File,M), 10226 write_rules(File), !. 10227write_rules(_M). 10228 10229write_features(M):- 10230 setting(featurefile,File,M), 10231 write_features(File,M), !. 10232write_features(_M). 10233 10234write_rules(File,M):- 10235 aleph_open(File,write,Stream), 10236 set_output(Stream), 10237 M:'$aleph_global'(rules,rules(L)), 10238 aleph_reverse(L,L1), 10239 write_rule(L1,M), 10240 flush_output(Stream), 10241 set_output(user_output). 10242 10243write_rule(Rules,M):- 10244 aleph_member(RuleId,Rules), 10245 M:'$aleph_global'(theory,theory(RuleId,_,Rule,_,_)), 10246 pp_dclause(Rule,M), 10247 fail. 10248write_rule(_,_M). 10249 10250write_features(File,M):- 10251 aleph_open(File,write,Stream), 10252 set_output(Stream), 10253 listing(M:'$aleph_feature'/2), 10254 close(Stream), 10255 set_output(user_output). 10256write_features(_,_M). 10257 10258 10259best_hypothesis(Head1,Body1,[P,N,L],M):- 10260 M:'$aleph_search'(selected,selected([P,N,L|_],Clause,_,_)), 10261 split_clause(Clause,Head2,Body2), !, 10262 Head1 = Head2, Body1 = Body2.
/
10275hypothesis(M:Head1,Body1,Label):-
10276 hypothesis(Head1,Body1,Label,M).
10289hypothesis(Head1,Body1,Label,M):- 10290 M:'$aleph_search'(pclause,pclause(Head2,Body2)), !, 10291 Head1 = Head2, Body1 = Body2, 10292 get_hyp_label((Head2:-Body2),Label,M). 10293hypothesis(Head1,Body1,Label,M):- 10294 M:'$aleph_global'(hypothesis,hypothesis(_,Theory,_,_)), 10295 (Theory = [_|_] -> aleph_member(Clause,Theory); 10296 Theory = Clause), 10297 split_clause(Clause,Head2,Body2), 10298 Head1 = Head2, Body1 = Body2, 10299 get_hyp_label((Head2:-Body2),Label,M).
/
10308rdhyp(M:_):-
10309 retractall(M:'$aleph_search'(pclause,_)),
10310 retractall(M:'$aleph_search'(covers,_)),
10311 retractall(M:'$aleph_search'(coversn,_)),
10312 read(Clause),
10313 add_hyp(Clause,M),
10314 nl,
10315 show(hypothesis,M).
/
10326addhyp_i(M:_):- 10327 addhyp(M). 10328 10329addhyp(M):- 10330 M:'$aleph_global'(hypothesis,hypothesis(Label,Theory,PCover,NCover)), 10331 Theory = [_|_], !, 10332 add_theory(Label,Theory,PCover,NCover,M). 10333addhyp(M):- 10334 M:'$aleph_global'(hypothesis,hypothesis(Label,_,PCover,_)), !, 10335 rm_seeds(M), 10336 worse_coversets(PCover,pos,Label,Worse,M), 10337 (Worse = [] -> true; 10338 M:'$aleph_global'(last_clause,last_clause(NewClause)), 10339 update_coversets(Worse,NewClause,pos,Label,M)), !. 10340addhyp(M):- 10341 M:'$aleph_search'(selected,selected(Label,RClause,PCover,NCover)), !, 10342 add_hyp(Label,RClause,PCover,NCover,M), 10343 rm_seeds(M), 10344 worse_coversets(PCover,pos,Label,Worse,M), 10345 (Worse = [] -> true; 10346 M:'$aleph_global'(last_clause,last_clause(NewClause)), 10347 update_coversets(Worse,NewClause,pos,Label,M)), !. 10348 10349% add bottom clause as hypothesis 10350% provided minacc, noise and search constraints are met 10351% otherwise the example saturated is added as hypothesis 10352add_bottom(Bottom,M):- 10353 retractall(M:'$aleph_search'(selected,selected(_,_,_,_))), 10354 bottom(Bottom,M), 10355 add_hyp(Bottom,M), 10356 M:'$aleph_global'(hypothesis,hypothesis(Label,Clause,_,_)), 10357 (clause_ok(Clause,Label,M) -> true; 10358 M:'$aleph_sat'(example,example(Num,Type)), 10359 M:example(Num,Type,Example), 10360 retract(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 10361 setting(evalfn,Evalfn,M), 10362 complete_label(Evalfn,Example,[1,0,1],Label1), 10363 asserta(M:'$aleph_global'(hypothesis,hypothesis(Label1,(Example:-true),[Num-Num],[])))). 10364 10365 10366% specialise a hypothesis by recursive construction of 10367% abnormality predicates
10376sphyp_i(M:_):- 10377 sphyp(M). 10378 10379sphyp(M):- 10380 retractall(M:'$aleph_search'(sphyp,hypothesis(_,_,_,_))), 10381 retractall(M:'$aleph_search'(gcwshyp,hypothesis(_,_,_,_))), 10382 retract(M:'$aleph_global'(hypothesis, 10383 hypothesis([P,N,L|T],Clause,PCover,NCover))), 10384 asserta(M:'$aleph_search'(sphyp,hypothesis([P,N,L|T],Clause,PCover,NCover))), 10385 store(searchstate,M), 10386 gcws(M), 10387 retractall(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 10388 asserta(M:'$aleph_global'(hypothesis, 10389 hypothesis([P,N,L|T],Clause,PCover,NCover))), 10390 reinstate(searchstate,M).
/
10399addgcws_i(M:_):- 10400 addgcws(M). 10401 10402addgcws(M):- 10403 retract(M:'$aleph_search'(gcwshyp,hypothesis(Label,C,P,N))), !, 10404 asserta(M:'$aleph_search'(gcwshyp,hypothesis(Label,C,P,N))), 10405 addhyp(M), 10406 add_gcws(M).
/
10414rmhyp_i(M:_):- 10415 rmhyp(M). 10416 10417rmhyp(M):- 10418 retract(M:'$aleph_search'(pclause,pclause(Head,Body))), 10419 asserta(M:'$aleph_local'(pclause,pclause(Head,Body))), !. 10420rmhyp(M):- 10421 retract(M:'$aleph_global'(hypothesis,hypothesis(Label,Clause1,P,N))), 10422 asserta(M:'$aleph_local'(hypothesis,hypothesis(Label,Clause1,P,N))), !. 10423rmhyp(_).
/
10432covers(M:PC):-
10433 get_hyp(Hypothesis,M),
10434 label_create(Hypothesis,Label,M),
10435 extract_cover(pos,Label,P),
10436 examples(pos,P,M),
10437 length(P,PC),
10438 p1_message('examples covered'),
10439 p_message(PC),
10440 retractall(M:'$aleph_search'(covers,_)),
10441 asserta(M:'$aleph_search'(covers,covers(P,PC))).
/
10449coversn(M:NC):- 10450 get_hyp(Hypothesis,M), 10451 label_create(Hypothesis,Label,M), 10452 extract_cover(neg,Label,N), 10453 examples(neg,N,M), 10454 length(N,NC), 10455 p1_message('examples covered'), 10456 p_message(NC), 10457 retractall(M:'$aleph_search'(coversn,_)), 10458 asserta(M:'$aleph_search'(coversn,coversn(N,NC))). 10459 10460% covers(-Number) 10461% as in covers/0, but first checks if being done 10462% within a greedy search 10463covers(P,M):- 10464 get_hyp(Hypothesis,M), 10465 (setting(greedy,true,M) -> 10466 M:'$aleph_global'(atoms,atoms_left(pos,Pos)); 10467 M:'$aleph_global'(atoms,atoms(pos,Pos))), 10468 label_create(Hypothesis,pos,Pos,Label,M), 10469 retractall(M:'$aleph_search'(covers,_)), 10470 extract_pos(Label,PCover), 10471 interval_count(PCover,P), 10472 asserta(M:'$aleph_search'(covers,covers(PCover,P))). 10473 10474% coversn(-Number) 10475% as in coversn/0, but first checks if being done 10476% within a greedy search 10477coversn(N,M):- 10478 get_hyp(Hypothesis,M), 10479 (setting(greedy,true,M) -> 10480 M:'$aleph_global'(atoms_left,atoms_left(neg,Neg)); 10481 M:'$aleph_global'(atoms_left,atoms(neg,Neg))), 10482 label_create(Hypothesis,neg,Neg,Label,M), 10483 retractall(M:'$aleph_search'(coversn,_)), 10484 extract_neg(Label,NCover), 10485 interval_count(NCover,N), 10486 asserta(M:'$aleph_search'(coversn,coverns(NCover,N))). 10487 10488% covers(-List,-Number) 10489% as in covers/1, but returns list of examples covered and their count 10490covers(PList,P,M):- 10491 get_hyp(Hypothesis,M), 10492 (setting(greedy,true,M) -> 10493 M:'$aleph_global'(atoms,atoms_left(pos,Pos)); 10494 M:'$aleph_global'(atoms,atoms(pos,Pos))), 10495 label_create(Hypothesis,pos,Pos,Label,M), 10496 retractall(M:'$aleph_search'(covers,_)), 10497 extract_pos(Label,PCover), 10498 intervals_to_list(PCover,PList), 10499 length(PList,P), 10500 asserta(M:'$aleph_search'(covers,covers(PCover,P))). 10501 10502% coversn(-List,-Number) 10503% as in coversn/1, but returns list of examples covered and their count 10504coversn(NList,N,M):- 10505 get_hyp(Hypothesis,M), 10506 (setting(greedy,true,M) -> 10507 M:'$aleph_global'(atoms_left,atoms_left(neg,Neg)); 10508 M:'$aleph_global'(atoms_left,atoms(neg,Neg))), 10509 label_create(Hypothesis,neg,Neg,Label,M), 10510 retractall(M:'$aleph_search'(coversn,_)), 10511 extract_neg(Label,NCover), 10512 intervals_to_list(NCover,NList), 10513 length(NList,N), 10514 asserta(M:'$aleph_search'(coversn,coverns(NCover,N))).
/
10522example_saturated(M:Example):- 10523 example_saturated(Example,M). 10524 10525example_saturated(Example,M):- 10526 M:'$aleph_sat'(example,example(Num,Type)), 10527 M:example(Num,Type,Example). 10528 10529reset(M):- 10530 clean_up(M), 10531 clear_cache(M), 10532 aleph_abolish('$aleph_global'/2,M), 10533 aleph_abolish(example/3,M), 10534 assert(M:example(0,uspec,aleph_false)), 10535 set_default(_,M), 10536 !. 10537 10538% Generic timing routine due to Mark Reid. 10539% Under cygwin, cputime cannot be trusted 10540% so walltime is used instead. To use cputime, set the body of this 10541% predicate to "Time is cputime". 10542stopwatch(Time) :- 10543 Time is cputime. 10544% statistics(walltime,[Time|_]). 10545 10546wallclock(Time):- 10547 statistics(real_time,[Time|_]). 10548 10549time(P,N,[Mean,Sd]):- 10550 time_loop(N,P,Times), 10551 mean(Times,Mean), 10552 sd(Times,Sd). 10553 10554test_ex(Exs,Flag,N,T,M):- 10555 retractall(M:'$aleph_local'(covered,_)), 10556 retractall(M:'$aleph_local'(total,_)), 10557 asserta(M:'$aleph_local'(covered,0)), 10558 asserta(M:'$aleph_local'(total,0)), 10559 test_ex1(Exs,Flag,M), 10560 retract(M:'$aleph_local'(covered,N)), 10561 retract(M:'$aleph_local'(total,T)). 10562 10563test_ex1(Exs,Flag,M):- 10564 setting(portray_examples,Pretty,M), 10565 member(Example,Exs), 10566 retract(M:'$aleph_local'(total,T0)), 10567 T1 is T0 + 1, 10568 asserta(M:'$aleph_local'(total,T1)), 10569 (once(depth_bound_call(Example,M)) -> 10570 (Flag = show -> 10571 p1_message(covered), 10572 aleph_portray(Example,Pretty,M), 10573 nl; 10574 true); 10575 (Flag = show -> 10576 p1_message('not covered'), 10577 aleph_portray(Example,Pretty,M), 10578 nl; 10579 true), 10580 fail), 10581 retract(M:'$aleph_local'(covered,N0)), 10582 N1 is N0 + 1, 10583 asserta(M:'$aleph_local'(covered,N1)), 10584 fail. 10585 10586test_ex1(_,_,_). 10587 10588 10589 10590test(F,Flag,N,T,M):- 10591 retractall(M:'$aleph_local'(covered,_)), 10592 retractall(M:'$aleph_local'(total,_)), 10593 asserta(M:'$aleph_local'(covered,0)), 10594 asserta(M:'$aleph_local'(total,0)), 10595 (F = [_|_] -> 10596 test_files(F,Flag,M); 10597 test_file(F,Flag,M) 10598 ), 10599 retract(M:'$aleph_local'(covered,N)), 10600 retract(M:'$aleph_local'(total,T)). 10601 10602test_files([],_,_M). 10603test_files([File|Files],Flag,M):- 10604 test_file(File,Flag,M), 10605 test_files(Files,Flag,M). 10606 10607test_file('?',_,_M):- !. 10608test_file(File,Flag,M):- 10609 setting(portray_examples,Pretty,M), 10610 aleph_open(File,read,Stream), !, 10611 repeat, 10612 read(Stream,Example), 10613 (Example = end_of_file -> close(Stream); 10614 retract(M:'$aleph_local'(total,T0)), 10615 T1 is T0 + 1, 10616 asserta(M:'$aleph_local'(total,T1)), 10617 (once(depth_bound_call(Example,M)) -> 10618 (Flag = show -> 10619 p1_message(covered), 10620 aleph_portray(Example,Pretty,M), 10621 nl; 10622 true); 10623 (Flag = show -> 10624 p1_message('not covered'), 10625 aleph_portray(Example,Pretty,M), 10626 nl; 10627 true), 10628 fail), 10629 retract(M:'$aleph_local'(covered,N0)), 10630 N1 is N0 + 1, 10631 asserta(M:'$aleph_local'(covered,N1)), 10632 fail), 10633 !. 10634test_file(File,_,_M):- 10635 p1_message('cannot open'), p_message(File). 10636 10637in(false,_,_M):- 10638 !, 10639 fail. 10640in(bottom,Lit,M):- 10641 !, 10642 M:'$aleph_sat'(lastlit,Last), 10643 get_clause(1,Last,[],FlatClause), 10644 aleph_member(Lit,FlatClause). 10645in((Head:-true),Head,_M):- !. 10646in((Head:-Body),L,M):- 10647 !, 10648 in((Head,Body),L,M). 10649in((L1,_),L1,_M). 10650in((_,R),L,M):- 10651 !, 10652 in(R,L,M). 10653in(L,L,_M). 10654 10655in((L1,L),L1,L,_M). 10656in((L1,L),L2,(L1,Rest),M):- 10657 !, 10658 in(L,L2,Rest,M). 10659in(L,L,true,_M).
10666random(X,normal(Mean,Sigma)):- 10667 var(X), !, 10668 normal(Mean,Sigma,X). 10669random(X,normal(_,_)):- 10670 !, 10671 number(X). 10672 % X >= Mean - 3*Sigma, 10673 % X =< Mean + 3*Sigma. 10674random(X,Distr):- 10675 Distr = [_|_], 10676 var(X), !, 10677 draw_element(Distr,X1), 10678 X = X1. 10679random(X,Distr):- 10680 Distr = [_|_], 10681 nonvar(X), !, 10682 aleph_member(Prob-X,Distr), 10683 Prob > 0.0. 10684 10685mean(L,M):- 10686 sum(L,Sum), 10687 length(L,N), 10688 M is Sum/N. 10689 10690sd(L,Sd):- 10691 length(L,N), 10692 (N = 1 -> Sd = 0.0; 10693 sum(L,Sum), 10694 sumsq(L,SumSq), 10695 Sd is sqrt(SumSq/(N-1) - (Sum*Sum)/(N*(N-1)))). 10696 10697sum([],0). 10698sum([X|T],S):- 10699 sum(T,S1), 10700 S is X + S1. 10701 10702sumsq([],0). 10703sumsq([X|T],S):- 10704 sumsq(T,S1), 10705 S is X*X + S1. 10706 10707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 10708% 10709% auxilliary definitions for some of the above 10710 10711set_default(A,M):- 10712 default_setting(A,B), 10713 set(A,B,M), 10714 fail. 10715set_default(_,_M). 10716 10717default_setting(A,B):- 10718 set_def(A,_,_,_,B,_), 10719 B \= ''. 10720 10721% special case for threads as only SWI supports it 10722check_setting(threads,B):- 10723 set_def(threads,_,_,Dom,_,_), 10724 check_legal(Dom,B), 10725 prolog_type(P), 10726 (B > 1 -> 10727 (P = swi -> true; 10728 err_message(set(threads,B)), 10729 fail 10730 ); 10731 true 10732 ), !. 10733check_setting(A,B):- 10734 set_def(A,_,_,Dom,_,_), !, 10735 (check_legal(Dom,B) -> true; 10736 err_message(set(A,B))). 10737check_setting(_,_). 10738 10739check_legal(int(L)-int(U),X):- 10740 !, 10741 number(L,IL), 10742 number(U,IU), 10743 number(X,IX), 10744 IX >= IL, 10745 IX =< IU. 10746check_legal(float(L)-float(U),X):- 10747 !, 10748 number(L,FL), 10749 number(U,FU), 10750 number(X,FX), 10751 FX >= FL, 10752 FX =< FU. 10753check_legal([H|T],X):- 10754 !, 10755 aleph_member1(X,[H|T]). 10756/* AXO: Tolto perche infastidisce e non serve */ 10757check_legal(read(filename),X):- 10758 X \= '?', 10759 !, 10760 exists(X). 10761/* il commento finiva qua */ 10762 10763check_legal(_,_). 10764 10765number(+inf,Inf):- 10766 Inf is inf, !. 10767number(-inf,MInf):- 10768 MInf is -inf, !. 10769number(X,Y):- 10770 Y is X, !. 10771 10772setting_definition(A,B,C,D,E,F1):- 10773 set_def(A,B,C,D,E,F), 10774 (F = noshow -> F1 = dontshow; F = F1). 10775 10776% set_def(Parameter,Class,TextDescr,Type,Default,Flag) 10777set_def(abduce, search-search_strategy, 10778 'Abduce Atoms and Generalise', 10779 [true, false], false, 10780 show). 10781set_def(best, search-search_space, 10782 'Label to beat', 10783 prolog_term,'', 10784 show). 10785set_def(cache_clauselength, miscellaneous, 10786 'Maximum Length of Cached Clauses', 10787 int(1)-int(+inf), 3, 10788 show). 10789set_def(caching, miscellaneous, 10790 'Cache Clauses in Search', 10791 [true, false], false, 10792 show). 10793set_def(check_redundant, miscellaneous, 10794 'Check for Redundant Literals', 10795 [true, false], false, 10796 show). 10797set_def(check_good, miscellaneous, 10798 'Check good clauses for duplicates', 10799 [true, false], false, 10800 show). 10801set_def(check_useless, saturation, 10802 'Remove I/O unconnected Literals', 10803 [true, false], false, 10804 show). 10805set_def(classes, tree, 10806 'Class labels', 10807 prolog_term,'', 10808 show). 10809set_def(clauselength_distribution, search-search_strategy, 10810 'Probablity Distribution over Clauses', 10811 prolog_term,'', 10812 show). 10813set_def(clauselength, search-search_space, 10814 'Maximum Clause Length', 10815 int(1)-int(+inf), 4, 10816 show). 10817set_def(clauses, search-search_space, 10818 'Maximum Clauses per Theory', 10819 int(1)-int(+inf),'', 10820 show). 10821set_def(condition, evaluation, 10822 'Condition SLP', 10823 [true, false], false, 10824 show). 10825set_def(confidence, tree, 10826 'Confidence for Rule Pruning', 10827 float(0.0)-float(1.0), 0.95, 10828 show). 10829set_def(construct_bottom, saturation, 10830 'Build a bottom clause', 10831 [saturation, reduction, false], saturation, 10832 show). 10833set_def(depth, miscellaneous, 10834 'Theorem Proving Depth', 10835 int(1)-int(+inf), 10, 10836 show). 10837set_def(evalfn, evaluation, 10838 'Evaluation Function', 10839 [coverage, compression, posonly, pbayes, accuracy, laplace, 10840 auto_m, mestimate, mse, entropy, gini, sd, wracc, user], coverage, 10841 show). 10842set_def(explore, search-search_space, 10843 'Exhaustive Search of all alternatives', 10844 [true, false], false, 10845 show). 10846set_def(good, miscellaneous, 10847 'Store good clauses', 10848 [true, false], false, 10849 show). 10850set_def(goodfile, miscellaneous, 10851 'File of good clauses', 10852 write(filename),'', 10853 show). 10854set_def(gsamplesize, evaluation, 10855 'Size of random sample', 10856 int(1)-int(+inf), 100, 10857 show). 10858set_def(i, saturation, 10859 'bound layers of new variables', 10860 int(1)-int(+inf), 2, 10861 show). 10862set_def(interactive, search-search_strategy, 10863 'Interactive theory construction', 10864 [true, false], false, 10865 show). 10866set_def(language, search-search_space, 10867 'Maximum occurrence of any predicate symbol in a clause', 10868 int(1)-int(+inf), +inf, 10869 show). 10870set_def(lazy_negs, evaluation, 10871 'Lazy theorem proving on negative examples', 10872 [true, false], false, 10873 show). 10874set_def(lazy_on_contradiction, evaluation, 10875 'Lazy theorem proving on contradictions', 10876 [true, false], false, 10877 show). 10878set_def(lazy_on_cost, evaluation, 10879 'Lazy theorem proving on cost', 10880 [true, false], false, 10881 show). 10882set_def(lookahead, search-search_space, 10883 'Lookahead for automatic refinement operator', 10884 int(1)-int(+inf), 1, 10885 show). 10886set_def(m, evaluation, 10887 'M-estimate', 10888 float(0.0)-float(+inf),'', 10889 show). 10890set_def(max_abducibles, search-search_space, 10891 'Maximum number of atoms in an abductive explanation', 10892 int(1)-int(+inf), 2, 10893 show). 10894set_def(max_features, miscellaneous, 10895 'Maximum number of features to be constructed', 10896 int(1)-int(+inf), +inf, 10897 show). 10898set_def(minacc, evaluation, 10899 'Minimum clause accuracy', 10900 float(0.0)-float(1.0), 0.0, 10901 show). 10902set_def(mingain, tree, 10903 'Minimum expected gain', 10904 float(0.000001)-float(+inf), 0.05, 10905 show). 10906set_def(minpos, evaluation, 10907 'Minimum pos covered by a clause', 10908 int(0)-int(+inf), 1, 10909 show). 10910set_def(minposfrac, evaluation, 10911 'Minimum proportion of positives covered by a clause', 10912 float(0.0)-float(1.0), 0, 10913 show). 10914set_def(minscore, evaluation, 10915 'Minimum utility of an acceptable clause', 10916 float(-inf)-float(+inf), -inf, 10917 show). 10918set_def(moves, search-search_strategy, 10919 'Number of moves in a randomised local search', 10920 int(0)-int(+inf), 5, 10921 show). 10922set_def(newvars, search-search_space, 10923 'Existential variables in a clause', 10924 int(0)-int(+inf), +inf, 10925 show). 10926set_def(nodes, search-search_space, 10927 'Nodes to be explored in the search', 10928 int(1)-int(+inf), 5000, 10929 show). 10930set_def(noise, evaluation, 10931 'Maximum negatives covered', 10932 int(0)-int(+inf), 0, 10933 show). 10934set_def(nreduce_bottom, saturation, 10935 'Negative examples based reduction of bottom clause', 10936 [true, false], false, 10937 show). 10938set_def(openlist, search-search_space, 10939 'Beam width in a greedy search', 10940 int(1)-int(+inf), +inf, 10941 show). 10942set_def(optimise_clauses, miscellaneous, 10943 'Perform query Optimisation', 10944 [true, false], false, 10945 show). 10946set_def(permute_bottom, saturation, 10947 'Randomly permute order of negative literals in the bottom clause', 10948 [true, false], false, 10949 show). 10950set_def(portray_examples, miscellaneous, 10951 'Pretty print examples', 10952 [true, false], false, 10953 show). 10954set_def(portray_hypothesis, miscellaneous, 10955 'Pretty print hypotheses', 10956 [true, false], false, 10957 show). 10958set_def(portray_literals, miscellaneous, 10959 'Pretty print literals', 10960 [true, false], false, 10961 show). 10962set_def(portray_search, miscellaneous, 10963 'Pretty print search', 10964 [true, false], false, 10965 show). 10966set_def(print, miscellaneous, 10967 'Literals printed per line', 10968 int(1)-int(+inf), 4, 10969 show). 10970set_def(prior, miscellaneous, 10971 'Prior class distribution', 10972 prolog_term,'', 10973 show-ro). 10974set_def(proof_strategy, miscellaneous, 10975 'Current proof strategy', 10976 [restricted_sld, sld, user], restricted_sld, 10977 show). 10978set_def(prooftime, miscellaneous, 10979 'Theorem proving time', 10980 float(0.0)-float(+inf), +inf, 10981 show). 10982set_def(prune_tree, tree, 10983 'Tree pruning', 10984 [true, false], false, 10985 show). 10986set_def(recordfile, miscellaneous, 10987 'Log filename', 10988 write(filename),'', 10989 show). 10990set_def(record, miscellaneous, 10991 'Log to file', 10992 [true, false], false, 10993 show). 10994set_def(refineop, search-search_strategy, 10995 'Current refinement operator', 10996 [user, auto, scs, false],'', 10997 show-ro). 10998set_def(refine, search-search_strategy, 10999 'Nature of customised refinement operator', 11000 [user, auto, scs, false], false, 11001 show). 11002set_def(resample, search-search_strategy, 11003 'Number of times to resample an example', 11004 int(1)-int(+inf), 1, 11005 show). 11006set_def(rls_type, search-search_strategy, 11007 'Type of randomised local search', 11008 [gsat, wsat, rrr, anneal], gsat, 11009 show). 11010set_def(rulefile, miscellaneous, 11011 'Rule file', 11012 write(filename),'', 11013 show). 11014set_def(samplesize, search-search_strategy, 11015 'Size of sample', 11016 int(0)-int(+inf), 0, 11017 show). 11018set_def(scs_percentile, search-search_strategy, 11019 'Percentile of good clauses for SCS search', 11020 float(0.0)-float(100.0),'', 11021 show). 11022set_def(scs_prob, search-search_strategy, 11023 'Probability of getting a good clause in SCS search', 11024 float(0.0)-float(1.0),'', 11025 show). 11026set_def(scs_sample, search-search_strategy, 11027 'Sample size in SCS search', 11028 int(1)-int(+inf), '', 11029 show). 11030set_def(search, search-search_strategy, 11031 'Search Strategy', 11032 [bf, df, heuristic, ibs, ils, rls, scs, id, ic, ar, false], bf, 11033 show). 11034set_def(searchstrat, search-search_strategy, 11035 'Current Search Strategy', 11036 [bf, df, heuristic, ibs, ils, rls, scs, id, ic, ar], bf, 11037 show-ro). 11038set_def(searchtime, search-search_strategy, 11039 'Search time in seconds', 11040 float(0.0)-float(+inf), +inf, 11041 show). 11042set_def(skolemvars, miscellaneous, 11043 'Counter for non-ground examples', 11044 int(1)-int(+inf), 10000, 11045 show). 11046set_def(splitvars, saturation, 11047 'Split variable co-refencing', 11048 [true, false], false, 11049 show). 11050set_def(stage, miscellaneous, 11051 'Aleph processing mode', 11052 [saturation, reduction, command], command, 11053 show-ro). 11054set_def(store_bottom, saturation, 11055 'Store bottom', 11056 [true, false], false, 11057 show). 11058set_def(subsample, search-search_strategy, 11059 'Subsample for evaluating a clause', 11060 [true,false], false, 11061 show). 11062set_def(subsamplesize, search-search_strategy, 11063 'Size of subsample for evaluating a clause', 11064 int(1)-int(+inf), +inf, 11065 show). 11066set_def(temperature, search-search_strategy, 11067 'Temperature for randomised search annealing', 11068 float(0.0)-float(+inf), '', 11069 show). 11070set_def(test_neg, miscellaneous, 11071 'Negative examples for testing theory', 11072 read(filename),'', 11073 show). 11074set_def(test_pos, miscellaneous, 11075 'Positive examples for testing theory', 11076 read(filename),'', 11077 show). 11078set_def(threads, miscellaneous, 11079 'Number of threads', 11080 int(1)-int(+inf), 1, 11081 show). 11082set_def(train_neg, miscellaneous, 11083 'Negative examples for training', 11084 read(filename),'', 11085 show). 11086set_def(train_pos, miscellaneous, 11087 'Positive examples for training', 11088 read(filename),'', 11089 show). 11090set_def(tree_type, tree, 11091 'Type of tree to construct', 11092 [classification, class_probability, regression, model], '', 11093 show). 11094set_def(tries, search-search_strategy, 11095 'Number of restarts for a randomised search', 11096 int(1)-int(+inf), 10, 11097 show). 11098set_def(typeoverlap, miscellaneous, 11099 'Type overlap for induce_modes', 11100 float(0.0)-float(1.0), 0.95, 11101 show). 11102set_def(uniform_sample, search-search_strategy, 11103 'Distribution to draw clauses from randomly', 11104 [true, false], false, 11105 show). 11106set_def(updateback, miscellaneous, 11107 'Update background knowledge with clauses found on search', 11108 [true, false], true, 11109 noshow). 11110set_def(verbosity, miscellaneous, 11111 'Level of verbosity', 11112 int(1)-int(+inf), 1, 11113 show). 11114set_def(version, miscellaneous, 11115 'Aleph version', 11116 int(0)-int(+inf), 5, 11117 show-ro). 11118set_def(walk, search-search_strategy, 11119 'Random walk probability for Walksat', 11120 float(0.0)-float(1.0), '', 11121 show). 11122 11123 11124% the following needed for compatibility with P-Progol 11125special_consideration(search,ida,M):- 11126 set(search,bf,M), set(evalfn,coverage,M), !. 11127special_consideration(search,compression,M):- 11128 set(search,heuristic,M), set(evalfn,compression,M), !. 11129special_consideration(search,posonly,M):- 11130 set(search,heuristic,M), set(evalfn,posonly,M), !. 11131special_consideration(search,user,M):- 11132 set(search,heuristic,M), set(evalfn,user,M), !. 11133 11134special_consideration(refine,Refine,M):- 11135 set(refineop,Refine,M), !. 11136special_consideration(refineop,auto,M):- 11137 gen_auto_refine(M), !. 11138 11139special_consideration(portray_literals,true,M):- 11140 set(print,1,M), !. 11141 11142special_consideration(record,true,M):- 11143 noset(recordfile_stream,M), 11144 (setting(recordfile,F,M) -> 11145 aleph_open(F,append,Stream), 11146 set(recordfile_stream,Stream,M); 11147 true), !. 11148special_consideration(record,false,M):- 11149 noset(recordfile_stream,M), !. 11150special_consideration(recordfile,File,M):- 11151 noset(recordfile_stream,M), 11152 (setting(record,true,M) -> 11153 aleph_open(File,append,Stream), 11154 set(recordfile_stream,Stream,M); 11155 true), !. 11156special_consideration(good,true,M):- 11157 noset(goodfile_stream,M), 11158 (setting(goodfile,F,M) -> 11159 aleph_open(F,append,Stream), 11160 set(goodfile_stream,Stream,M); 11161 true), !. 11162special_consideration(good,false,M):- 11163 noset(goodfile_stream,M), !. 11164special_consideration(goodfile,File,M):- 11165 noset(goodfile_stream,M), 11166 (setting(good,true,M) -> 11167 aleph_open(File,append,Stream), 11168 set(goodfile_stream,Stream,M); 11169 true), !. 11170special_consideration(minscore,_,M):- 11171 aleph_abolish('$aleph_feature'/2,M), !. 11172special_consideration(_,_,_M). 11173 11174rm_special_consideration(portray_literals,_,M):- 11175 set_default(print,M), !. 11176rm_special_consideration(refine,_,M):- 11177 set_default(refineop,M), !. 11178rm_special_consideration(record,_,M):- 11179 noset(recordfile_stream,M), !. 11180rm_special_consideration(recordfile_stream,_,M):- 11181 (setting(recordfile_stream,S,M) -> close(S); true), !. 11182rm_special_consideration(good,_,M):- 11183 noset(goodfile_stream,M), !. 11184rm_special_consideration(goodfile_stream,_,M):- 11185 (setting(goodfile_stream,S,M) -> close(S); true), !. 11186rm_special_consideration(_,_,_M). 11187 11188 11189get_hyp((Head:-Body),M):- 11190 M:'$aleph_search'(pclause,pclause(Head,Body)), !. 11191get_hyp(Hypothesis,M):- 11192 M:'$aleph_global'(hypothesis,hypothesis(_,Hypothesis,_,_)). 11193 11194add_hyp(end_of_file,_M):- !. 11195add_hyp(Clause,M):- 11196 nlits(Clause,L), 11197 label_create(Clause,Label,M), 11198 extract_count(pos,Label,PCount), 11199 extract_count(neg,Label,NCount), 11200 retractall(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 11201 extract_pos(Label,P), 11202 extract_neg(Label,N), 11203 setting(evalfn,Evalfn,M), 11204 complete_label(Evalfn,Clause,[PCount,NCount,L],Label1,M), 11205 asserta(M:'$aleph_global'(hypothesis,hypothesis(Label1,Clause,P,N))). 11206 11207add_hyp(Label,Clause,P,N,M):- 11208 retractall(M:'$aleph_global'(hypothesis,hypothesis(_,_,_,_))), 11209 asserta(M:'$aleph_global'(hypothesis,hypothesis(Label,Clause,P,N))). 11210 11211add_theory(Label,Theory,PCover,NCover,M):- 11212 aleph_member(C,Theory), 11213 add_hyp(Label,C,PCover,NCover,M), 11214 update_theory(_,M), 11215 fail. 11216add_theory(_,_,PCover,NCover,M):- 11217 rm_seeds(pos,PCover,M), 11218 (setting(evalfn,posonly,M) -> rm_seeds(rand,NCover,M); true), 11219 M:'$aleph_global'(atoms_left,atoms_left(pos,PLeft)), 11220 interval_count(PLeft,PL), 11221 p1_message('atoms left'), p_message(PL), !. 11222 11223add_gcws(M):- 11224 retract(M:'$aleph_search'(gcwshyp,hypothesis(L,C,P,N))), 11225 asserta(M:'$aleph_global'(hypothesis,hypothesis(L,C,P,N))), 11226 update_theory(_,M), 11227 fail. 11228add_gcws(_M). 11229 11230 11231restorehyp(M):- 11232 retract(M:'$aleph_local'(pclause,pclause(Head,Body))), 11233 assertz(M:'$aleph_search'(pclause,pclause(Head,Body))), !. 11234restorehyp(M):- 11235 retract(M:'$aleph_local'(hypothesis,hypothesis(Label,Clause1,P,N))), 11236 asserta(M:'$aleph_global'(hypothesis,hypothesis(Label,Clause1,P,N))), !. 11237restorehyp(_). 11238 11239get_hyp_label(_,Label,_M):- var(Label), !. 11240get_hyp_label((_:-Body),[P,N,L],M):- 11241 nlits(Body,L1), 11242 L is L1 + 1, 11243 (M:'$aleph_search'(covers,covers(_,P))-> true; 11244 covers(_,M), 11245 M:'$aleph_search'(covers,covers(_,P))), 11246 (M:'$aleph_search'(coversn,coverns(_,N))-> true; 11247 coversn(_,M), 11248 M:'$aleph_search'(coversn,coversn(_,N))). 11249 11250 11251show_global(Key,Pred,M):- 11252 M:'$aleph_global'(Key,Pred), 11253 copy_term(Pred,Pred1), numbervars(Pred1,0,_), 11254 aleph_writeq(Pred1), write('.'), nl, 11255 fail. 11256show_global(_,_,_M). 11257 11258aleph_portray(hypothesis,true,M):- 11259 M:aleph_portray(hypothesis), !. 11260aleph_portray(hypothesis,false,M):- 11261 p_message('hypothesis'), 11262 hypothesis(Head,Body,_,M), 11263 pp_dclause((Head:-Body),M), !. 11264aleph_portray(_,hypothesis,_M):- !. 11265 11266aleph_portray(search,true,M):- 11267 M:aleph_portray(search), !. 11268aleph_portray(search,_,_M):- !. 11269 11270aleph_portray(train_pos,true,M):- 11271 M:aleph_portray(train_pos), !. 11272aleph_portray(train_pos,_,M):- 11273 !, 11274 setting(train_pos,File,M), 11275 show_file(File). 11276 11277aleph_portray(train_neg,true,M):- 11278 M:aleph_portray(train_neg), !. 11279aleph_portray(train_neg,_,M):- 11280 !, 11281 setting(train_neg,File,M), 11282 show_file(File). 11283 11284aleph_portray(test_pos,true,M):- 11285 M:aleph_portray(test_pos), !. 11286aleph_portray(test_pos,_,M):- 11287 !, 11288 setting(test_pos,File,M), 11289 show_file(File). 11290 11291aleph_portray(test_neg,true,M):- 11292 M:aleph_portray(test_neg), !. 11293aleph_portray(test_neg,_,M):- 11294 !, 11295 setting(test_neg,File,M), 11296 show_file(File). 11297 11298aleph_portray(Lit,true,M):- 11299 M:aleph_portray(Lit), !. 11300aleph_portray(Lit,_,_M):- 11301 aleph_writeq(Lit). 11302 11303aleph_writeq(Lit):- 11304 write_term(Lit,[numbervars(true),quoted(true)]). 11305 11306show_file(File):- 11307 aleph_open(File,read,Stream), 11308 repeat, 11309 read(Stream,Clause), 11310 (Clause = end_of_file -> close(Stream), ! 11311 ; 11312 writeq(Clause), write('.'), nl, 11313 fail). 11314 11315time_loop(0,_,[]):- !. 11316time_loop(N,P,[T|Times]):- 11317 wallclock(S), 11318 , 11319 wallclock(F), 11320 T is F - S, 11321 N1 is N - 1, 11322 time_loop(N1,P,Times). 11323 11324list_profile :- 11325 % get number of calls for each profiled procedure 11326 findall(D-P,profile_data(P,calls,D),LP), 11327 % sort them 11328 sort(LP,SLP), 11329 % and output (note the most often called predicates will come last 11330 write_profile_data(SLP). 11331 11332write_profile_data([]). 11333 write_profile_data([D-P|SLP]) :- 11334 % just swap the two calls to get most often called predicates first. 11335 format('~w: ~w~n', [P,D]), 11336 write_profile_data(SLP). 11337 11338 11339 11340 11341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 11342% F I N A L C O M M A N D S 11343 11344 11345 11346:- multifile sandbox:safe_meta/2.11347 11348sandbox:safe_meta(aleph:induce(_), []). 11349sandbox:safe_meta(aleph:induce_tree(_), []). 11350sandbox:safe_meta(aleph:induce_max(_), []). 11351sandbox:safe_meta(aleph:induce_cover(_), []). 11352sandbox:safe_meta(aleph:induce_incremental(_), []). 11353sandbox:safe_meta(aleph:induce_clauses(_), []). 11354sandbox:safe_meta(aleph:induce_theory(_), []). 11355sandbox:safe_meta(aleph:induce_modes(_), []). 11356sandbox:safe_meta(aleph:induce_features(_), []). 11357sandbox:safe_meta(aleph:induce_constraints(_), []). 11358sandbox:safe_meta(aleph:sat(_), []). 11359sandbox:safe_meta(aleph:aleph_set(_,_), []). 11360sandbox:safe_meta(aleph:aleph_setting(_,_), []). 11361sandbox:safe_meta(aleph:noset(_), []). 11362sandbox:safe_meta(aleph:model(_), []). 11363sandbox:safe_meta(aleph:mode(_,_), []). 11364sandbox:safe_meta(aleph:modeh(_,_), []). 11365sandbox:safe_meta(aleph:modeb(_,_), []). 11366sandbox:safe_meta(aleph:show(_), []). 11367sandbox:safe_meta(aleph:hypothesis(_,_,_), []). 11368sandbox:safe_meta(aleph:rdhyp(_), []). 11369sandbox:safe_meta(aleph:addhyp_i(_), []). 11370sandbox:safe_meta(aleph:sphyp_i(_), []). 11371sandbox:safe_meta(aleph:covers(_), []). 11372sandbox:safe_meta(aleph:coversn(_), []). 11373sandbox:safe_meta(aleph:reduce(_), []). 11374sandbox:safe_meta(aleph:abducible(_), []). 11375sandbox:safe_meta(aleph:bottom(_), []). 11376sandbox:safe_meta(aleph:commutative(_), []). 11377sandbox:safe_meta(aleph:symmetric(_), []). 11378sandbox:safe_meta(aleph:lazy_evaluate(_), []). 11379sandbox:safe_meta(aleph:positive_only(_), []). 11380sandbox:safe_meta(aleph:example_saturated(_), []). 11381 11382sandbox:safe_meta(aleph:addgcws_i(_), []). 11383sandbox:safe_meta(aleph:rmhyp_i(_), []). 11384sandbox:safe_meta(aleph:addgcws_i(_), []). 11385sandbox:safe_meta(aleph:good_clauses(_), [])
aleph
A Learning Engine for Proposing Hypotheses - ALEPH
Version 5
Aleph is an Inductive Logic Programming system developed by Ashwin Srinivasan:
http://www.cs.ox.ac.uk/activities/machlearn/Aleph/
Aleph v.5 was ported to SWI-Prolog by Fabrizio Riguzzi and Paolo Niccolò Giubelli.
Aleph is freely available for academic purposes. % If you intend to use it for commercial purposes then % please contact Ashwin Srinivasan first. %