how to use subexpressions

2019-07-09 09:20发布

问题:

Hello stackoverflow community, i have a prolog code that creates subexpressions for a truth table and then gives them values true/false well its working fine for alot of expressions but using this statement this happens

1 ?- phrase(subexprs(bicond(and(impl(A,B),impl(B,A)),bicond(A,B))),Subexprs), bindList([A,B]), maplist(expr_value, Subexprs, Values).
A = B, B = true,
Subexprs = [true impl true, true impl true,  (true impl true)and(true impl true), true bicond true,  **(true impl true)and(true impl true)bicond(true bicond true)**],
Values = [true, true, true, true, false] .

the last value is not what should be printed the whole expression should be printed instead which is bicond((true impl true)and(true impl true),bicond true)

here is my code

and(A,B) :- A, B.
or(A,_) :- A.
or(_,B) :- B.
equ(A,B) :- or(and(A,B), and(not(A),not(B))).
xor(A,B) :- not(equ(A,B)).
nor(A,B) :- not(or(A,B)).
nand(A,B) :- not(and(A,B)).
impl(A,B) :- or(not(A),B).
bicond(true,true):-true.
bicond(true,false):-false.
bicond(false,true):-false.
bicond(false,false):-true.


:- op(900, fy,not).
:- op(910, yfx, and).
:- op(910, yfx, nand).
:- op(920, yfx, or).
:- op(920, yfx, nor).
:- op(930, yfx, impl).
:- op(930, yfx, equ).
:- op(930, yfx, xor).
:- op(910, yfx, bicond).


subexprs(V) -->
    { var(V), ! },
    [].
subexprs(and(L, R)) -->
    subexprs(L),
    subexprs(R),
    [and(L, R)].
subexprs(or(L, R)) -->
    subexprs(L),
    subexprs(R),
    [or(L, R)].
subexprs(impl(L, R)) -->
    subexprs(L),
    subexprs(R),
    [impl(L, R)].
subexprs(nand(L, R)) -->
    subexprs(L),
    subexprs(R),
    [nand(L, R)].
subexprs(nor(L, R)) -->
    subexprs(L),
    subexprs(R),
    [nor(L, R)].
subexprs(xor(L, R)) -->
    subexprs(L),
    subexprs(R),
    [xor(L, R)].
subexprs(bicond(L, R)) -->
    subexprs(L),
    subexprs(R),
    [bicond(L, R)].


expr_value(Expr, true) :-
    call(Expr),
    !.
expr_value(_Expr, false).

bind(true).
bind(false).
bindList([]).
bindList([V|Vs]) :- bind(V),bindList(Vs).

i think the wrong part is the op but i dont know how to fix it

回答1:

With your current definition of bicond/2, the call bicond((true impl true)and(true impl true), bicond(true, true)) will fail: bicond/2 expects each of its arguments to unify with the term true or false. But you are calling it with complex terms.

Instead, you have to rewrite the definition to "evaluate" its operand terms, exactly as you do in the definition of equ/2.



标签: prolog