List 如何检查Prolog列表中的每个元素是否大于0?
我有以下Prolog谓词原型:solution(+InputVector),其中InputVector是长度未知的值列表。如果列表中的所有值都大于0,我将打印一条消息。我该怎么做 尝试检查列表是否为[]或[X | Xs],并相应地采取行动。您就快到了。考虑下面(更新感谢@ ABT医生):List 如何检查Prolog列表中的每个元素是否大于0?,list,recursion,prolog,List,Recursion,Prolog,我有以下Prolog谓词原型:solution(+InputVector),其中InputVector是长度未知的值列表。如果列表中的所有值都大于0,我将打印一条消息。我该怎么做 尝试检查列表是否为[]或[X | Xs],并相应地采取行动。您就快到了。考虑下面(更新感谢@ ABT医生): 让我们考虑一下这一行是如何工作的: 定义谓词solution/1的第一个子句,该子句将包含X的单个元素列表作为参数 测试项目X是否为>0的数字。否则,谓词将在此处终止并失败。否则,Prolog将继续到下一行 虽
让我们考虑一下这一行是如何工作的:
solution/1
的第一个子句,该子句将包含X
的单个元素列表作为参数李>
X
是否为>0
的数字。否则,谓词将在此处终止并失败。否则,Prolog将继续到下一行!
)删除了在第(1)行生成的选择点Prolog,因为第(6)行的第二个子句也可能是用输入执行的[X]
,因为这相当于[X | Y]
其中Y
=[]
。因此,这是一种所谓的“grue”——仅为提高效率而削减[X]
包含所有大于零的元素,谓词将打印一条消息并成功solution/1
的第二个子句,它获取一个包含一个或多个项的列表,其中X
是列表的头部,Y
是列表的尾部(剩余部分)(列表本身可能为空:[]
)Y
solution/1
只能在大于零的非空数字列表上成功。如果希望允许此谓词在空列表上成功,则可以简化实现:
solution([]) :-
write_ln('Success!').
solution([X|Y]) :-
X > 0,
solution(Y).
在此版本中,solution/1
的两个子句中的任何一个都是基于参数执行的:第一个处理空列表,第二个处理大于零的非空数字列表。这里不需要cut(!
),因为谓词参数是不可统一的([]
\=[X | Y]
),并且Prolog不会为第一个子句的任何调用生成选择点
我希望这对您有所帮助,并使Prolog语法的一些语义更清晰。我将这样编写谓词:
all_greater_than_zero([]).
all_greater_than_zero([H|T]) :-
H > 0,
all_greater_than_zero(T).
我认为空名单是可以接受的。如果不是,你可以删除第一个子句。 < P>如果你有兴趣将你的学习扩展到“高阶”谓词,考虑/ 2:
3?-maplist(你已经在你的问题中描述了解决方案……我是prolog新手,我的教授不是最好的老师,所以我只是在猜测和测试。下面是一个我迄今为止尝试过的例子:解决方案([X | Y]):-X>0。解决方案([u | Y]):-solution Y(Y)。你没有处理空列表[]
,当前,如果任何数字都大于零,则您的解决方案将成功,如果所有数字都大于零,则不会成功。我对prolog完全不熟悉,因此语法本身对我来说完全不熟悉。同样,如果原始输入列表为空(可能不是预期的),则此操作将失败。此外,如果没有if-then-else,则执行此操作似乎更干净。您可以把没有->
的空列表包括在内,这样:解决方案([Val]):-Val>0,写下[u ln('Solved')。解决方案([Val]Vals]):-Val>0解决方案(Vals)
@aBathologist你说得对,谢谢!我会更新答案,因为我更喜欢它,因为它简化了描述(特别是针对假定空列表正常的备选方案)@sharky我很高兴我能做出有用的贡献!我有两个问题,以防万一你有时间回答:首先,我对Prolog很陌生,还没有来得及研究切割,所以我对它在这里的用法仍然有点不清楚,但我不知怎的形成了一种偏见,认为最好尽可能避免它们,因为它们会增加声明式方法的“不洁”。这有什么道理吗?第二,你能避免第5行与[X,Y |[]]之间的歧义吗?@aBathologist,而在实践中,cuts确实会使Prolog程序变得不洁(例如对于现实世界的Prolog编程)削减通常对效率至关重要。如果你在做任何严肃的Prolog编程,我建议你了解如何以及何时正确使用。此外,[X | Y]
!=[X,Y |[]]
。列表符号中的条形
将头元素(LHS)与尾元素(RHS)分开。在[X | Y]
,X
是head元素,Y
是任意长度的尾部列表,而[X,Y |[]]
表示长度为2的列表。如果不能接受空列表,那么如果所有元素都是>0
,那么简单地删除示例中的第一个子句如何允许OP根据需要“打印消息”?
all_greater_than_zero([]).
all_greater_than_zero([H|T]) :-
H > 0,
all_greater_than_zero(T).
3 ?- maplist(<(0), [1,2,3]).
true.
4 ?- maplist(<(0),[0,1,2,3]).
false.