在 Prolog 中使用字符串连接解决约束

Solving constraints with string concatenations in Prolog

在这里,我试图解决Prolog中一些简单的字符串约束。虽然这个问题看起来很简单,但是 main 谓词仍然没有打印 FinalString 的值,应该是 "hello world"。 Prolog 是否有可能解决包含字符串连接的约束,就像这个一样?

:- set_prolog_flag(verbose,silent).
:- prompt(_, '').
:- use_module(library(readutil)).
main :-
    append("hello ", B, FinalString),
    append(A, "world", FinalString),
    append(A, B, FinalString),
    writeln(FinalString),
    true.
:-main.

如果你是初学者做实验,最好坚持使用。通过这种方式,您可以快速识别问题。由于您很可能正在使用 SWI7 - 像这样:

?- append("hello ", B, FinalString),
   append(A, "world", FinalString),
   append(A, B, FinalString).
false.

所以如果这是错误的,让概括它,删除最右边的目标:

?- append("hello ", B, FinalString),
   append(A, "world", FinalString).
false.

不...

?- append("hello ", B, FinalString).
false.

实际问题是 SWI 中的双引号现在具有不一致的含义。要获得传统行为,请使用命令行选项 --traditional 和:

调用 SWI
?- set_prolog_flag(double_quotes,chars).
true.

?- append("hello ", B, FS).
FS = [h, e, l, l, o, ' '|B].

有关此标志的更多信息,请参阅 this answer

现在您的原始查询产生了一个合理的答案:

?- append("hello ", B, FS),append(A, "world", FS),append(A, B, FS).
B = [w, o, r, l, d],
FS = [h, e, l, l, o, ' ', w, o, r|...],
A = [h, e, l, l, o, ' '] ;
**LOOPS**

...或者是吗?它找到了你想要的答案,但同时,当被问及是否有进一步的答案时,它会循环!使用顶层 shell 时可以很容易地检测到此类问题,但使用像您这样的脚本仍然无法检测到。这个循环是一个固有的问题。没有简单的出路,因为只有一个解决方案这一事实是 所有三个目标共同造成的

如果你真的喜欢把它写成脚本,不如这样写:

:- set_prolog_flag(double_quotes, chars).

main :-
    append("hello ", B, FinalString),
    append(A, "world", FinalString),
    append(A, B, FinalString),
    write(FinalString),
    nl,
    halt.

:- initialization(main).