If statement 纯Prolog-Peano列表交集

If statement 纯Prolog-Peano列表交集,if-statement,prolog,logical-purity,If Statement,Prolog,Logical Purity,假设我们只查看Peano编号列表。让 假设pure_2 Prolog不是具有dif/2的pure_1 Prolog,而是 使用纯_1 Prolog和when/2。我们可以实现列表交叉吗 我们会退后一步,从编程语言中汲取灵感 Gödel和Nu Prolog。因此,对于任何需要的,否则我们会 利用这个答案。什么是: /* pure_2 Prolog = pure_1 Prolog with when/2 */ intersect(A, B, C) :- ?? 注意,尽管如此,与Gödel和Nu P

假设我们只查看Peano编号列表。让 假设pure_2 Prolog不是具有dif/2的pure_1 Prolog,而是 使用纯_1 Prolog和when/2。我们可以实现列表交叉吗

我们会退后一步,从编程语言中汲取灵感 Gödel和Nu Prolog。因此,对于任何需要的,否则我们会 利用这个答案。什么是:

/* pure_2 Prolog = pure_1 Prolog with when/2 */
intersect(A, B, C) :- ??
注意,尽管如此,与Gödel和Nu Prolog相反,在这里,为了遵守这个等式的pure_2 Prolog,我们不允许使用ISO Prolog if then else(->)。但我们可以根据需要使用一种隔离关系

一个测试用例是稳定性:

?- intersect([s(0)], [0], X).
X = []

?- intersect([X], [Y], Z), X = s(0), Y = 0.
X = []
?- intersect([s(s(0))], [s(0)], X).
X = []

?- intersect([X], [Y], Z), X = s(s(0)), Y = s(0).
X = s(s(0)),
Y = s(0),
Z = []
(从和中提取代码)

测试:

?- horn_intersect([X], [Y], Z).
X = Y, Y = 0,
Z = [0] ;
X = Y, Y = s(0),
Z = [s(0)] ;
X = Y, Y = s(s(0)),
Z = [s(s(0))] ;
X = Y, Y = s(s(s(0))),
Z = [s(s(s(0)))] ;
X = Y, Y = s(s(s(s(0)))),
Z = [s(s(s(s(0))))] ;
X = Y, Y = s(s(s(s(s(0))))),
Z = [s(s(s(s(s(0)))))] ;
X = Y, Y = s(s(s(s(s(s(0)))))),
Z = [s(s(s(s(s(s(0))))))] ;
X = Y, Y = s(s(s(s(s(s(s(0))))))),
Z = [s(s(s(s(s(s(s(0)))))))] ;
X = Y, Y = s(s(s(s(s(s(s(s(0)))))))),
Z = [s(s(s(s(s(s(s(s(0))))))))] ;
X = Y, Y = s(s(s(s(s(s(s(s(s(0))))))))),
Z = [s(s(s(s(s(s(s(s(s(...)))))))))] ;
X = Y, Y = s(s(s(s(s(s(s(s(s(s(...)))))))))),
Z = [s(s(s(s(s(s(s(s(s(...)))))))))] .

?- horn_intersect(X, Y, Z).
X = Z, Z = [] ;
Y = Z, Z = [] ;
X = Z, Z = [0],
Y = [0|_2472] ;
X = Z, Z = [0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0, 0, 0, 0],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0, 0, 0, 0|...],
Y = [0|_2472] ;
X = Z, Z = [0, 0, 0, 0, 0, 0, 0, 0, 0|...],
Y = [0|_2472] .

when/2和freeze/2允许比dif/2更精细的控制。这里有一些代码 它使用when/2和freeze/2,而且似乎是稳定的,也不会失败, 并且不会为接地输入留下选择点:

/* reified and delayed equality */
eq(X, Y, R) :- when((nonvar(X), nonvar(Y)), eq2(X, Y, R)).
eq2(0, 0, 1).
eq2(0, s(_), 0).
eq2(s(_), 0, 0).
eq2(s(X), s(Y), R) :- eq(X, Y, R).

/* reified and delayed disjunction */
or(X, Y, R) :- when((nonvar(X), nonvar(Y)), or2(X, Y, R)).
or2(0, 0, 0).
or2(0, 1, 1).
or2(1, 0, 1).
or2(1, 1, 1).

/* reified and delayed membership */
member(_, [], 0).
member(X, [Y|Z], R) :-
   eq(X, Y, H),
   or(H, J, R),
   member(X, Z, J).

/* reified and delayed if-then-else */
ite(B, P, Q) :- freeze(B, ite2(B, P, Q)).
ite2(1, P, _) :- P.
ite2(0, _, Q) :- Q.

/* */
intersect([], _, []).
intersect([X|Y], Z, T) :-
   ite(B, T = [X|R], T = R),
   member(X, Z, B),
   intersect(Y, Z, R).
下面是一些测试稳定性的示例查询:

?- intersect([s(0)], [0], X).
X = []

?- intersect([X], [Y], Z), X = s(0), Y = 0.
X = []
?- intersect([s(s(0))], [s(0)], X).
X = []

?- intersect([X], [Y], Z), X = s(s(0)), Y = s(0).
X = s(s(0)),
Y = s(0),
Z = []
下面是一个测试失败率的查询示例:

?- intersect([s(_)], [0], X).
X = []
下面是一个示例,它显示了/2时发生的延迟:

?- intersect([X], [Y], Z).
freeze(_A, ite2(_A, Z = [X], Z = [])),
when((nonvar(X), nonvar(Y)), eq2(X, Y, _D)),
when(nonvar(_D), or2(_D, 0, _A))

以上是用Jekejeke Prolog 1.4.6测试的,需要导入库(term/suspend)以使when/2可用。在SWI Prolog中,eq/3留下了一个选择点,但这是相同的问题,如。

是和否。有一些技巧可以引入快速故障。@Mostowski新版本似乎有效。我要说的是,在前进方向上,它没有计划那么富有表现力。当然,Scheme只能向前运行。最有可能的是,如果没有dif/2或when/2,您就无法实现它。在你的新版本中,Steadstance失败了:horn_intersect([X],[Y],Z),X=s(0),Y=0。错误:堆栈限制(1.0Gb)超出我认为不允许的
nonvar
。您可以在when/2文档中阅读关于nonvar/1的内容。您还会发现dif/2可以从when/2启动。只需检查两个内置的SWI Prolog docu。