【问题标题】:Pure Prolog Peano List Intersection纯 Prolog Peano List 交集
【发布时间】:2021-04-02 06:45:48
【问题描述】:

假设我们只查看 Peano 数字列表。让 假设 pure_2 Prolog 不是具有 dif/2 的 pure_1 Prolog,而是 使用 pure_1 Prolog 和 when/2。我们可以实现列表交集吗?

我们会退后一步,从编程语言中汲取灵感 哥德尔和 Nu-Prolog。因此,对于任何需要的 if-then-else,我们会 借鉴这个答案here。会是什么:

/* 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 (->;_) .但我们可能会根据要求使用分离关系here

一个测试用例将是坚定的:

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

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

【问题讨论】:

  • 是和不是。有一些技巧可以引入快速失败。

标签: if-statement prolog logical-purity


【解决方案1】:

(从thisthis获取代码)

less(0, s(_)).
less(s(X), s(Y)) :- less(X, Y).

neq(X, Y) :- less(X, Y); less(Y, X).

eq(0, 0).
eq(s(X), s(Y)) :- eq(X, Y).


horn_intersect([],_,[]).
horn_intersect(_,[],[]).

horn_intersect([X|Xs],List2,[X|Ms]) :- in(X,List2),horn_intersect(Xs,List2,Ms).
horn_intersect([X|Xs],List2,Ms)     :- not_in(X,List2),horn_intersect(Xs,List2,Ms).

in(X,[K|_]) :- eq(X, K).
in(X,[K|Ms]) :- neq(X, K),in(X,Ms).

not_in(_,[]).
not_in(X,[K|Ms]) :- neq(X, K),not_in(X,Ms).

测试:

?- 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] .

【讨论】:

  • @MostowskiCollapse 新版本似乎有效。我会说它在前进方向上的表现力不如Scheme。当然,Scheme 只能向前运行。
  • 如果没有 dif/2 或 when/2,你很可能无法做到这一点。随着你的新版本的坚定失败:horn_intersect([X],[Y],Z), X=s(0), Y=0。错误:超出堆栈限制 (1.0Gb)
【解决方案2】:

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(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 = []

这是一个示例,显示了在 when/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 测试的,需要导入库 library(term/suspend) 以使 when/2 可用。在 SWI-Prolog eq/3 中留下了一个选择点,但这和here 是一样的问题。

【讨论】:

  • 我认为 nonvar 是不允许的。
  • 您可以在 when/2 文档中阅读有关 nonvar/1 的信息。您还会发现可以从 when/2 引导 dif/2。只需检查两个内置的 SWI-Prolog 文档。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 2020-03-16
  • 2018-04-24
  • 1970-01-01
相关资源
最近更新 更多