? users online
  • Logout
    • Open hangout
    • Open chat for current file
<div class="notebook open-fullscreen">

<div class="nb-cell program" name="p11">
% Auszug aus foResolution.pl
% 
% adapted by Wiebke Petersen
</div>

<div class="nb-cell program" data-background="true" name="p3">
% swish helper

:-style_check(-discontiguous).
:-style_check(-singleton).
</div>

<div class="nb-cell program" data-background="true" data-singleline="true" name="p2">
% consemPredicates (excerpt)

/*========================================================================
   List membership
========================================================================*/

memberList(X,[X|_]).
memberList(X,[_|Tail]):- 
   memberList(X,Tail).

/*========================================================================
   Removing first member of a list
========================================================================*/

removeFirst(X,[X|Tail],Tail) :- !.
removeFirst(X,[Head|Tail],[Head|NewTail]):-
   removeFirst(X,Tail,NewTail).

/*========================================================================
   Appending two lists
========================================================================*/

appendLists([],List,List).
appendLists([X|Tail1],List,[X|Tail2]):- 
   appendLists(Tail1,List,Tail2).

/*========================================================================
   Remove Duplicates
========================================================================*/

removeDuplicates([],[]).

removeDuplicates([X|L],Pruned):-
        memberList(Y,L), X==Y, !,
        removeDuplicates(L,Pruned).

removeDuplicates([X|L],[X|Pruned]):-
        removeDuplicates(L,Pruned).

/*========================================================================
   Selecting (i.e. removing) a member of a list
========================================================================*/

selectFromList(X,[X|L],L).
selectFromList(X,[Y|L1],[Y|L2]):-
   selectFromList(X,L1,L2).

/*========================================================================
   Union of two sets (disallowing unification of list elements)
========================================================================*/

unionSets([],L,L).

unionSets([X|L1],L2,L3):-
   memberList(Y,L2), 
   X==Y, !,
   unionSets(L1,L2,L3).

unionSets([X|L1],L2,[X|L3]):-
   unionSets(L1,L2,L3).

/*========================================================================
   Substitution Predicates
========================================================================*/

substitute(Term,Var,Exp,Result):- 
   Exp==Var, !, Result=Term.

substitute(_Term,_Var,Exp,Result):- 
   \+ compound(Exp), !, Result=Exp.

substitute(Term,Var,Formula,Result):-
   compose(Formula,Functor,[Exp,F]),
   memberList(Functor,[lam,all,some]), !, 
   (
    Exp==Var, !, 
    Result=Formula
   ; 
    substitute(Term,Var,F,R),
    compose(Result,Functor,[Exp,R])
   ).

substitute(Term,Var,Formula,Result):-
   compose(Formula,Functor,ArgList),
   substituteList(Term,Var,ArgList,ResultList),
   compose(Result,Functor,ResultList).

substituteList(_Term,_Var,[],[]).
substituteList(Term,Var,[Exp|Others],[Result|ResultOthers]):-
   substitute(Term,Var,Exp,Result),
   substituteList(Term,Var,Others,ResultOthers).


/*========================================================================
   Skolem Function Counter
========================================================================*/

:- dynamic(functionCounter/1).

functionCounter(1).

newFunctionCounter(N):-
   functionCounter(N), M is N+1,
   retract(functionCounter(N)),
   asserta(functionCounter(M)).

/*========================================================================
   Basic Formula Syntax
========================================================================*/

basicFormula(F):-
   var(F), !, fail.

basicFormula(F):-
   compose(F,Symbol,Args),
   \+ memberList(Symbol,[not,and,imp,app,or,some,all,lam,eq]),
   simpleTerms(Args).

/*========================================================================
   Simple Terms
========================================================================*/

simpleTerms([]).

simpleTerms([X|Rest]):-
   simpleTerm(X),
   simpleTerms(Rest).

simpleTerm(T):-
    var(T);
    atomic(T);
    nonvar(T),
    functor(T,'$VAR',1);
    nonvar(T),
    functor(T,fun,_).

/*========================================================================
   Compose predicate argument structure
========================================================================*/

compose(Term,Symbol,ArgList):-
    Term =.. [Symbol|ArgList].
</div>

<div class="nb-cell program" data-background="true" data-singleline="true" name="p10">
% printInfix/1: druckt eine in Präfix-Form gegebene Formel in Infix-Form.

printInfix(X):- numbervars(X,1,_End,[]),printInfix1(X).

printInfix1(X):- var(X), write(X),!.

