在Prolog中分离列表
我很难理解如何让我的代码显示由偶数和奇数组成的分隔列表。 我甚至不确定我缺乏什么理解。 我对这个语言很陌生,必须把它用于学校。 我的命令和function的头脑不会让我知道这是怎么回事这个笑话。
现在,不,我不是要你做我的功课! 我只是要求你帮助我看看我缺乏了解。 我也查了类似的答案,但我不能将它们转换为我应该写这个函数的方式。
请再次,不要因为我以前通常被打击而使我受伤。 请帮我看看我的理解缺乏。 不要只是给我的答案和代码片段,而不是解释它。
这里是:
is_even(H) :- 0 is mod(H, 2). segregate(List, Even, Odd) :- segregator(List, Even, Odd). segregator([], [], []). segregator([H|T], E, O) :- is_even(H), % I feel here is where I am supposed to build the list, % but I have no clue how since Even or Odd has not been unified. segregator(T, E, O), write('Even is '), write(E), nl. segregator([H|T], E, O) :- % Same here as above. segregator(T, E, O), write('Odd is '), write(O), nl.
一个逻辑纯的实现是非常简单的,感谢clpfd :
:- use_module(library(clpfd)). list_evens_odds([],[],[]). list_evens_odds([X|Xs],[X|Es],Os) :- X mod 2 #= 0, list_evens_odds(Xs,Es,Os). list_evens_odds([X|Xs],Es,[X|Os]) :- X mod 2 #= 1, list_evens_odds(Xs,Es,Os).
一些示例查询,我们希望成功 (有一个有限的答案序列):
?- Xs = [1,2,3,4,5,6,7], list_evens_odds(Xs,Es,Os). Xs = [1,2,3,4,5,6,7], Es = [ 2, 4, 6 ], Os = [1, 3, 5, 7] ; false. ?- list_evens_odds(Ls,[2,4],[1,3]). Ls = [2,4,1,3] ? ; Ls = [2,1,4,3] ? ; Ls = [2,1,3,4] ? ; Ls = [1,2,4,3] ? ; Ls = [1,2,3,4] ? ; Ls = [1,3,2,4] ? ; no
那么我们预期会失败的查询呢?
?- list_evens_odds(Ls,[2,4,5],[1,3]). no ?- list_evens_odds(Ls,[2,4],[1,3,6]). no ?- list_evens_odds([_,_,_],[2,4],[1,3]). no
最后, 最一般的查询 :
?- assert(clpfd:full_answer). yes ?- list_evens_odds(Ls,Es,Os). Ls = [], Es = [], Os = [] ? ; Ls = [_A], Es = [_A], Os = [], _A mod 2#=0, _A in inf..sup ? ...
编辑2015-05-06
另一种方法是用逻辑纯度来做到这一点!
将元谓词tpartition/4
与zeven_t/2
或zodd_t/2
一起使用。
bool01_t(1,true). bool01_t(0,false). zeven_t(Z,Truth) :- Z mod 2 #= 0 #<==> B, bool01_t(B,Truth). %zodd_t(Z,Truth) :- Z mod 2 #= 1 #<==> B, bool01_t(B,Truth). zodd_t(Z,Truth) :- Z mod 2 #= B, bool01_t(B,Truth). % tweaked
zeven_t/2
表示整数的均匀性 , zodd_t/2
表示奇怪 。
随着一切就绪,让我们运行一些查询!
?分配(zeven_t,[1,2,3,4,5,6,7], Es , Os )。 Es = [2,4,6], Os = [1,3,5,7]。 ?分区(zodd_t,[1,2,3,4,5,6,7], Os , Es )。 %参数顺序不同 Es = [2,4,6], Os = [1,3,5,7]。
都确定性地成功 。 使用list_evens_odds/3
的等效查询不会。