Prolog - 用列表解决问题

时间:2013-10-22 21:08:53

标签: prolog

您好我必须解决一些列表的prolog问题,但我无法弄清楚这些是如何工作的。 我必须在列表中的每个偶数元素后面添加“1”,以区分2个列表。 我知道这看起来很容易,在其他语言如java或c#中我会很容易,但是prolog它让我很头疼。 请帮帮我:|

1 个答案:

答案 0 :(得分:1)

编辑注意澄清的问题陈述("偶数项"意味着项目的值是偶数(而不是列表中项目的序号位置):

insert_one_after_even_items( [] , [] ).             % if the source list is exhaused, we're done.
insert_one_after_even_items( [X|Xs] , [X,1|Ys] ) :- % otherwise, 
   0 is X mod 2 ,                                   % - if the number is even, prepend it and a 1 to the result list, and
   insert_one_after_even_items( Xs , Ys )           % - recurse down.
   .                                                %
insert_one_after_even_items( [X|Xs] , [X|Ys] ) :-   % otherwise,
   1 is X mod 2 ,                                   % - if the number is odd, prepend it to the result list, and
   insert_one_after_even_items( Xs , Ys )           % - recurse down.
   .                                                % Easy!

对于你的第二个问题,产生两个列表之间的差异,你在谈论集合差异吗?如果是这样,给定两组A和B,你是在谈论相对差异(B中不存在的A的所有元素),还是绝对差异(两个集合中不存在的A或B的所有元素) ?

要解决相对集差异问题(查找B中不存在的A的所有成员),您可以使用内置的member/2谓词:

relative_difference( [] , _ , [] ) .          % if the source list is exhausted, we're done
relative_difference( [A|As] , Bs , R ) :-     % if the source list is non-empty, and
  member(A,Bs) ,                              % - the current A is an element of B,
  ! ,                                         % - we insert a deterministic cut (no backtracking)
  relative_difference( As , Bs , R )          % - and recurse down, discarding the current A
  .                                           %
relative_difference( [A|As] , Bs , [A|R] ) :- % if the source list is non-empty (and A is not an element of B due to the cut inserted earlier)
  relative_difference( As , Bs , R )          % we simply add A to the result list and recurse down.
  .

您将在此处注意一件事:我们正在构建结果列表,所有这些示例都是从变量构建的。列表的尾部是未绑定的(并作为新结果传递给下一个递归调用,它将成为新的列表节点,或者最后是空列表。

这具有

的效果
  • 按顺序构建列表(而不是按相反的顺序)。
  • 如果结果在初始调用中绑定,则随着递归的进行逐项对预期结果进行统一,这意味着
  • 第一次统一失败发生时执行被短路。

如果你的prolog实现没有member/2作为内置,那么它很容易实现。像这样的东西应该这样做:

member(X,[X|T]) :- ! .           % A hit! cut and succeed.
member(X,[_|T]) :- member(X,T) . % ... and a miss. Just recurse down on the tail.