我正在处理此序言分配,在其中必须解析用户输入的字符串字符列表(特别是“ u”),并确定所有元素是否都等于字符串“ u”。如果是,则返回元素数,否则返回false。例如:
uA(-Length,+String,+Leftover) //Prototype
?- uA(L,["u","u","u"],[]).
L = 3 .
?- uA(L,["u","u","d"],[]).
false.
我对序言如何工作有很好的了解,但是我对列表的操作方式感到困惑。任何帮助将不胜感激。谢谢!
编辑:排序功能取得了一些进展(谢谢!),但是我遇到了一个单独的问题。
uA(Length, String) :-
sort(String, [_]),
member("u", String),
length(String, Length).
这基本上满足了我的需要,但是,当我运行它时:
?- uA(L, ["u", "u", "u"]).
L = 3 ;
L = 3 ;
L = 3.
有没有办法使它只打印一次L = 3?谢谢!
答案 0 :(得分:1)
如果要声明所有列表项都相等,则无需先对列表进行排序。
只需将库谓词maplist/2
与内置谓词(=)/2
一起使用:
?- maplist(=(X), Xs).
Xs = []
; Xs = [X]
; Xs = [X, X]
; Xs = [X, X, X]
; Xs = [X, X, X, X]
… % ... and so on ...
答案 1 :(得分:0)
首先,在Prolog中使用双引号引起注意。它们的解释取决于标准double_quotes
标志的值。此标志的最可移植的值为codes
,例如"123"
被解释为[49,50,51]
。此标志的其他可能值为atom
和chars
。某些Prolog系统,例如SWI-Prolog也支持string
值。
但是回到您的问题。一种检查基本列表中所有元素是否相等的快速方法是使用标准sort/2
谓词(这将消除重复的元素)。例如:
| ?- sort(["u","u","u"], [_]).
yes
| ?- sort(["u","u","d"], [_]).
no
由于[_]
与任何单例列表统一,因此只有在排序结果中包含单个元素的列表时,调用才能成功;只有在其所有元素都相等的情况下,才对非空地面列表进行调用。请注意,此解决方案与double_quotes
标志的值无关。另请注意,您需要单独处理一个空列表。
答案 2 :(得分:0)
我的方法是检查列表中的每个元素是否相同(通过检查列表的开头及其相邻元素是否相同)。如果相同,则返回True,否则返回false。然后计算列表中每个元素的长度是相同的。
isEqual([X,Y]):- X == Y , !.
isEqual([H,H1|T]):- H == H1 , isEqual([H1|T]).
len([],0).
len([_|T],L):- len(T,L1) , L is L1+1.
goal(X):- isEqual(X) , len(X,Length) , write('Length = ') , write(Length).
输出
?- goal(["u","u","u"]).
Length = 3
true
?- goal(["u","u","a"]).
false
您可以这样做。希望这对您有所帮助。