xMenores带有三个参数:
- 第一个是数字.
- 第二个是数字列表.
- 第三个是列表,并且是将包含结果的变量.
规则xMenores的目标是获得一个列表,该列表的编号(第二个参数)小于第一个参数上的值.例如:
The objective of the rule xMenores is obtain a list with the numbers of the list (Second parameter) that are smaller than the value on the first parameter. For example:
?- xMenores(3,[1,2,3],X). X = [1,2]. % expected result问题在于,当X > H为false并且我的编程技能在序言中几乎为空时,xMenores返回false.所以:
The problem is that xMenores returns false when X > H is false and my programming skills are almost null at prolog. So:
?- xMenores(4,[1,2,3],X). X = [1,2,3]. % Perfect. ?- xMenores(2,[1,2,3],X). false. % Wrong! "X = [1]" would be perfect.我考虑使用X > H, R is H.是因为我需要每当X大于H时,R就采用H的值.但是我不知道像Prolog中的if或类似的控件结构可以处理此问题.
I consider X > H, R is H. because I need that whenever X is bigger than H, R takes the value of H. But I don't know a control structure like an if or something in Prolog to handle this.
请问有什么解决办法吗?谢谢.
Please, any solution? Thanks.
推荐答案使用( if -> then ; else )
您可能要寻找的控制结构是( if -> then ; else ).
警告:您可能应该交换前两个参数的顺序:
Warning: you should probably swap the order of the first two arguments:
lessthan_if([], _, []). lessthan_if([X|Xs], Y, Zs) :- ( X < Y -> Zs = [X|Zs1] ; Zs = Zs1 ), lessthan_if(Xs, Y, Zs1).但是,如果您正在编写真实代码,则几乎可以肯定应该使用库(应用),例如include/3,如由@CapelliC建议:
However, if you are writing real code, you should almost certainly go with one of the predicates in library(apply), for example include/3, as suggested by @CapelliC:
?- include(>(3), [1,2,3], R). R = [1, 2]. ?- include(>(4), [1,2,3], R). R = [1, 2, 3]. ?- include(<(2), [1,2,3], R). R = [3].请参见 include/3 的实现.您会注意到上面的lessthan/3只是库(应用)中更通用的include/3的特化:include/3将重新排列参数并使用( if -> then ; else ).
See the implementation of include/3 if you want to know how this kind of problems are solved. You will notice that lessthan/3 above is nothing but a specialization of the more general include/3 in library(apply): include/3 will reorder the arguments and use the ( if -> then ; else ).
或者,较少程序性"而较多声明性"的谓词:
Alternatively, a less "procedural" and more "declarative" predicate:
lessthan_decl([], _, []). lessthan_decl([X|Xs], Y, [X|Zs]) :- X < Y, lessthan_decl(Xs, Y, Zs). lessthan_decl([X|Xs], Y, Zs) :- X >= Y, lessthan_decl(Xs, Y, Zs).(lessthan_if/3和lessthan_decl/3与Nicholas Carey的解决方案几乎相同,除了顺序争论.)
(lessthan_if/3 and lessthan_decl/3 are nearly identical to the solutions by Nicholas Carey, except for the order of arguments.)
不利的一面是,lessthan_decl/3留下了选择点.但是,对于一般的可读解决方案来说,这是一个很好的起点.我们需要两个代码转换:
On the downside, lessthan_decl/3 leaves behind choice points. However, it is a good starting point for a general, readable solution. We need two code transformations:
您将通过lurker到达解决方案.
You will arrive at the solution by lurker.
Prolog中最通用的比较谓词是 compare/3 .一种使用它的常见模式是显式枚举Order的三个可能值:
The most general comparison predicate in Prolog is compare/3. A common pattern using it is to explicitly enumerate the three possible values for Order:
lessthan_compare([], _, []). lessthan_compare([H|T], X, R) :- compare(Order, H, X), lessthan_compare_1(Order, H, T, X, R). lessthan_compare_1(<, H, T, X, [H|R]) :- lessthan_compare(T, X, R). lessthan_compare_1(=, _, T, X, R) :- lessthan_compare(T, X, R). lessthan_compare_1(>, _, T, X, R) :- lessthan_compare(T, X, R).(与其他解决方案相比,该解决方案可以使用任何术语,而不仅仅是整数或算术表达式.)
(Compared to any of the other solutions, this one would work with any terms, not just integers or arithmetic expressions.)
将compare/3替换为 zcompare/3 :
:- use_module(library(clpfd)). lessthan_clpfd([], _, []). lessthan_clpfd([H|T], X, R) :- zcompare(ZOrder, H, X), lessthan_clpfd_1(ZOrder, H, T, X, R). lessthan_clpfd_1(<, H, T, X, [H|R]) :- lessthan_clpfd(T, X, R). lessthan_clpfd_1(=, _, T, X, R) :- lessthan_clpfd(T, X, R). lessthan_clpfd_1(>, _, T, X, R) :- lessthan_clpfd(T, X, R).这肯定比其他任何解决方案都要多的代码,但它不会留下不必要的选择点:
This is definitely more code than any of the other solutions, but it does not leave behind unnecessary choice points:
?- lessthan_clpfd(3, [1,3,2], Xs). Xs = [1, 2]. % no dangling choice points!在其他情况下,其行为与潜伏者的DCG解决方案一样:
In the other cases, it behaves just as the DCG solution by lurker:
?- lessthan_clpfd(X, [1,3,2], Xs). Xs = [1, 3, 2], X in 4..sup ; X = 3, Xs = [1, 2] ; X = 2, Xs = [1] ; X = 1, Xs = [] . ?- lessthan_clpfd(X, [1,3,2], Xs), X = 3. % X = 3, Xs = [1, 2] ; % no error! false. ?- lessthan_clpfd([1,3,2], X, R), R = [1, 2]. X = 3, R = [1, 2] ; false.除非您需要这种通用方法,否则include(>(X), List, Result)就足够了.
Unless you need such a general approach, include(>(X), List, Result) is good enough.
更多推荐
列表中的数字小于给定数字
发布评论