/************************************************************************* name: modelChecker1.pl (Volume 1, Chapter 1) version: April 18, 2001 description: The basic model checker authors: Patrick Blackburn & Johan Bos *************************************************************************/ :- module(modelChecker1,[evaluate/0, evaluate/2, evaluate/3, satisfy/4]). :- ensure_loaded(comsemOperators). :- use_module(comsemPredicates,[memberList/2, compose/3, printRepresentations/1]). :- use_module(exampleModels,[example/2]). :- use_module(modelCheckerTestSuite,[test/4]). /*======================================================================== Evaluate a formula in an example model ========================================================================*/ evaluate(Formula,Example):- evaluate(Formula,Example,[]). /*======================================================================== Evaluate a formula in an example model wrt an assignment ========================================================================*/ evaluate(Formula,Example,Assignment):- example(Example,Model), ( satisfy(Formula,Model,Assignment,pos), !, printStatus(pos) ; printStatus(neg) ). /*======================================================================== Testsuite ========================================================================*/ evaluate:- format('~n>>>>> MODEL CHECKER 1 ON TESTSUITE <<<<<~n',[]), test(Formula,Example,Assignment,Status), format('~n~nInput formula:',[]), printRepresentations([Formula]), format('Example Model: ~p~nStatus: ',[Example]), printStatus(Status), format('~nModel Checker says: ',[]), evaluate(Formula,Example,Assignment), fail. evaluate. /*======================================================================== Print status of a testsuite example ========================================================================*/ printStatus(pos):- write('Satisfied in model. '). printStatus(neg):- write('Not satisfied in model. '). printStatus(undef):- write('Cannot be evaluated. '). /*======================================================================== Existential Quantification ========================================================================*/ satisfy(exists(X,Formula),model(D,F),G,pos):- memberList(V,D), satisfy(Formula,model(D,F),[g(X,V)|G],pos). satisfy(exists(X,Formula),model(D,F),G,neg):- setof(V,(memberList(V,D),satisfy(Formula,model(D,F),[g(X,V)|G],neg)),D). /*======================================================================== Universal Quantification ========================================================================*/ satisfy(forall(X,Formula),Model,G,Pol):- satisfy(~ exists(X,~ Formula),Model,G,Pol). /*======================================================================== Conjunction ========================================================================*/ satisfy(Formula1 & Formula2,Model,G,pos):- satisfy(Formula1,Model,G,pos), satisfy(Formula2,Model,G,pos). satisfy(Formula1 & Formula2,Model,G,neg):- satisfy(Formula1,Model,G,neg); satisfy(Formula2,Model,G,neg). /*======================================================================== Disjunction ========================================================================*/ satisfy(Formula1 v Formula2,Model,G,pos):- satisfy(Formula1,Model,G,pos); satisfy(Formula2,Model,G,pos). satisfy(Formula1 v Formula2,Model,G,neg):- satisfy(Formula1,Model,G,neg), satisfy(Formula2,Model,G,neg). /*======================================================================== Implication ========================================================================*/ satisfy(Formula1 > Formula2,Model,G,Pol):- satisfy((~Formula1 v Formula2),Model,G,Pol). /*======================================================================== Negation ========================================================================*/ satisfy(~ Formula,Model,G,pos):- satisfy(Formula,Model,G,neg). satisfy(~ Formula,Model,G,neg):- satisfy(Formula,Model,G,pos). /*======================================================================== Equality ========================================================================*/ satisfy(X=Y,Model,G,pos):- i(X,Model,G,Value1), i(Y,Model,G,Value2), Value1=Value2. satisfy(X=Y,Model,G,neg):- i(X,Model,G,Value1), i(Y,Model,G,Value2), \+ Value1=Value2. /*======================================================================== One-place predicates ========================================================================*/ satisfy(Formula,model(D,F),G,pos):- compose(Formula,Symbol,[Argument]), i(Argument,model(D,F),G,Value), memberList(f(1,Symbol,Values),F), memberList(Value,Values). satisfy(Formula,model(D,F),G,neg):- compose(Formula,Symbol,[Argument]), i(Argument,model(D,F),G,Value), memberList(f(1,Symbol,Values),F), \+ memberList(Value,Values). /*======================================================================== Two-place predicates ========================================================================*/ satisfy(Formula,model(D,F),G,pos):- compose(Formula,Symbol,[Arg1,Arg2]), i(Arg1,model(D,F),G,Value1), i(Arg2,model(D,F),G,Value2), memberList(f(2,Symbol,Values),F), memberList((Value1,Value2),Values). satisfy(Formula,model(D,F),G,neg):- compose(Formula,Symbol,[Arg1,Arg2]), i(Arg1,model(D,F),G,Value1), i(Arg2,model(D,F),G,Value2), memberList(f(2,Symbol,Values),F), \+ memberList((Value1,Value2),Values). /*======================================================================== Interpretation of Constants and Variables ========================================================================*/ i(X,model(_,F),G,Value):- ( var(X), memberList(g(Y,Value),G), Y==X, ! % IMPORTANT CUT! ; atom(X), memberList(f(0,X,Value),F) ).