如何绕过为表单[X | L]的过程的参数分配空列表?

时间:2012-08-20 18:19:21

标签: prolog

我有以下程序:

% finds all members in sorted list L1 that are not in the sorted L2 
%   and puts them in NL
make_list(L1,L2,NL):-
    make_list(L1,L2,NL,x).
make_list([],_,[],_):-!.

% X represents the last value parsed from L1
make_list(L1,[],L2,X):-!,
    make_list(L1,[99999999],L2,X).

make_list([X1|L1],[X2|L2],[X3|NewL],Last):-
    (
        (X1<X2,
         X1 \= Last,
         X3=X1,!,
         make_list(L1,[X2|L2],NewL,X1);
         X1<X2,!,
         make_list(L1,[X2|L2],[X3|NewL],X1)
         )
    );
    (
        X1=X2,!,
        make_list(L1,[X2|L2],[X3|NewL],*)
    );
    make_list([X1|L1],L2,[X3|NewL],*).

我的问题是,当最后一个值相同时(即:?- make_list([1,2],[2],L).),由于

,代码无效
make_list([X1|L1],L2,[X3|NewL],*).

make_list(L1,[X2|L2],[X3|NewL],*)

将包含至少一个变量(第3个列表)的列表传递给make_list([],_,[],_)。有评论说该程序的功能。如何使代码完成它应该做的事情?

我还在这里问了一个关于相同但完全没有工作的代码的问题:How do parenthesis work?

2 个答案:

答案 0 :(得分:2)

在解决此问题时,您应该考虑六个相互排斥的案例:

  1. 两个列表中的元素都用完了
  2. 第一个列表中的元素用完了,但第二个列表中没有元素。
  3. 第二个列表中的元素用尽,但第一个
  4. 中没有
  5. 两个列表至少有一个元素,头元素匹配
  6. 两个列表至少有一个元素,第一个列表的head元素较小
  7. 两个列表至少有一个元素,第一个列表的head元素更大
  8. 这六种组合涵盖了您需要编写的规则。

    前两种情况可由单一规则涵盖:

    make_list([], _, []).
    

    这意味着如果第一个列表为空,则无法添加到输出列表中。

    第三种情况也很简单:如果第二个列表为空,则输出与第一个列表相同:

    make_list(L1, [], L1).
    

    第四种情况稍微不那么简单:如果头部统一,同时丢弃它们,并解决一个较小的子问题:

    make_list([H|T1], [H|T2], NL) :-
        make_list(T1, T2, NL).
    

    第五个案例将第一个列表的头部插入到输出中,第六个案例跳过第二个列表的头部:

    make_list([H1|T1], [H2|T2], NL) :-
        H1 < H2,
        make_list(T1, [H2|T2], N2),
        NL = [H1|N2].
    
    make_list([H1|T1], [H2|T2], NL) :-
        H1 > H2,
        make_list([H1|T1], T2, NL).
    

    请注意,当第一个列表包含重复项时,此解决方案无法按预期工作,而第二个列表不包含相应元素的重复项。

答案 1 :(得分:1)

% finds all members in sorted list L1 that are not in the sorted L2 
% and puts them in NL

make_list(L1,L2,NL):-
    make_list(L1,L2,NL,x).

make_list([],_,[],_):-!.

% X represents the last value parsed from L1
make_list(L1,[],L2,X):-!,
    make_list(L1,[99999999],L2,X).

此处的问题是NewL[X3|NewL],当L1为空时,make_list([],_,[],_):-!.失败,因为[X3|NewL]无法分配[] }

make_list([X1|L1],[X2|L2],NewL,Last):-
    X1<X2,
    X1 \= Last,
    NewL = [X3|NewL2],X3=X1,
    make_list(L1,[X2|L2],NewL2,X1),!
    ;
    X1<X2,
    make_list(L1,[X2|L2],NewL,X1),!.

make_list([X1|L1],[X1|L2],NewL,Last):-!,
    make_list(L1,[X1|L2],NewL,Last).

接下来的两种情况是X1>X2X2被忽略,X1仅在X1=Last

时被忽略
make_list([X1|L1],[_|L2],NewL,X1):-!, % X1>X2
    make_list(L1,L2,NewL,X1).

make_list([X1|L1],[_|L2],NewL,Last):- % X1>X2
    make_list([X1|L1],L2,NewL,Last).