我正试图编写一个小程序,将给定的目标分解为所有最小的部分,并最终对其进行评估。到目前为止,我有:
alien(X) :- fromMars(X), fromSaturn(X); fromJupiter(X), X = 'john'.
fromMars(john).
fromSaturn(john).
fromJupiter(john).
test(true) :- !.
test((Goal1,Goal2)) :- test(Goal1), test(Goal2).
test((Goal1;Goal2)) :- test(Goal1), test(Goal2).
test(X = Y) :- call(X = Y).
test(Goal) :- clause(Goal,Body),test(Body).
据我所知,这将使用子句/2递归检查规则,例如,如果我调用test(alien(john)).
。当它达到Body
只包含fromMars(X), fromSaturn(X); fromJupiter(X), X = 'john'
之类的事实时,它将使用test((Goal1,Goal2)) :-
和test((Goal1;Goal2)) :-
规则来分割这些事实,最终达到奇异事实。当传递一个奇异事实时,如果可以解决,子句/2将把Body
实例化为true。
算术会出现问题。在上述程序中,最终将出现单一目标X = 'john'
。这会导致第/2条(私人程序?(出现错误。我引入了规则test(X = Y) :-
来捕捉这个案例,这样我就可以用另一种方式来处理它。然而,我真正想要的是一条涵盖所有算术的规则。显然,我不能用test(X = Y) :-
的风格编写一个规则来捕捉所有可能的算术类型。
我的目标是最终编写一个溯因元interper,它可以处理任何类型的规则
如果这些都没有意义,请告诉我,我会努力澄清:(
元解释器它是Prolog的"强项"之一。请参阅Markus Triska关于这个有趣主题的页面。
正如Little Booby Tables建议的那样,你可以用这样简单的东西来捕捉算术
test(X is Y) :- X is Y.
顺便说一句,我想你在这里有一个打字错误
test((Goal1;Goal2)) :- test(Goal1), test(Goal2).
应该是
test((Goal1;Goal2)) :- test(Goal1) ; test(Goal2).
EDIT:如果需要,可以通用化使用运算符。仅举一个所需内置程序的例子:
?- X = (1+2), X =.. [F, A, B], current_op(U, V, F).
X = 1+2,
F = (+),
A = 1,
B = 2,
U = 200,
V = fy .