1% MODULE kb EXPORTS
    2:- module( kb, 
    3	[ init_kb/1,                   % Read, store and evaluate background knowledge
    4                                       % and examples, label them 'usr'
    5          init_kb/2,                   % same as before, using specified label
    6          save_kb/1,                   % Save knowledge base to qof-file
    7          consult_kb/1,                % Consult qof-file without additional processing
    8          gen_id/1,                    % generates a new kb id
    9	  id_count/1,                  % last generated id
   10          store_clause/4,              % Store horn-clause or Clist in kb
   11          store_clauses/2,             % Store a list of Clauses in kb 
   12          store_clauses/3,             % as store_clauses,but returns clauseIDs 
   13          store_ex/3,                  % Store example in kb
   14          get_example/3,               %          example          |
   15          get_clause/5,                % Retrieve clause           | from knowledge base
   16          get_fact/4,                  %          fact             |
   17          get_evaluation/2,            %          clause-evaluation|
   18          clear_kb/0,                  % Remove everything
   19          delete_clause/1,             % Remove clauses one by one
   20          delete_example/1,            % Remove examples one by one
   21          delete_all/1,
   22          random_ex/1,                 % one random pos. example
   23          two_random_ex/2,             % 2 random pos. examples
   24          two_random_uncovered_ex/2,   % 2 random uncovered pos. examples
   25          two_random_ex_from_list/3,   % 2 random examples from given list
   26          i_random_ex/2,               % i random pos. examples
   27          shortest_clause/1,           % shortest clause
   28          shortest_clause/2,           % shortest clause with label
   29          two_shortest_clauses/2,      % 2 shortest clauses
   30          two_shortest_clauses/3,      % 2 shortest clauses with label
   31          shortest_ex/1,               % shortest pos. example
   32          shortest_uncovered_ex/1,     % shortest uncovered pos. example
   33          shortest_uncovered_ex/2,     % shortest ex from list
   34          two_shortest_ex/2,           % 2 shortest pos. examples
   35          two_shortest_uncovered_ex/2, % 2 shortest pos. uncovered ex
   36          all_shortest_ex/1,           % list of all shortest pos. examples
   37          all_shortest_uncovered_ex/1, % list of all shortest uncovered pos. examples
   38          no_rules/0,
   39          no_pos_examples/0,
   40          no_neg_examples/0,
   41          no_examples/0,
   42          flatten_kb/0,
   43          flatten_rules/0,
   44          unflatten_kb/0,
   45	  delete_covered_examples/0,
   46	  get_predlist/1,
   47	  rename/3,
   48          known/6,
   49          ex/3,
   50          assertallz/1,
   51          interpretable_predicate/1
   52     ]).   53
   54% IMPORTS
   55:- use_module(home(div_utils),
   56              [body2list/2,mysetof/3]).   57:- use_module(home(evaluation),
   58              [eval_examples/0,complexity/2,evaluated/1,change_evaluated/1]).   59:- use_module(home(argument_types),
   60              [type_restriction/2,verify_types/0]).   61:- use_module(home(flatten),
   62              [flatten_clause/2,unflatten_clause/2]).   63:- use_module(home(interpreter),
   64              [prooftrees/3]).   65:- use_module_if_exists(library(prompt)).   66:- use_module_if_exists(library(ask), 
   67              [yesno/1]).   68:- use_module_if_exists(library(basics),
   69              [nonmember/2,member/2]).   70:- use_module_if_exists(library(random),
   71              [random_select/3]).   72
   73% METAPREDICATES
   74% none
   75
   76
   77:- dynamic id_count/1, ex/3, known/6.   78
   79
   80%***********************************************************************
   81%*	
   82%* module: kb.pl        					
   83%*									
   84%* author: B.Jung, M.Mueller, I.Stahl, B.Tausend              date:12/92	
   85%*									
   86%* changed:								
   87%*									
   88%* description:	- knowledge base handling
   89%*              - flatten / unflatten knowledge base ( clauses & examples)
   90%*              - heuristics to select examples from kb randomly
   91%*		  or according to their complexities.
   92%*		  It is assumed that the examples' current evaluation
   93%*		  corresponds to the current rules.
   94%*									
   95%* see also:	
   96%*									
   97%***********************************************************************
   98
   99
  100%***********************************************************************
  101%*									
  102%* predicate: 	gen_id/1							
  103%*									
  104%* syntax:	gen_id(-New)							
  105%*									
  106%* args: -New kbID								
  107%*									
  108%* description:	generates a new kb id	
  109%*
  110%* example:
  111%*
  112%* peculiarities:
  113%*
  114%* see also:
  115%*									
  116%***********************************************************************
  117
  118gen_id(New) :- retract(id_count(Old)),
  119               New is Old+1,
  120               asserta(id_count(New)).
  121gen_id(1) :- asserta(id_count(1)).
  122
  123
  124%****************************************************************************************
  125%* 
  126%*  predicate: init_kb/1,2
  127%*
  128%*  syntax: init_kb (+Filename)
  129%*          init_kb (+Filename, +Label)
  130%*
  131%*  args:
  132%*
  133%*  description: the file Filename may contain Horn clauses "H:-B." and 
  134%*       "H.", examples "ex(Fact,Class)" and comments "%* blabla".
  135%*       Examples are stored in the kb as "ex(ID, Fact, Class)",
  136%*       clauses as
  137%*          "known(ID,Head,Body,Clist,Label,evaluation(1,2,3,4,5,6,7,8,9))".
  138%*       where ID ... unique kb identifier (a natural number)
  139%*             Class ... +,-,?
  140%*             Clist ... clause in list representation
  141%*                       [head:p, body1:n, body2:n, body3:r, ...]. Each literal is
  142%*                       marked p(positiv), n(negativ) or r(negativ + redundant)
  143%*             Label ... e.g. the generating operator
  144%*                       default used for init_kb/1: usr
  145%*             evaluation ... of the clauses w.r.t. the examples:
  146%*               1... #applications of the clause
  147%*               2... #definitively positive examples covered by the clause
  148%*               3... list of definitively positive examples covered by the clause
  149%*                    of the form [...exID:Fact........]
  150%*               4... #definitively negative  examples covered by the clause
  151%*               5... list of definitively negative  examples covered by the clause
  152%*                    of the form [...exID:Fact........]
  153%*               6... #probably positive examples covered by the clause
  154%*                    i.e. instantiations of the clause used in successful 
  155%*                    proofs of positive examples
  156%*               7... list of probably positive examples covered by the clause
  157%*                    [...exID:Fact........] where exID is the example of which the 
  158%*                    proof uses fact as subgoal
  159%*               8... #probably negative  examples covered by the clause
  160%*                    i.e. instantiations of the clause used in successful
  161%*                     proofs of negative examples
  162%*               9... list of probably negative examples covered by the clause
  163%*                    [...exID:Fact........] where exID is the example of which the 
  164%*                    proof uses fact as subgoal
  165%*
  166%*       For each example, all possible prooftrees are stored in the kb:
  167%*       "prooftrees(ID,M,Trees)" where M is success or fail and Trees contains
  168%*       all successful or failing proofs of example ID.
  169%*
  170%*       init_kb can be used successively for different files
  171%*
  172%* example:
  173%*
  174%* peculiarities:
  175%*
  176%*
  177%* see also:
  178%*
  179%*****************************************************************************************
  180
  181init_kb(Filename) :- init_kb(Filename, usr).
  182
  183init_kb(Filename, Origin) :- 
  184        open(Filename,read,S),
  185           repeat, read(S,Term),
  186           store_term(Term,Origin),
  187        close(S), !,
  188	eval_examples,
  189        verify_types.
  190
  191
  192%***********************************************************************
  193%*									
  194%* predicate:	consult_kb/1
  195%*									
  196%* syntax:	consult_kb(+ Filename)							
  197%*									
  198%* args:								
  199%*									
  200%* description:	Restore knowledge base from qof-file which was produced by save_kb/1.
  201%*									
  202%* example:								
  203%*									
  204%* peculiarities:	none				
  205%*									
  206%* see also:								
  207%*									
  208%***********************************************************************
  209
  210consult_kb(Filename) :- clear_kb,
  211                        [Filename].
  212
  213
  214%***********************************************************************
  215%*									
  216%* predicate:	save_kb/1
  217%*									
  218%* syntax:	save_kb(+ Filename)						
  219%*									
  220%* args: Filename: name of a file (.qof)					
  221%*									
  222%* description:	 Save snapshot of current knowledge base as compiled file
  223%*
  224%* example:
  225%*									
  226%* peculiarities: suffix, .qof is recommended for Filename.	
  227%*
  228%* see also:
  229%*									
  230%***********************************************************************
  231
  232save_kb(Filename) :- 
  233	save_predicates([known/6, ex/3, prooftrees/3, id_count/1,
  234                         type_restriction/2,evaluated/1],
  235                         Filename).
  236
  237
  238%***********************************************************************
  239%*									
  240%* predicate:	clear_kb/0							
  241%*									
  242%* syntax:	-							
  243%*									
  244%* args: 	none						
  245%*									
  246%* description:	deletes all rules and examples from the kb
  247%* 									
  248%* example:									
  249%*									
  250%* peculiarities:	none				
  251%*									
  252%* see also:								
  253%*									
  254%***********************************************************************
  255
  256clear_kb :- %nl,yesno('Delete all knowledge and examples (y/n) '),
  257            retractall(known(_,_,_,_,_,_)), retractall(ex(_,_,_)),
  258            retractall(prooftrees(_,_,_)),retractall(id_count(_)),
  259            retractall(type_restriction(_,_)),retractall(evaluated(_)).
  260
  261
  262
  263%***********************************************************************
  264%*									
  265%* predicate:	store_term/2							
  266%*									
  267%* syntax:	store_term(+Term,+Label)						
  268%*									
  269%* args: 								
  270%*									
  271%* description:	stores clause Term or example Term read from the 
  272%*		input file during init_kb in the kb using known/6
  273%* 		or ex/3							
  274%*									
  275%* example:								
  276%*									
  277%* peculiarities:	none				
  278%*									
  279%* see also:								
  280%*									
  281%***********************************************************************
  282
  283store_term(end_of_file,_) :- !.
  284store_term(ex(F,C),_):-
  285        gen_id(ID),
  286        assertz(ex(ID,F,C)),
  287        !, fail.
  288store_term((H:- B),O) :- 
  289        body2list(B,L),
  290        gen_id(ID), 
  291        assertz(known(ID,H,B,[H:p|L],O,
  292                evaluation(0,0,[],0,[],0,[],0,[]))),
  293        !, fail.
  294store_term(type_restriction(M,A),_):-
  295        assertz(argument_types:type_restriction(M,A)),
  296        !,fail.
  297store_term(H,O) :- 
  298        gen_id(ID), 
  299        assertz(known(ID,H,true,[H:p],O,
  300                      evaluation(0,0,[],0,[],0,[],0,[]))), !, fail.
  301
  302
  303%***********************************************************************
  304%*									
  305%* predicate:	store_clause/4
  306%*									
  307%* syntax:	store_clause (?prolog-clause,?clause-list,+label,-ID)	
  308%*									
  309%* args:								
  310%*									
  311%* description:	Store new clause in knowledge base (provide either horn-clause	
  312%*	 or clause-list), label it and receive the unique clause-ID.	
  313%*       If store_clause is called with ID instantiated, it will fail if ID is 
  314%*       already in use in the knowledge-base. If not, ID will be used.
  315%*									
  316%* example:								
  317%*									
  318%* peculiarities:	none				
  319%*									
  320%* see also:								
  321%*									
  322%***********************************************************************
  323
  324store_clause(A,B,_,ID) :-
  325        (nonvar(ID), (known(ID,_,_,_,_,_);ex(ID,_,_)))
  326        -> !, fail ; 
  327        var(A), var(B) -> !, fail ;                        
  328        fail.
  329store_clause((H:- B), [H:p|L], Label, ID) :- 
  330        body2list(B,L),
  331        (var(ID) -> gen_id(ID);
  332            id_count(Top),
  333            ID =< Top          ),
  334        (var(Label) -> Label = usr ; true),
  335        assertz(known(ID,H,B,[H:p|L],Label,evaluation(0,0,[],0,[],0,[],0,[]))), !,
  336        change_evaluated(no).
  337store_clause(H, [H:p], Label, ID) :-
  338        (var(ID) -> gen_id(ID);
  339            id_count(Top),
  340            ID =< Top          ),
  341        (var(Label) -> Label = usr ; true),
  342        assertz(known(ID,H,true,[H:p],Label,evaluation(0,0,[],0,[],0,[],0,[]))), !,
  343        change_evaluated(no).
  344
  345
  346
  347%***********************************************************************
  348%*									
  349%* predicate:	store_clauses/2							
  350%*									
  351%* syntax:	store_clauses(+List_of_Clauses,+Label)
  352%*									
  353%* args: List_of_Clauses ... list of prolog clauses
  354%*									
  355%* description:	Same as store_clause/4 for a list of clauses
  356%*									
  357%* example:								
  358%*									
  359%* peculiarities:	none				
  360%*									
  361%* see also:								
  362%*									
  363%***********************************************************************
  364
  365store_clauses([],_).
  366store_clauses([C|R],Label):-
  367   store_clause(C,_,Label,_),
  368   store_clauses(R,Label).
  369
  370
  371%***********************************************************************
  372%*									
  373%* predicate:	store_clauses/3							
  374%*									
  375%* syntax:	store_clauses(+List_of_Clauses,+Label,-IDlist)
  376%*									
  377%* args: List_of_Clauses ... list of prolog clauses
  378%*       IDlist... kb-ids for the clauses
  379%*									
  380%* description:	Same as store_clauses/2, but returns IDs of the clauses
  381%*									
  382%* example:								
  383%*									
  384%* peculiarities:	none				
  385%*									
  386%* see also:								
  387%*									
  388%***********************************************************************
  389
  390store_clauses([],_,[]).
  391store_clauses([C|R],Label,[ID|R1]):-
  392   store_clause(C,_,Label,ID),
  393   store_clauses(R,Label,R1).
  394
  395
  396%***********************************************************************
  397%*									
  398%* predicate:	store_ex/3							
  399%*									
  400%* syntax:	store_ex(?fact,?classification,-ID)
  401%*									
  402%* args:								
  403%*									
  404%* description:	Store new example in knowledge base and receive the 
  405%*	unique identification number.
  406%* 	If it is called with ID already instantiated: see above.	
  407%*									
  408%* example:								
  409%*									
  410%* peculiarities:	none				
  411%*									
  412%* see also:								
  413%*									
  414%***********************************************************************
  415
  416store_ex(F,Class,ID):-
  417    ex(ID1,F1,Class1),F == F1,!,
  418    Class = Class1, ID = ID1.
  419store_ex(F,_,ID) :-
  420        (nonvar(ID), (ex(ID,_,_);known(ID,_,_,_,_,_)))
  421        -> !, fail ;
  422	var(F) -> !, fail;
  423	fail.
  424store_ex(Fact, Class, ID) :-
  425        (var(ID) -> gen_id(ID);
  426            id_count(Top),
  427            ID =< Top          ),
  428        assertz(ex(ID,Fact,Class)), !,
  429        change_evaluated(no).
  430
  431
  432
  433%***********************************************************************
  434%*									
  435%* predicate: get_example/3
  436%*            get_clause/5
  437%*            get_fact/4
  438%*            get_evaluation/2
  439%*
  440%* syntax: get_example (? ID, ? Example, ? Classification)
  441%*         get_clause (? ID, ? Head, ? Body, ? Clist, ? Label)
  442%*         get_fact (? ID, ? Fact, ? Clist, ? Label)
  443%*         get_evaluation (+ ID, - Evaluation)
  444%*
  445%* args:								
  446%*		
  447%* description:	read example/clause/fact or clause evaluation from the kb
  448%*									
  449%* example:								
  450%*									
  451%* peculiarities:	none				
  452%*									
  453%* see also:								
  454%*									
  455%***********************************************************************
  456
  457get_example(ID, F, C) :- ex(ID, F, C).
  458get_clause(ID, H, B, L, O) :- 
  459     known(ID, H, B, L, O, _).        
  460get_fact(ID, F, L, O) :- 
  461     known(ID, F, true, L, O, _).
  462get_evaluation(ID, Eval) :- 
  463     known(ID,_,_,_,_,Eval).
  464
  465
  466%***********************************************************************
  467%*									
  468%* predicate:	delete_clause/1 , delete_example/1, delete_all/1
  469%*									
  470%* syntax: delete_clause(+ ID) , delete_example(+ ID), 
  471%*         delete_all(+list_of_clauseIDs)
  472%*									
  473%* args:								
  474%*									
  475%* description:	delete clause(s)/example(s) with identifier(s) ID(list_of_clauseIDs)
  476%*									
  477%* example:								
  478%*									
  479%* peculiarities:	none				
  480%*									
  481%* see also:								
  482%*									
  483%***********************************************************************
  484
  485delete_clause(ID) :- 
  486        retract(known(ID,_,_,_,_,_)),
  487        change_evaluated(no).
  488delete_example(ID) :- 
  489        retract(ex(ID,_,_)),
  490        change_evaluated(no).
  491
  492
  493delete_all([]) :- !. 
  494delete_all([Id1|Rest]) :-
  495	delete_clause(Id1), !,
  496	delete_all(Rest).
  497delete_all([Id1|Rest]) :-
  498	delete_example(Id1), !,
  499	delete_all(Rest).
  500
  501
  502%***********************************************************************
  503%*									
  504%* predicate: interpretable_predicate/1
  505%*									
  506%* syntax:	interpretable_predicate(-Term)
  507%*									
  508%* args: Term .. prolog term with principal funtor P/N
  509%*									
  510%* description:	succeeds if rules or examples for P/N are in the kb
  511%*									
  512%* example:								
  513%*									
  514%* peculiarities:	none				
  515%*									
  516%* see also:								
  517%*									
  518%***********************************************************************
  519
  520interpretable_predicate(A):-
  521    functor(A,F,N),functor(A1,F,N),
  522    ( get_clause(_,A1,_,_,_) ; get_example(_,A1,_) ).
  523
  524
  525%***********************************************************************
  526%*									
  527%* predicate: assertallz/1
  528%*									
  529%* syntax:    assertallz(+List)
  530%*									
  531%* args:								
  532%*									
  533%* description:	asserts all elements of List at the end of the kb
  534%*									
  535%* example:								
  536%*									
  537%* peculiarities:	none				
  538%*									
  539%* see also:								
  540%*									
  541%***********************************************************************
  542
  543assertallz([]).
  544assertallz([X|R]):-
  545   assertz(X),
  546   assertallz(R).
  547
  548
  549%***********************************************************************
  550%*									
  551%* predicate:	rename_clause/3							
  552%*									
  553%* syntax:	rename (+ ID_list,+ Old_name,+ New_name )
  554%*									
  555%* args: Old_name, New_name ... atoms
  556%*									
  557%* description: rename	every occurence of predicate 'Old_name' to 'New_name' 
  558%*		in a set of clauses given as
  559%* 		a list of kb-references (Id-list). 'New_name' should be atomic.	
  560%*									
  561%* example:								
  562%*									
  563%* peculiarities:	none				
  564%*									
  565%* see also:								
  566%*									
  567%***********************************************************************
  568
  569rename([],_,_) :- !.
  570rename([Id1|Rest], Old, New) :-
  571	get_clause(Id1,_,_,Clist,Label),
  572	rename_clause(Clist,NewClause,Old,New),
  573	delete_clause(Id1),
  574	store_clause(_,NewClause,Label,Id1), !,
  575	rename(Rest, Old, New).
  576
  577
  578%***********************************************************************
  579%*									
  580%* predicate:	rename_clause/4							
  581%*									
  582%* syntax: rename_clause(+CL,-CL1,+Old,+New)
  583%*									
  584%* args: CL,CL1.. clauses in list representation
  585%*       Old, New atoms 								
  586%*									
  587%* description:	replaces each literal Old(...) within CL with New(...)
  588%*									
  589%* example:								
  590%*									
  591%* peculiarities:	none				
  592%*									
  593%* see also:								
  594%*									
  595%***********************************************************************
  596
  597rename_clause([], [], _, _) :- !.
  598rename_clause([Lit:X|Rest], [NewLit:X|NewRest], Old, New) :-
  599	( Lit =.. [Old|Args] ->
  600	    NewLit =.. [New|Args];
  601	    NewLit = Lit
  602	), !,
  603	rename_clause(Rest,NewRest,Old,New).
  604
  605
  606%***********************************************************************
  607%*									
  608%* predicate:	random_ex/1							
  609%*									
  610%* syntax: random_ex(-ID)								
  611%*									
  612%* args: ID exampleID								
  613%*									
  614%* description:	chooses randomly an example from the kb
  615%*									
  616%* example:								
  617%*									
  618%* peculiarities:	none				
  619%*									
  620%* see also:								
  621%*									
  622%***********************************************************************
  623
  624random_ex(ID1):-
  625        findall(ID, get_example(ID,_,'+'), Bag),
  626        random_select( ID1, Bag, _ ).
  627
  628
  629%***********************************************************************
  630%*									
  631%* predicate: two_random_ex/2								
  632%*									
  633%* syntax: two_random_ex(-ID1,-ID2)
  634%*									
  635%* args: ID1,ID2 exampleIDs								
  636%*									
  637%* description:	chooses randomly two examples from the kb
  638%*									
  639%* example:								
  640%*									
  641%* peculiarities:	none				
  642%*									
  643%* see also:								
  644%*									
  645%***********************************************************************
  646
  647two_random_ex(ID1,ID2):-
  648        findall(ID, get_example(ID,_,'+'), Bag),
  649        ( random_select( ID1, Bag, Residue) ;select( ID1, Bag, Residue) ) ,
  650        ( random_select( ID2, Residue, _) ; select( ID2, Residue, _) ).
  651        % sometimes random_select/3 doesn't work properly
  652
  653two_random_ex_from_list(List,ID1,ID2):-
  654        random_select( ID1, List, Residue),
  655        random_select( ID2, Residue, _).
  656
  657two_random_uncovered_ex(ID1,ID2):-
  658        findall( ID, ( kb:prooftrees(ID,fail,_),
  659                       get_example(ID,_,'+')
  660                     ), 
  661                Uncovered),
  662        two_random_ex_from_list(Uncovered,ID1,ID2).        
  663
  664
  665%***********************************************************************
  666%*									
  667%* predicate: i_random_ex/2								
  668%*									
  669%* syntax: i_random_ex(+I,-ExIDs)
  670%*									
  671%* args: I .. number								
  672%*									
  673%* description:	selects randomly I examples from the kb
  674%*									
  675%* example:								
  676%*									
  677%* peculiarities:	none				
  678%*									
  679%* see also:								
  680%*									
  681%***********************************************************************
  682
  683i_random_ex(I,Examples):-
  684        I > 0,
  685        findall(ID, get_example(ID,_,'+'), Bag),
  686        length(Bag,J),
  687        ( J =< I      ->  Examples = Bag
  688        ;
  689        i_random_ex( I, Bag, Examples) 
  690        ).
  691i_random_ex( 0,_,[]):-!.
  692i_random_ex( N, Bag, [ ID | Rest]):-
  693        random_select( ID, Bag, Residue),
  694        M is N - 1,
  695        i_random_ex( M , Residue, Rest).
  696
  697
  698%***********************************************************************
  699%*									
  700%* predicate: shortest_clause/1								
  701%*									
  702%* syntax: shortest_clause(-ID:C)
  703%*									
  704%* args: ID .. clauseID, C ... complexity of the corresponding clause
  705%*									
  706%* description:	selects the shortest clause from the kb 
  707%*									
  708%* example:								
  709%*									
  710%* peculiarities:	none				
  711%*									
  712%* see also:								
  713%*									
  714%***********************************************************************
  715
  716shortest_clause(ID1:C1):- 
  717        shortest_clause( _,ID1:C1). 
  718        
  719shortest_clause(Label,ID1:C1):-
  720        findall( ID:C, ( get_clause(ID,_,_,Clause,Label),
  721                        complexity(Clause,C)
  722                      ),
  723                Bag),
  724        shortest(Bag,ID1:C1,_).
  725       
  726
  727%***********************************************************************
  728%*									
  729%* predicate: two_shortest_clauses/2
  730%*									
  731%* syntax: two_shortest_clauses(-ID1:CL1,-ID2:CL2)
  732%*									
  733%* args: ID1/2 .. clauseIDs, CL1/2 ... complexities of the corresponding clauses
  734%*									
  735%* description:	selects two shortest clauses from kb
  736%*									
  737%* example:								
  738%*									
  739%* peculiarities:	none				
  740%*									
  741%* see also:								
  742%*									
  743%***********************************************************************
  744
  745two_shortest_clauses(ID1:C1,ID2:C2):-
  746       two_shortest_clauses(_ ,ID1:C1,ID2:C2).
  747
  748two_shortest_clauses(Label,ID1:C1,ID2:C2):-
  749       findall( ID:C, ( get_clause(ID,_,_,Clause,Label),
  750                        complexity(Clause,C)
  751                      ),
  752                Bag),
  753       two_shortest(Bag, ID1:C1, ID2:C2).
  754
  755
  756
  757%***********************************************************************
  758%*									
  759%* predicate: shortest_ex/1
  760%*									
  761%* syntax: shortest_ex(-ID:C)								
  762%*									
  763%* args: ID .. exID, C .. complexity of the corresponding example
  764%*									
  765%* description:	selects the shortest example from kb
  766%*									
  767%* example:								
  768%*									
  769%* peculiarities:	none				
  770%*									
  771%* see also:								
  772%*									
  773%***********************************************************************
  774
  775shortest_ex(ID1:C1):-
  776        findall( ID:C, ( get_example(ID,Ex,'+'),
  777                        complexity(Ex,C)
  778                      ),
  779                Bag),
  780        shortest(Bag,ID1:C1,_).
  781       
  782
  783%***********************************************************************
  784%*									
  785%* predicate:	two_shortest_ex/2							
  786%*									
  787%* syntax: two_shortest_ex(-ID1:C1,-ID2:C2)
  788%*									
  789%* args: ID1/2 .. exIDs, C1/2 .. complexities of the corresponding examples
  790%*									
  791%* description:	selects two shortest example from kb
  792%*									
  793%* example:								
  794%*									
  795%* peculiarities:	none				
  796%*									
  797%* see also:								
  798%*									
  799%***********************************************************************
  800
  801two_shortest_ex(ID1:C1,ID2:C2):-
  802       findall( ID:C, ( get_example(ID,Ex,'+'),
  803                        complexity(Ex,C)
  804                      ),
  805                Bag),
  806       two_shortest(Bag, ID1:C1, ID2:C2).
  807
  808
  809%***********************************************************************
  810%*									
  811%* predicate:	shortest_uncovered_ex/1							
  812%*									
  813%* syntax: shortest_uncovered_ex(-ExID)
  814%*									
  815%* args:								
  816%*									
  817%* description:	selects the shortest example that is not covered by the kb
  818%*									
  819%* example:								
  820%*									
  821%* peculiarities:	none				
  822%*									
  823%* see also:								
  824%*									
  825%***********************************************************************
  826
  827shortest_uncovered_ex(ID1):-
  828       findall( ID:C, ( kb:prooftrees(ID,fail,_), 
  829                        get_example(ID,Ex,'+'),
  830                        complexity(Ex,C) ), 
  831                Uncovered),
  832       shortest( Uncovered, ID1:_, _Residue).
  833
  834
  835%***********************************************************************
  836%*									
  837%* predicate:	shortest_uncovered_ex/2							
  838%*									
  839%* syntax: shortest_uncovered_ex(+ExIds,-ExId)
  840%*									
  841%* args: ExIds .. list of Ids of uncovered examples
  842%*									
  843%* description:	selects the shortest example among ExIds
  844%*									
  845%* example:								
  846%*									
  847%* peculiarities:	none				
  848%*									
  849%* see also:								
  850%*									
  851%***********************************************************************
  852
  853shortest_uncovered_ex(Uncovered,ID1):-
  854       add_complexities(Uncovered,Bag),
  855       shortest( Bag, ID1:_, _Residue).
  856
  857
  858%***********************************************************************
  859%*									
  860%* predicate:	two_shortest_uncovered_ex/2
  861%*									
  862%* syntax: two_shortest_uncovered_ex(-ExID1,-ExID2)
  863%*									
  864%* args:								
  865%*									
  866%* description:	selects two shortest examples that are not covered by the kb
  867%*									
  868%* example:								
  869%*									
  870%* peculiarities:	none				
  871%*									
  872%* see also:								
  873%*									
  874%***********************************************************************
  875
  876two_shortest_uncovered_ex(ID1,ID2):-
  877       findall( ID:C, ( kb:prooftrees(ID,fail,_), 
  878                        get_example(ID,Ex,'+'),
  879                        complexity(Ex,C) ), 
  880                Uncovered),
  881       two_shortest(Uncovered, ID1:_, ID2:_).
  882
  883
  884%***********************************************************************
  885%*									
  886%* predicate:	all_shortest_ex/1							
  887%*									
  888%* syntax: all_shortest_ex(-ExIds)
  889%*									
  890%* args:								
  891%*									
  892%* description: selects all shortest examples from kb
  893%*									
  894%* example:								
  895%*									
  896%* peculiarities:	none				
  897%*									
  898%* see also:								
  899%*									
  900%***********************************************************************
  901
  902all_shortest_ex(Bag):-
  903       shortest_ex( _:C1),
  904       findall( ID, ( get_example(ID,Ex,'+'), complexity(Ex,C1) ), Bag).
  905
  906
  907%***********************************************************************
  908%*									
  909%* predicate:	all_shortest_uncovered_ex/1
  910%*									
  911%* syntax: all_shortest_uncovered_ex(-ExIds)
  912%*									
  913%* args:								
  914%*									
  915%* description: selects all shortest uncovered examples from kb
  916%*
  917%* example:								
  918%*									
  919%* peculiarities:	none				
  920%*									
  921%* see also:								
  922%*									
  923%***********************************************************************
  924
  925all_shortest_uncovered_ex(Bag):-
  926       findall( ID:C, ( kb:prooftrees(ID,fail,_), 
  927                        get_example(ID,Ex,'+'),
  928                        complexity(Ex,C) ), 
  929                Uncovered),
  930       shortest( Uncovered, _:C1,_),
  931       findall( ID2, member( ID2:C1, Uncovered), Bag).
  932
  933
  934%***********************************************************************
  935%*									
  936%* predicate: two_shortest /3								
  937%*									
  938%* syntax: two_shortest(+Bag,-ID1:C1,-ID2:C2)
  939%*									
  940%* args: Bag = [ ID:C, ...] , where ID refers to example with complexity C
  941%*       ID1/2 ...exampleIDs, C1/2 ... corresponding complexities
  942%*									
  943%* description:	
  944%*									
  945%* example:								
  946%*									
  947%* peculiarities:	none				
  948%*									
  949%* see also:								
  950%*									
  951%***********************************************************************
  952
  953two_shortest( Bag, ID1:C1,ID2:C2):-
  954       shortest( Bag, ID1:C1, Residue),
  955       shortest( Residue, ID2:C2, _),!.
  956
  957
  958%***********************************************************************
  959%*									
  960%* predicate:	shortest/3							
  961%*									
  962%* syntax: shortest(+Bag,-ID:C,-Residue)
  963%*									
  964%* args: Bag, Residue = [ ID:C, ...] , where ID is the complexity of ID
  965%*       ID ...kbID, C ... corresponding complexity
  966%*									
  967%* description:	selects the shortest ID from Bag wrt complexity, Residue is the rest
  968%*									
  969%* example:								
  970%*									
  971%* peculiarities:	none				
  972%*									
  973%* see also:								
  974%*									
  975%***********************************************************************
  976
  977shortest( [ID:C],ID:C ,[]).
  978shortest( [ID1:C1|Rest] , ID:C, Residue):- 
  979       shortest( Rest, ID2:C2, Residue2),
  980       ( C1 < C2      ->    ID = ID1, C = C1, Residue = Rest
  981       | otherwise    ->    ID = ID2, C = C2, Residue = [ID1:C1|Residue2]
  982       ),!.
  983
  984
  985%***********************************************************************
  986%*									
  987%* predicate:add_complexities/2								
  988%*									
  989%* syntax: add_complexities(+L,-Pairs)
  990%*									
  991%* args: L = [ID:kb_entry_for_ID,...], 
  992%*       Pairs = [ID:complexity_of_kb_entry_for_ID,...]
  993%*									
  994%* description:								
  995%*									
  996%* example:								
  997%*									
  998%* peculiarities:	none				
  999%*									
 1000%* see also:								
 1001%*									
 1002%***********************************************************************
 1003
 1004add_complexities([],[]).
 1005
 1006add_complexities( [ ID:Ex | More], [ ID:C | MorePairs ]):-
 1007        complexity(Ex,C),
 1008        add_complexities(More, MorePairs).
 1009
 1010
 1011%***********************************************************************
 1012%*									
 1013%* predicate:	no_rules/0, no_pos_examples/0, 
 1014%*              no_neg_examples/0, no_examples/0
 1015%*									
 1016%* syntax:								
 1017%*									
 1018%* args:								
 1019%*									
 1020%* description:	tests kb on the different properties
 1021%*									
 1022%* example:								
 1023%*									
 1024%* peculiarities:	none				
 1025%*									
 1026%* see also:								
 1027%*									
 1028%***********************************************************************
 1029
 1030no_rules:- \+ get_clause(_,_,_,_,_).
 1031
 1032no_pos_examples:- \+ get_example(_,_,'+').
 1033
 1034no_neg_examples:- \+ get_example(_,_,'-').
 1035
 1036no_examples:- \+ get_example(_,_,_).
 1037
 1038
 1039%***********************************************************************
 1040%*									
 1041%* predicate:	delete_covered_examples/0
 1042%*									
 1043%* syntax:								
 1044%*									
 1045%* args:								
 1046%*									
 1047%* description:	deletes examples explained by the kb
 1048%*									
 1049%* example:								
 1050%*									
 1051%* peculiarities:	none				
 1052%*									
 1053%* see also:								
 1054%*									
 1055%***********************************************************************
 1056
 1057delete_covered_examples:- 
 1058        findall( I, ( 
 1059                   get_evaluation(I,Eval),
 1060                   arg(3,Eval,CoveredEx),
 1061                   member(ID:_, CoveredEx),
 1062                   delete_example(ID)
 1063                    ),
 1064                 _),!.
 1065                     
 1066
 1067%***********************************************************************
 1068%*									
 1069%* predicate: flatten_rules/0								
 1070%*									
 1071%* syntax:								
 1072%*									
 1073%* args:								
 1074%*									
 1075%* description:	flattens all clauses in the kb
 1076%*									
 1077%* example:								
 1078%*									
 1079%* peculiarities:	none				
 1080%*									
 1081%* see also:								
 1082%*									
 1083%***********************************************************************
 1084
 1085flatten_rules:-
 1086        findall( ID:C:Label, ( get_clause(ID,_,_,C,Label), delete_clause(ID) ), Bag1),
 1087        store_flat_clauses(Bag1),!.
 1088
 1089%***********************************************************************
 1090%*									
 1091%* predicate: flatten_kb/0								
 1092%*									
 1093%* syntax:								
 1094%*									
 1095%* args:								
 1096%*									
 1097%* description: flattens all clauses and examples in the kb
 1098%*									
 1099%* example:								
 1100%*									
 1101%* peculiarities:	none				
 1102%*									
 1103%* see also:								
 1104%*									
 1105%***********************************************************************
 1106
 1107flatten_kb:-
 1108        findall( ID:C:Label, ( get_clause(ID,_,_,C,Label), delete_clause(ID) ), Bag1),
 1109        store_flat_clauses(Bag1),
 1110        findall( ID:[C:p]:ex, ( get_example(ID,C,'+') ), Bag2),  
 1111        store_flat_clauses(Bag2),!.
 1112
 1113
 1114%***********************************************************************
 1115%*									
 1116%* predicate: unflatten_kb/0								
 1117%*									
 1118%* syntax:								
 1119%*									
 1120%* args:								
 1121%*									
 1122%* description:	unflattens a flat kb
 1123%*									
 1124%* example:								
 1125%*									
 1126%* peculiarities:	none				
 1127%*									
 1128%* see also:								
 1129%*									
 1130%***********************************************************************
 1131
 1132unflatten_kb:- 
 1133        findall( ID:C:Label, ( get_clause(ID,_,_,C,Label), delete_clause(ID) ), Bag),
 1134        store_unflat_clauses(Bag).
 1135
 1136%***********************************************************************
 1137%*									
 1138%* predicate: store_flat_clauses/1				
 1139%*									
 1140%* syntax: store_flat_clauses(+CL)
 1141%*									
 1142%* args: CL = [ID:C:Label,...] where ID is clause- or exampleID, C is the corresponding
 1143%*	 clause in list notation and Label is the clause label or "ex" if examples are
 1144%*       flattened
 1145%*								
 1146%* description:	 store flat clauses preferably with their old Id.
 1147%*               After flattening, examples become clauses; they get a new Id
 1148%*               while their unflat form remains in the kb.
 1149%*									
 1150%* example:								
 1151%*									
 1152%* peculiarities:	none				
 1153%*									
 1154%* see also:								
 1155%*									
 1156%***********************************************************************
 1157
 1158store_flat_clauses([]).
 1159store_flat_clauses([ID:C:Label|More]):-
 1160        flatten_clause(C,CFlat),
 1161        ( store_clause(_,CFlat,Label,ID) ; store_clause(_,CFlat,Label,_) ),
 1162        store_flat_clauses(More).
 1163
 1164
 1165%***********************************************************************
 1166%*									
 1167%* predicate: store_unflat_clauses/1
 1168%*									
 1169%* syntax: store_unflat_clauses(+CL)
 1170%*									
 1171%* args: CL = [ID:C:Label,...] where ID is a clause- or exampleID, C is the corresponding
 1172%*	 clause in list notation and Label is the clause label or "ex"
 1173%*									
 1174%* args:								
 1175%*									
 1176%* description:	if Label \= ex, C is unflattened and replaced in the kb by 
 1177%*      the unflat version
 1178%*									
 1179%* example:								
 1180%*									
 1181%* peculiarities:	none				
 1182%*									
 1183%* see also:								
 1184%*									
 1185%***********************************************************************
 1186
 1187store_unflat_clauses([]).
 1188store_unflat_clauses( [_ID:_C:ex |More]):-
 1189        !,
 1190        store_unflat_clauses(More).
 1191store_unflat_clauses([ID:C:Label|More]):-
 1192        Label \== ex,
 1193        !,
 1194        unflatten_clause(C,CUnFlat),
 1195        store_clause(_,CUnFlat,Label,ID),
 1196        store_unflat_clauses(More).
 1197
 1198
 1199%***********************************************************************
 1200%*
 1201%* predicate: get_predlist/1
 1202%*
 1203%* syntax: get_predlist(-Predlist)  
 1204%*		 	
 1205%* args:  Predlist =  [P:PVars|_] 
 1206%*	
 1207%* description: selects all predicates with a type restriction from kb
 1208%*        & adapts type restrictions by transfomation in a list [X:Tx,...]         
 1209%*        of variables X and types Tx
 1210%*
 1211%* example:
 1212%*	
 1213%* peculiarities:	none						
 1214%*									
 1215%* see also:								
 1216%*									
 1217%***********************************************************************
 1218
 1219get_predlist(Predlist):-
 1220%   mysetof(P:PVars,
 1221%           Vars^( type_restriction(P,Vars),
 1222%                  adapt_v(Vars,PVars)), Predlist).
 1223    mysetof(P:N,I^H^B^CL^L^(get_clause(I,H,B,CL,L), L\== type ,functor(H,P,N)),Plist),
 1224    get_pred(Plist,Predlist).
 1225
 1226get_pred([],[]).
 1227get_pred([Pred:N|R],[P:PVars|R1]):-
 1228    get_pred(R,R1),
 1229    functor(P,Pred,N),
 1230    (   type_restriction(P,Vars) ->
 1231        adapt_v(Vars,PVars)
 1232    ;   P =.. [_|Vars],
 1233        adapt_v1(Vars,PVars)
 1234    ).
 1235
 1236%***********************************************************************
 1237%*
 1238%* predicate: adapt_v/2
 1239%*
 1240%* syntax: adapt_v(+TR,-Vars)                     					
 1241%*		 	
 1242%* args:  TR: [Tx(X),...] type restrictions for variables X of a predicate
 1243%*        Vars: [X:Tx,...]                                              
 1244%*	
 1245%* description: transforms a set of type restrictions Tx(X) into       
 1246%*        a set X:Tx of variables X and types Tx 
 1247%*
 1248%* example: adapt_v([list(A),atom(B)],[A:list,B:atom]                     
 1249%*	
 1250%* peculiarities:	none						
 1251%*									
 1252%* see also:								
 1253%*									
 1254%***********************************************************************
 1255
 1256adapt_v([],[]).
 1257adapt_v([T|R],[X:Tx|R1]):-
 1258   adapt_v(R,R1),
 1259   T =.. [Tx,X].
 1260
 1261adapt_v1([],[]).
 1262adapt_v1([X|R],[X:all|R1]):-
 1263   adapt_v1(R,R1)