替换prolog

时间:2016-03-18 09:58:23

标签: prolog

我正在编写一个程序,其中包含谓词' 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).

1 个答案:

答案 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时曾经帮助过很多):

  • 指定的字母列表为空
  • 正在阅读的当前信件是'a'
  • 正在阅读的当前信件是'e'
  • 正在阅读的当前信件是除“a”或“e”之外的其他字母

我们现在尝试将其翻译成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).

正如您所看到的,我们现在编写了一个结构化模型,可以很容易地为不同情况指定不同的行为。

现在剩下要做的就是为每种情况指定条件。

祝你好运!