使用 Prolog 查找列表的回文:- 练习 3.5 " Prolog Programming for Artificial Intelligence" by Ivan Btrako



过去三年来我一直在与Java进行编程,而我刚刚开始学习Prolog。我下载了Swi-Prolog以运行我的代码并进行跟踪,但是我在这个特定的问题上遇到了麻烦。

/*concatinates 2 Lists together*/
 conc([],L,L).
 conc([X|T],L2,[X|T1]):-
     conc(T,L2,T1).
/*Finds the reverse a List*/    
reverse([],[]).
reverse([H|T],ReversedList):-
    reverse(T,Reverse),
    conc(Reverse,[H],ReversedList).
palindrome(L):-
    reverse(L,L1),
    L is L1.

例如,如果我输入

palindrome([m,a,d,a,m]). 

l是[m,a,d,a,m]&L1应为[M,A,D,A,M]从反向谓词返回。

L = L1和输出应为真。但是,打印了我不明白的错误

ERROR: Type error: `[]' expected, found `[m,a,d,a,m]' (a list) ("x" must hold one character)
ERROR: In:
ERROR:    [9] [m,a|...]is[m,a|...]
ERROR:    [8] palindrome([m,a|...]) at c:/users/d/desktop/trial.pl:97
ERROR:    [7] <user>

我的代码仅在将谓词更改为:

时起作用。
palindrome(L):-
    reverse(L,L).

我不明白为什么逻辑是相同的... L = L1与调用l1,l起来。

另外,这是谓词的代码,而无需使用反向函数。我很难理解为什么我们拥有palidrome1([_])基本案例&amp;为什么如果我不为cont函数放置[第一个],它将返回false。

palindromel( [] ).
palindromel( [_] ).
palindromel( [First | Rest]) :-
    conc( Middle, [First], Rest), /*Do I have to put First in a list bracket?*/
    palindromel( Middle).

任何帮助将不胜感激。

但是,打印了我不明白的错误。

导致线路的错误是

L is L1

is/2说:

-Number is +Expr
True when Number is the value to which Expr evaluates. 
Typically, is/2 should be used with unbound left operand. 
If equality is to be tested, =:=/2 should be used.

由于左侧不是一个数字,右侧不是表达式is/2


我不明白为什么逻辑是相同的。

实际上逻辑不是相同的。is/2与统一不同,=/2

原因

palindrome(L):-
    reverse(L,L).

工作是因为两个参数都只有一个变量到reverse/2。因此,必须统一reverse/2的输入和reverse/2的结果。在这种情况下,因为输入和输出是腔室的相同,因此可以统一。

另一种看到这种变化的方式

palindrome(L1):-
    reverse(L1,L2),
    L1 = L2.

这次我为reverse/2使用了两个不同的变量,但随后将统一作为单独的步骤进行。第一种方式

palindrome(L):-
    reverse(L,L).

与此变化相同,但在第一个方式中,使用reverse(L,L)来考虑统一。


我很难理解为什么我们有palidrome1([_])基本情况。

当我开始创建代码以解决问题时,我会在脑海中或纸上手动解决问题。我从最简单的案例开始,并致力于更复杂的情况。对于allindromes,最简单的情况是一个没有字母的单词。

因此,如果输入是一个空列表[] palindrome是一个空列表[]

palindromel( [] ).

下一个更难的情况是一个单词,其中一个字母为[_]

palindromel( [_] ).

下一个更难的情况是一个单词,带有两个字母,即[A,A]

palindromel( [A,A] ).

等等

 palindromel( [A,B,A] ).
 palindromel( [A,B,B,A] ).
 palindromel( [A,B,C,B,A] ).
 palindromel( [A,B,C,C,B,A] ).

要避免必须创建无尽的从句列表,请使用递归。但是,对于palindrome,这两个简易案例成为递归的基本案例,其余的是使用递归条款的基本案例进行的。

如果我不为cont函数放置括号[第一个],它将返回false。

我询问Bratko的" Prolog编程"的原因是,在他的书中,他让学生创建conc/3,但没有注意到它确实是Append/3。如果您正在使用本书,请自己帮个忙,然后使用append/3,因为它没有错误,并且在append/3时,conc/3的赔率会失败。

append/3附加两个列表以创建第三个列表。如果您不将[]放在单个字符周围,那么它不是列表,而是字符,append/3conc/3将失败。

最新更新