编辑:首先通过将String转换为具有string_chars / 2的列表来解决此问题。仍然不确定为什么需要这样做。我以为序言中的字符串已经是char列表。
不是最好的序言,但我必须使用它来完成此任务。我想写一个谓词,它将从字符串中删除字符,直到该字符串是回文。我有palindrome / 1,看来工作正常。
我已经尝试过了:
predicate(String):-
palindrome(String).
predicate(String):-
select(_, String, NewString), % Idea: Removing a character from String will give NewString
predicate(NewString).
因此,predicate("addal")
之类的东西应该为真,但我为假。
实际上,在代码中添加一些断点,例如在程序的不同位置编写“达到”,则表明程序在select(_, String, NewString)
处失败
为什么选择/ 3不起作用?这个想法只是删除一个随机字符。
编辑:它是回文,而不是像我起初所说的字谜。
答案 0 :(得分:2)
在包括SWI在内的任何现代Prolog中致make your program work:
:- set_prolog_flag(double_quotes, chars).
atom_chars/2
或string_chars/2
的显式转换使程序不必要地被模式化。也就是说,您将始终必须提供完整的字符串,例如"abc"
。对于字符串作为字符列表,这意味着[a,b,c]
,它又可以泛化为[a,X,c]
或以[a,b,c]
作为实例的任何术语。无法以这种方式概括SWI的字符串。
这样的概括在Prolog中非常有用。如果放弃它们,就会损失很多。
答案 1 :(得分:1)
这实际上取决于您使用的Prolog。这就是为什么准确地显示您所做的事情不会受到伤害的原因。
$ gprolog
Compiled Jul 15 2018, 03:47:56 with gcc
By Daniel Diaz
Copyright (C) 1999-2018 Daniel Diaz
| ?- select(X, "foo", Rest).
Rest = [111,111]
X = 102 ? ;
Rest = [102,111]
X = 111 ? ;
Rest = [102,111]
X = 111 ? ;
no
| ?-
$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.3-26-g30498cd0a)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- select(X, "foo", Rest).
false.
?- string_codes("foo", Codes), select(X, Codes, Rest).
Codes = [102, 111, 111],
X = 102,
Rest = [111, 111] ;
Codes = [102, 111, 111],
X = 111,
Rest = [102, 111] ;
Codes = [102, 111, 111],
X = 111,
Rest = [102, 111].
在“常规”序言中,"this is a list of character codes"
。在SWI-Prolog "this is a string"
中,它不是列表,它是表示字符串的原子事物。您需要将其转换为列表。