SICStus-prolog中的匹配

SICStus-prolog中的匹配,prolog,theorem-proving,Prolog,Theorem Proving,这是我的代码,用于证明萨奇摩定理。它实现了一些统一 :- op(700, xfx, ==>). :- op(400, yfx, &). :- op(400, yfx, or). fact([a, 9]). fact([b, 9]). rule([a, X] & [b, X] ==> [c, X]). %% horn bit rule([c, X] ==> [r, X] or [s, X]). %% non horn bit rule([r, X] ==>

这是我的代码,用于证明萨奇摩定理。它实现了一些统一

:- op(700, xfx, ==>).
:- op(400, yfx, &).
:- op(400, yfx, or).

fact([a, 9]).
fact([b, 9]).
rule([a, X] & [b, X] ==> [c, X]). %% horn bit
rule([c, X] ==> [r, X] or [s, X]). %% non horn bit
rule([r, X] ==> [t, X]).
rule([s, X] ==> [t, X]).

horn(A & B) :- 
    !,
    horn(A),
    horn(B).
horn(A or B) :-  
    !,
    (horn(A); horn(B)).
horn(P) :-
    fact(P).
horn(P) :-
    temp(P). 
horn(P) :-
    rule(SUBGOALS ==> P),
    \+ P = (_A or _B),
    horn(SUBGOALS).

satchmo(P) :-
    retractall(temp(_)),
    prove(P).

prove(P) :-
    horn(P).
prove(P) :-
    rule(LHS ==> (A or B)),
    horn(LHS),
    \+ horn(A or B),

cprove(A ==> P), 
    cprove(B ==> P). 

cprove(A ==> P) :-
    try(A),
    (prove(P) ->
    untry(A);
    (untry(A), fail)).

try(A & B) :-
    !,
    try(A),
    try(B).
try(A) :-
    assert(temp(A)).

untry(A & B) :-
    !,
    untry(A),
    untry(B).
untry(A) :-
    retract(temp(A)).
为了了解它是如何工作的,我们可以通过间谍([satchmo])来做到这一点

1-如果给定的查询是事实:

?- satchmo([a, 9]). 
yes.

该计划将证明这是事实

2-如果喇叭位中的查询为:

?- satchmo([c, 9]). 
yes. 
?- satchmo([t, 9]). 
yes. 
程序将证明这一点,因为这是horn规则

3-如果非喇叭位中的查询为:

?- satchmo([c, 9]). 
yes. 
?- satchmo([t, 9]). 
yes. 
这也会被证明的

这是完美的工作。但当我试图改变它一点。我需要做的不是统一,而是另一种匹配,可以证明以下内容:

如果我有:

rule[living, X] ==> [mortal, X]. 
[man, socrates]. 
我想证明:

?- satchmo([mortal, socrates]). 
yes.
为此,我对我的代码进行了一些修改,因此,我没有:

horn(P):-
    fact(P).
我提出了一个非常相似的观点:

horn(P):-
    match(P, P0),
    fact(P0).
我将匹配定义为:

match(X, Y):-
    X=Y.
我知道我没有做任何事情,但我想修改一下比赛的定义,以证明我的需要

我被困在这里的某个地方,看看我现在的代码

:- op(700, xfx, ==>).
:- op(400, yfx, &).
:- op(400, yfx, or).
:- op(400, yfx, <<<).

fact([a, 9]).
fact([b, 9]).
rule([a, X] & [b, X] ==> [c, X]). %% horn bit
rule([c, X] ==> [r, X] or [s, X]). %% non horn bit
rule([r, X] ==> [t, X]).
rule([s, X] ==> [t, X]).

man <<< human.
human <<< animal.
animal <<< living.

subset(X, X).
subset(X, Y) :-
    X <<< Y.
subset(X, Z) :-
    X <<< Y,
    subset(Y, Z).

horn(A & B) :- 
    !,
    horn(A),
    horn(B).
horn(A or B) :-  
    !,
    (horn(A); horn(B)).
horn(P) :-
    fact(P).
horn(P) :-
    temp(P). 
horn(P) :-
    rule(SUBGOALS ==> P),
    \+ P = (_A or _B),
    horn(SUBGOALS).

satchmo(P) :-
    retractall(temp(_)),
    prove(P).

prove(P) :-
    horn(P).
prove(P) :-
    rule(LHS ==> (A or B)),
    horn(LHS),
    \+ horn(A or B),
    cprove(A ==> P), 
    cprove(B ==> P). 

cprove(A ==> P) :-
    try(A),
    (prove(P) ->
    untry(A);
    (untry(A), fail)).

try(A & B) :-
    !,
    try(A),
    try(B).
try(A) :-
    assert(temp(A)).

untry(A & B) :-
    !,
    untry(A),
    untry(B).
untry(A) :-
    retract(temp(A)).
这里的问题是,我不知道如何通过证明来实现我的目标:

?- satchmo([mortal, socrates]).
yes.
发件人:

[living, X] ==> [mortal, X]. 
[man, socrates].
可以通过改变匹配的定义来实现吗?如果没有,还有其他方法吗

好的,完成

这个问题的解决方法是简单地更改匹配的定义,因此如下所示:

match(P, P0) :-
    P = [X, _],
    P0 = [Y, _],
    subset(Y, X).

subset(X, X).

subset(X, Y) :-
    X <<< Y.

subset(X, Z) :-
    X <<< Y,
    subset(Y, Z).
我可以证明:

?- satchmo([mortal, socrates]).

您是否尝试使用
trace
检查您的逻辑路径?是的,我通过编写?-spy([satchmo])来跟踪它。你想证明,萨奇摩([凡人,苏格拉底]),但是一个“通过检查的追踪”表明,这些规则最终会导致事实
事实/1
规则/1
,在两个元素的第一个元素中都有一个原子,但没有一个元素与之匹配。
rule([living, X] ==> [mortal, X]).
?- satchmo([mortal, socrates]).