0
votes

I have to define a prolog program which gives the truth table for a logic formula like this:

(a or non (b and c))

where the logic variables can only have true or false value, and the only operators are AND,OR and NOT. The program should behave like this:

table(a and (b or non a)).

[a, b]
[v, v] v
[v, f] f
[f, v] f
[f, f] f
yes

What i did is define the 3 operators ,but i dont know how to continue. Can you help me ?

:- op(30,fx,non).
:- op(100,xfy,or).
:- op(100,xfy,and).
1
Is (a or not (b and c) the exact format you must use? are you sure there is no uppercase variable? If so, you first need to parse the input to collect all variables; when you have your variables, generate all combinations of true/false for all inputs; then, evaluate the expression for each combination of inputs and print a line for each result. But first, how would you write a rule that represents the and(A,B,R) relationship? A, B and R can be either v/f (vrai/faux). Please try this first.coredump
Thanks. I dont know how to deal with the 3 defined operators. What can i do to obtain that (b and c ), if both true give true as result, so that not(b and c) gives false, and so on ?Qwerto

1 Answers

1
votes

Not going for the full solution, but here are some hints.

Basic approach

% fact: truth value "v" is satisfiable in all environments.
sat(v,_).

% rule: and(X,Y) is satisfiable in environment E iff both X and Y are sat in E
sat(and(X,Y),E) :- sat(X,E), sat(Y,E).

Bindings

sat(Var, E) :- 
  (member(Var:Value,E) -> 
    Value = v 
  ; throw(unknown_variable(Var,E))).

Example:

[eclipse 6]: sat(o,[o:v]).

Yes (0.00s cpu)
[eclipse 7]: sat(o,[o:f]).

No (0.00s cpu)
[eclipse 8]: sat(o,[u:v]).
uncaught exception in throw(unknown_variable(o, [u : v]))
Abort

Enumeration

Define a rule (binding) which binds a variable to a value non-deterministically, and another one (bindings) which binds a list of symbols (atoms) to a list of bindings.

% Two different solution possible when binding Var
binding(Var, Var:v).
binding(Var, Var:f).

% Lists of bindings
bindings([],[]).
bindings([V|VL],[B|BL]) :-
  binding(V,B), 
  bindings(VL,BL).

For example:

[eclipse 9]: bindings([a,b,c],L).

L = [a : v, b : v, c : v]
Yes (0.00s cpu, solution 1, maybe more) ? ;

L = [a : v, b : v, c : f]
Yes (0.00s cpu, solution 2, maybe more) ? ;

L = [a : v, b : f, c : v]
Yes (0.00s cpu, solution 3, maybe more) ? ;

L = [a : v, b : f, c : f]
Yes (0.00s cpu, solution 4, maybe more) ? ;

L = [a : f, b : v, c : v]
Yes (0.00s cpu, solution 5, maybe more) ? ;

L = [a : f, b : v, c : f]
Yes (0.00s cpu, solution 6, maybe more) ? ;

L = [a : f, b : f, c : v]
Yes (0.00s cpu, solution 7, maybe more) ? ;

L = [a : f, b : f, c : f]
Yes (0.00s cpu, solution 8)

Operators

First, you could declare the following and predicate:

and(0,0,0).
and(1,0,0).
and(0,1,0).
and(1,1,1).

The rule can be applied as and(X,Y,R), and R is the result of the and operation. The same can be done with or, etc.

Your declaration:

:- op(100,xfy,and).

... allows to write X and Y instead of and(X,Y), but notice how there is no third argument here. With the ECLiPSe environment, the operator notation is also used in conjunction with is/2 to evaluate arithmetic expressions. Since the above add predicate deals with numbers, the following works:

X is 0 and 1.

The above unifies X with 0.