printInfix1(not(X)):- write('~'), write('('), printInfix1(X), write(')'),!.
printInfix1(and(X,Y)):- write('('), printInfix1(X), write(' &amp; '), printInfix1(Y), write(')'),!.
printInfix1(or(X,Y)):- write('('), printInfix1(X), write(' v '), printInfix1(Y), write(')'),!.
printInfix1(imp(X,Y)):- write('('), printInfix1(X), write(' &gt; '), printInfix1(Y), write(')'),!.
printInfix1(eq(X,Y)):- write('('), printInfix1(X), write(' = '), printInfix1(Y), write(')'),!.
printInfix1(some(X, F)):- write('some ('), write_term(X,[numbervars(true)]), write(' '), printInfix1(F), write(')'),!.
printInfix1(all(X, F)):- write('all ('), write_term(X,[numbervars(true)]), write(' '), printInfix1(F), write(')'),!.
printInfix1(lam(X, F)):- write('lam '), write_term(X,[numbervars(true)]), write(' '), printInfix1(F),!.
printInfix1(app(X,Y)):- write('('), printInfix1(X), write(' @ '), printInfix1(Y), write(')'),!.

printInfix1(A):- write(A),!.
</div>

<div class="nb-cell markdown" name="md1">
## Implementing FOL Resolution
</div>

<div class="nb-cell markdown" name="md2">
FOL in CNF umwandeln:
</div>

<div class="nb-cell program" data-background="true" name="p1">
cnf(Formula,SetCNF):-
   nnf(Formula,NNF),
   skolemise(NNF,Skolemised,[]),
   cnf([[Skolemised]],[],CNF),
   setCnf(CNF,SetCNF).
</div>

<div class="nb-cell program" data-background="true" data-singleline="true" name="p4">
% helper: skolemise

/*========================================================================
   Skolemise
========================================================================*/

skolemise(all(X,F),N,Vars):- 
   skolemise(F,N,[X|Vars]).

skolemise(some(X,F1),N,Vars):-
   skolemFunction(Vars,SkolemTerm),
   substitute(SkolemTerm,X,F1,F2),
   skolemise(F2,N,Vars).

skolemise(and(F1,F2),and(N1,N2),Vars):-
   skolemise(F1,N1,Vars),
   skolemise(F2,N2,Vars).

skolemise(or(F1,F2),or(N1,N2),Vars):-
   skolemise(F1,N1,Vars),
   skolemise(F2,N2,Vars).

skolemise(F,F,_):-
   literal(F).


/*========================================================================
   Literals
========================================================================*/

literal(not(F)):- basicFormula(F).
literal(F):- basicFormula(F).

/*========================================================================
   VarList is a list of free variables, and SkolemTerm is a previously 
   unused Skolem function symbol fun(N) applied to those free variables.
========================================================================*/

skolemFunction(VarList,SkolemTerm):-
   newFunctionCounter(N),
   compose(SkolemTerm,fun,[N|VarList]).
</div>

<div class="nb-cell program" data-background="true" data-singleline="true" name="p5">
% helper: nnf to cnf
  
/*========================================================================
   Convert From Negative Normal Form to Conjunctive Normal Form
========================================================================*/

cnf([],_,[]).

cnf([[]|Tcon],Lit,[Lit|NewTcon]):-
   !,
   cnf(Tcon,[],NewTcon).

cnf([[and(F1,F2)|Tdis]|Tcon],Lits,Output):-
   !,
   appendLists(Tdis,Lits,Full),
   cnf([[F1|Full],[F2|Full]|Tcon],[],Output).

cnf([[or(F1,F2)|Tdis]|Tcon],Lits,Output):-
   !,
   cnf([[F1,F2|Tdis]|Tcon],Lits,Output).

cnf([[Lit|Tdis]|Tcon],Lits,Output):-
   cnf([Tdis|Tcon],[Lit|Lits],Output).


/*========================================================================
   Remove Duplicates and Sort
========================================================================*/

setCnf(Cnf1,Cnf2):-
   setCnf(Cnf1,[],Cnf2).

setCnf([],Cnf1,Cnf2):-
   removeDuplicates(Cnf1,Cnf2).

setCnf([X1|L1],L2,L3):-
   removeDuplicates(X1,X2),
   sort(X2,X3),
   setCnf(L1,[X3|L2],L3).
</div>

<div class="nb-cell program" data-background="true" name="p6">
% nnf distinct from propositional logic 

nnf(not(all(X,F)),some(X,N)):-
   nnf(not(F),N).

nnf(all(X,F),all(X,N)):-
   nnf(F,N).

nnf(not(some(X,F)),all(X,N)):-
   nnf(not(F),N).

nnf(some(X,F),some(X,N)):-
   nnf(F,N).

% remaining nnf

nnf(not(and(F1,F2)),or(N1,N2)):- 
   nnf(not(F1),N1), 
   nnf(not(F2),N2).
   
nnf(and(F1,F2),and(N1,N2)):- 
   nnf(F1,N1),
   nnf(F2,N2).
   
nnf(not(or(F1,F2)),and(N1,N2)):-
   nnf(not(F1),N1),
   nnf(not(F2),N2).
   
nnf(or(F1,F2),or(N1,N2)):-
   nnf(F1,N1),
   nnf(F2,N2).

