gpt4 book ai didi

prolog - 在 Prolog 中插入剪切以使关系子句绑定(bind)但双向

转载 作者:行者123 更新时间:2023-12-04 22:55:12 24 4
gpt4 key购买 nike

考虑以下 Prolog 程序:

transform([], []).
transform([X | Xs],[Y | Ys]):-
isSpecial(X),
isSpecial(Y),
transformSpecial(X,Y),
transform(Xs,Ys).
transform([X | Xs],[ X | Ys]):-
transform(Xs,Ys).

isSpecial(foo).
isSpecial(bar).
isSpecial(foobar).

transformSpecial(X,Y):-
isSpecial(X),
isSpecial(Y),
not(X = Y).

在某些情况下,我会调用 tranform([foo, 1, 2], X)以及我想调用 transform(X, [foo, 1, 2]) 的情况.

在这两种情况下,我都希望 X 与 [bar, 1, 2] 统一。和 [foobar, 1, 2] , 但不是 [foo, 1, 2] .也就是说,我希望一旦谓词正确地识别出第二个子句适用,它应该只使用第二个子句回溯。

我应该在哪里插入切口以实现此行为?

最佳答案

您的程序目前过于笼统。毕竟,您的查询有三个解决方案,但只有第一个是预期的。最后一个是错误的。

?- transform([foo, 1, 2], Xs).
Xs = [bar, 1, 2]
; Xs = [foobar, 1, 2]
; Xs = [foo, 1, 2]. % wrong

现在的削减可能会减少解决方案的数量。但大多数情况下,这是非常错误的。您的问题应该“在哪里插入切口以实现这种行为?”只有作为答案:没有地方。你需要做更多的事情来实现这一点。

本质上,您所描述的是逐元素转换。所以也许我们坚持一次描述一个元素。
el_transformed(X, Y) :-
isSpecial(X),
isSpecial(Y),
dif(X,Y).
el_transformed(X, X). % too general!

使用 maplist(el_transformed, [foo, 1, 2], Xs)像之前一样...

请注意,此版本与您的原始代码一样错误。但是现在,添加额外条件很简单:
el_transformed(X, Y) :-
isSpecial(X),
isSpecial(Y),
dif(X,Y).
el_transformed(X, X) :-
dif(X, foo),
dif(X, bar),
dif(X, foobar).

有一个很大的缺点:这个版本在某些情况下不是很确定:
?- el_transformed(foobar, bar).
true
; false.

如果您想从中获得更多 yield ,请考虑使用 library(reif)两者都可用
为了
SICStus
SWI .
el_transformed(X, Y) :-
if_(( ( X = foo ; X = bar ; X = foobar ),
( Y = foo ; Y = bar ; Y = foobar ) ),
dif(X,Y),
X = Y).

有了这个公式,我们就不需要重复自己了。要检查代码是否正常,让我们尝试最一般的查询:
?- el_transformed(X, Y).
X = foo, Y = bar
; X = foo, Y = foobar
; X = bar, Y = foo
; X = bar, Y = foobar
; X = foobar, Y = foo
; X = foobar, Y = bar
; X = Y, dif(Y,foobar), dif(Y,bar), dif(Y,foo).

您正在查看所有可能发生的情况!没有其他情况需要考虑。

所以作为一个经验法则:每当你想要一个应该“双向”工作的谓词时,考虑把它写成“全向”!

也许你不喜欢明确提及 X = foo ; X = bar ; X = foobar ,在这种情况下,我们将不得不通过具体化 isSpecial/1 进行更深入的挖掘。至 isSpecial_t/2 :
isSpecial_t(X, T) :-
call(
( X = foo
; X = bar
; X = foobar
), T).

el_transformed(X, Y) :-
if_( ( isSpecial_t(X), isSpecial_t(Y) ), dif(X, Y) , X = Y ).

关于prolog - 在 Prolog 中插入剪切以使关系子句绑定(bind)但双向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50524038/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com