我正在编写一个程序,其中包含谓词' word_replacements / 2'的定义。如果两个参数是列表,则该谓词应该为真,并且第二个列表与第一个列表相同,但所有元素都是单个字母' a'取而代之的是字母'以及所有单字母元素' e'取而代之的是字母' a'。您的答案应该重现以下示例输入/输出:
?- word_replacements([e, a, s, i, l, y],Word_replacements).
Word_replacements = [a, e, s, i, l, y];
false.
?- word_replacements(Word, [a,e,s,i,l,y).
Word = [e, a, s, i, l, y];
false.
这是我尝试过的,但它只是让我误解。
word_replacements([],[]).
word_replacements([H|T], Word_replacements):-
word_replacements(H,Replace_A),
word_replacements(T,Replace_E),
Append(Replaced,[T],Word_replacements).
答案 0 :(得分:0)
首先要了解的是Prolog,因为unification而无法重新分配变量。为变量赋值后,它将永远不会再次更改。这对您的示例有影响,因为您似乎正在尝试替换包含特定字符的变量。
当然有各种方法可以解决这个问题,但既然你说你是prolog的新手,我会试着提供一个(未完成的)简单的写作方式:
首先,我们将评估您的代码:
word_replacements([],[]).
word_replacements([H|T], Word_replacements):-
(1) word_replacements(H,Replace_A),
(2) word_replacements(T,Replace_E),
(3) append(Replaced,[T],Word_replacements).
您所写的内容如下:
(1):对word_replacements的递归调用,但是以H作为第一个参数,因为H不是列表,而是一个元素,所以它永远不会模式匹配,因此执行将在这里失败。
(2):递归调用word_replacements,这次使用T,列表的尾部,这确实也是一个列表,所以这是正确的。但是,作为第二个参数,您指定一个新的未实例化变量“Replace_E”。 Prolog不知道这个变量来自何处,因此会给你警告'Singleton变量'。当您进行递归调用时,您希望最终得到结果,这意味着您必须在递归调用之间传递已知变量,而不是新的单例变量。
(3):在这里,您尝试使用方括号中的字母尾部追加另一个新变量“已替换”。这会将已经在列表中的尾部包装到另一个列表中,最终会出现类似[['l','y']]的内容,这不是你想要的。
好的,我们现在首先将问题分解为以下可能的状态(这在我刚开始使用Prolog时曾经帮助过很多):
我们现在尝试将其翻译成prolog代码:
% Empty list
word_replacements([],[]).
% If H is an 'e', we want to add an 'a' to our result
word_replacements([H|T],[a|R]) :-
...
word_replacements(T,R).
% If H is an 'a', we want to add an 'e' to our result
word_replacements([H|T],[e|R]) :-
...
word_replacements(T,R).
% If H is anything other than an 'a' or 'e', we want to keep that letter
word_replacements([H|T],[H|R]) :-
...
word_replacements(T,R).
正如您所看到的,我们现在编写了一个结构化模型,可以很容易地为不同情况指定不同的行为。
现在剩下要做的就是为每种情况指定条件。
祝你好运!