nnf(not(imp(F1,F2)),and(N1,N2)):- 
   nnf(F1,N1),
   nnf(not(F2),N2).
   
nnf(imp(F1,F2),or(N1,N2)):- 
   nnf(not(F1),N1),
   nnf(F2,N2).
   
nnf(not(not(F1)),N1):-
   nnf(F1,N1).
   
nnf(F1,F1):-
   literal(F1).

/*========================================================================
   Literals
========================================================================*/

literal(not(F)):- basicFormula(F).
literal(F):- basicFormula(F).
</div>

<div class="nb-cell markdown" name="md3">
### Resolution
</div>

<div class="nb-cell program" data-background="true" name="p7">
rprove(Formula):-
   cnf(not(Formula),CNF),
   nonRedundantFactors(CNF,NRF),
   refute(NRF).

rprove(Formula,Result):-
   cnf(not(Formula),CNF),
   nonRedundantFactors(CNF,NRF),
   (
      refute(NRF), !,
      Result = 'theorem'
   ;
      Result = 'not a theorem'
   ).
</div>

<div class="nb-cell program" data-background="true" data-singleline="true" name="p8">
% helper: refute

/*========================================================================
   Refute
========================================================================*/

refute(C):-
   memberList([],C).

refute(C):-
   \+ memberList([],C),
   resolveList(C,[],Output),
   unionSets(Output,C,NewC),
   \+ NewC == C,
   refute(NewC).

/*========================================================================
   Resolve a list against a list
========================================================================*/

resolveList([],Acc,Acc).

resolveList([Clause|List],Acc1,Acc3):-
   resolveClauseList(List,Clause,Acc1,Acc2),
   resolveList(List,Acc2,Acc3).


/*========================================================================
   Resolve a clause against a list
========================================================================*/

resolveClauseList([],_,Acc,Acc).

resolveClauseList([H|L],Clause,Acc,Output):-
   resolve(Clause,H,Result0),
   nonRedundantFactors([Result0],Result), 
   unionSets(Result,Acc,NewAcc),
   resolveClauseList(L,Clause,NewAcc,Output).

resolveClauseList([H|L],Clause,Acc1,Acc2):-
   \+ resolve(Clause,H,_),
   resolveClauseList(L,Clause,Acc1,Acc2).
</div>

<div class="nb-cell markdown" name="md4">
Abweichungen und Erweiterungen
</div>

<div class="nb-cell program" data-background="true" name="p9">
/*========================================================================
   Resolve two clauses
========================================================================*/

resolve(Clause1,Clause2,NewClause):-
   selectFromList(Lit1,Clause1,Temp1),
   selectFromList(not(Lit2),Clause2,Temp2), 
   unify_with_occurs_check(Lit1,Lit2),
   unionSets(Temp1,Temp2,NewClause).

resolve(Clause1,Clause2,NewClause):-
   selectFromList(not(Lit1),Clause1,Temp1),
   selectFromList(Lit2,Clause2,Temp2),
   unify_with_occurs_check(Lit1,Lit2),
   unionSets(Temp1,Temp2,NewClause).

/*========================================================================
   Compute Non-Redundant Factors for a list of clauses
========================================================================*/

nonRedundantFactors([],[]).

nonRedundantFactors([C1|L1],L4):-
   findall(C2,nonRedFact(C1,C2),L3),
   nonRedundantFactors(L1,L2),
   appendLists(L3,L2,L4).


/*========================================================================
   Compute Non-Redundant Factors for a Clause
========================================================================*/

nonRedFact([],[]).
   
nonRedFact([X|C1],C2):-
   memberList(Y,C1),
   unify_with_occurs_check(X,Y),
   nonRedFact(C1,C2).

nonRedFact([X|C1],[X|C2]):-
   nonRedFact(C1,C2).
</div>

<div class="nb-cell markdown" name="md5">
### Testanfragen:
</div>

<div class="nb-cell query" name="q1">
write("Theorem?"), rprove(all(X,or(p(X),not(p(X)))), Result).
</div>

<div class="nb-cell query" name="q2">
write("Theorem?"), rprove(imp(all(X,p(X)),not(some(Y,not(p(Y))))), Result).
</div>

<div class="nb-cell query" name="q3">
write("Theorem?"), rprove(some(X,or(p(X),q(X))), Result).
</div>

<div class="nb-cell query" name="q4">
write("Theorem?"), rprove(some(X,and(man(X),some(Y,woman(Y)))), Result).
</div>

<div class="nb-cell query" name="q5">
Formula=some(X,and(man(X),some(Y,woman(Y)))),
printInfix(Formula),
nl, % newline character
write("Theorem?"),
rprove(Formula,Result).
</div>

<div class="nb-cell markdown" name="md6">
Auch hier können wir die Formel in Infixnotation ausgeben:
</div>

</div>