0

我的目标是'_'用给定列表中的逻辑变量替换 。我的代码:

replace([], []).
replace(['_'|As], [_|Bs]) :- 
    replace(As, Bs).
replace([A|As], [B|Bs]) :-
    A \= '_',
    B = '#',
    replace(As, Bs).

它将返回一个正确的列表,但总是以false. 请问有什么帮助吗?

4

1 回答 1

0

任何匹配replace(['_'|As], [_|Bs])的输入也匹配replace([A|As], [B|Bs])。这意味着在执行第一个子句时,为后一个子句留下一个选择点。

prolog 找到第一个结果后,它注意到仍然有选择点打开,因此它会询问您是否需要更多结果。如果您说是,它将不会尝试执行其他子句。这将永远失败,因为A \= '_'从来都不是真的。

请注意,这种行为并没有错。'false' 并不意味着程序失败,它只是意味着在已经呈现的结果之后没有找到更多结果。在这种情况下,你知道总是只有一个结果,所以你可以告诉 prolog 不要通过!像这样使用 cut 运算符来打开任何选择点:

replace(['_'|As], [_|Bs]) :- 
    replace(As, Bs), !.

这实质上告诉 prolog,如果该子句成功,则不应再考虑剩余的可能匹配项。因此,没有选择点处于打开状态,一旦获得第一个结果,执行完成并返回 true。

于 2014-10-20T07:22:56.873 回答