在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/4zeven_t/2zodd_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], EsOs )。
 Es = [2,4,6], Os = [1,3,5,7]。
 ?分区(zodd_t,[1,2,3,4,5,6,7], OsEs )。  %参数顺序不同
 Es = [2,4,6], Os = [1,3,5,7]。

确定性地成功 。 使用list_evens_odds/3的等效查询不会。