Select / 3从字符串中删除随机字符失败

时间:2019-03-24 00:40:42

标签: prolog

编辑:首先通过将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不起作用?这个想法只是删除一个随机字符。

编辑:它是回文,而不是像我起初所说的字谜。

2 个答案:

答案 0 :(得分:2)

在包括SWI在内的任何现代Prolog中致make your program work

:- set_prolog_flag(double_quotes, chars).

atom_chars/2string_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"中,它不是列表,它是表示字符串的原子事物。您需要将其转换为列表。