使用逻辑编程符号,给出以下子句:
C = m(P,X) <- m(Q,X), m(R,X)
可以使用C'的第一个主体文字来解析C的头部以给出替换{P/Q',X/X'}
和子句:
D = m(P',X') <- m(Q,X'), m(R,X'), m(R',X').
如何用Prolog展示呢?换句话说,我怎么能证明你可以得到D
从C
?
您在我的第一篇文章之后澄清了您的问题,但下面已经进行了一些讨论。为避免混淆,我不会编辑它,而是写第二个:
无法将您的问题直接记录为序言程序的原因有两个:
因此,我们将在谓词mi_clause中对子句数据库进行编码,该谓词有两个参数:头和带有主体的列表。谓词clause_clause_resolvent具有6个参数:每个子句以及解析程序的head和body。在这里,解析程序是使用第一子句的主体的第一元素在第二子句的开头解析的结果。反之亦然。
mi_clause(m(_P,X), [m(_Q,X), m(_R,X)]). % your original clause, anonymous variables are prefixed with _ for compiler reasons
clause_clause_resolvent( Head1, Body1, Head2, Body2, RHead, RBody) :-
copy_term(clause(Head1,Body1), clause(H1,B1)), % create a variant of the first clause
copy_term(clause(Head2,Body2), clause(H2,B2)), % same for second clause
B1 = [H2|Rest1], % the prolog execution order always uses the first literal
H1 = RHead, % head of resolvent is the same (is only resolved with the query)
append(Rest1, B2, RBody). % create the new body
注释应该或多或少是不言自明的:copy_terms创建input子句的变体,否则您可能会丢失解析器。然后,选择第二个子句的正文的第一个元素,然后尝试统一。实际上,这种统一足以正确地实例化这两个子句。现在我们创建解析子句:子句1的头被带入(以统一符替换为模),解析子的主体是子句1的主体,而未解析的文字加在第二子句的主体的主体上。
现在尝试谓词,例如在SWI Prolog中:
?- mi_clause(H1,B1), mi_clause(H2,B2), clause_clause_resolvent(H1,B1,H2,B2,RH,RB).
H1 = m(_G1028, _G1029),
B1 = [m(_G1034, _G1029), m(_G1040, _G1029)],
H2 = m(_G1043, _G1044),
B2 = [m(_G1049, _G1044), m(_G1055, _G1044)],
RH = m(_G1068, _G1069),
RB = [m(_G1080, _G1069), m(_G1099, _G1069), m(_G1105, _G1069)].
如您所见,H1和H2是子句头的变体,其中包含新鲜的匿名变量。RB的所有元素仍然具有m(_,_G1069)的形式,从而获得了您期望的子句的变体。
如果要检查常规解析步骤,请用member_of_rest(H2,B1,Rest1)替换行B1 = [H2 | Rest1]并将其定义为:
member_of_rest(X, [X|Xs], Xs).
member_of_rest(X, [H|Xs], [H|Ys]) :-
member_of_rest(X, Xs, Ys).
作为一个很好的练习,您可以通过推断性地关闭Clause_clause_resolvent来扩展程序,以查看任意解析序列(您可能希望确定链接顺序,或者遇到无限递归)。
玩得开心!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句