how to use subexpressions

2019-07-09 09:04发布

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

标签: prolog
1条回答
Anthone
2楼-- · 2019-07-09 09:38

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.

查看更多
登录 后发表回答