List append/3具体化谓词变体的冗余答案

List append/3具体化谓词变体的冗余答案,list,prolog,reification,logical-purity,List,Prolog,Reification,Logical Purity,我想为一些问题提供一个逻辑上纯粹的解决方案 在这个论坛上 首先,我实现了一个具体化的变量append/3,并将其命名为appender/4。它基于@false in实现的谓词if_u/3和(=)/3: 实现基本正常,如下查询所示: ?- appendR([1,2],Ys,[2,3,4],T). T = false ? ; no ?- appendR([1,2],[3,4],Xs, T). T = true, Xs = [1,2,3,4], ? ;

我想为一些问题提供一个逻辑上纯粹的解决方案 在这个论坛上

首先,我实现了一个具体化的变量
append/3
,并将其命名为
appender/4
。它基于@false in实现的谓词
if_u/3
(=)/3

实现基本正常,如下查询所示:

?- appendR([1,2],Ys,[2,3,4],T).
T = false ? ;
no

?- appendR([1,2],[3,4],Xs, T).
T = true,  Xs = [1,2,3,4],                       ? ;
T = false, Xs = [1,2|_A],  prolog:dif([3,4],_A)  ? ;
T = false, Xs = [1|_A],    prolog:dif([2|_B],_A) ? ;
T = false,                 prolog:dif([1|_A],Xs) ? ;
no
到目前为止,一切都很好。。。下面是棘手的部分:

?- appendR([1,2],Ys,[1,2,3,4],T).
T = true,  Ys = [3,4]                   ? ;
T = false, prolog:dif(Ys,[3,4])         ? ;
T = false, prolog:dif([2|_A],[2,3,4])   ? ;
T = false, prolog:dif([1|_A],[1,2,3,4]) ? ;
no

我想得到前两个答案,但不是最后两个。救命啊

我还编写了另一个变体
appendRR/4

appendRR([],Ys,Zs, T) :- 
    =(Ys,Zs,T).
appendRR([_|_],_,[], false).
appendRR([X|Xs],Ys,[Z|Zs], T) :-
    if_(X=Z, appendRR(Xs,Ys,Zs,T), T = false).
它不会给出多余的答案:

?- appendRR([1,2],Ys,[1,2,3,4],T).
T = true,  Ys = [3,4]           ? ;
T = false, prolog:dif(Ys,[3,4]) ? ;
no
但是,目标
appendRR([1,2],u,foo,T)
失败。我宁愿得到答案
T=false
。这有点烦我


如果
appendRR
的调用者能够保证非列表项永远不会被用作
appendRR/4
的第三个参数,我仍然觉得这是可以容忍的:下一次尝试:
append\u t/4
。它应该结合和的“最佳”

首先,我们定义具体化的非空列表测试谓词
cons\u t/2

cons_t(V,T) :- 
   (  nonvar(V)                         % we can decide right now!
   -> (  V = [_|_]
      -> T = true
      ;  T = false
      )
   ;  V = [_|_],          T = true      % go nondet!
   ;  freeze(V,V\=[_|_]), T = false
   ).
基于
cons\u t/2
(=)/3
,以及
if\u/3
我们这样定义
append\u t/4

append_t([],Bs,Cs,T) :-
   =(Bs,Cs,T).
append_t([A|As],Bs,Cs0,T) :-
   if_(cons_t(Cs0),
       (Cs0=[C|Cs], if_(A=C, append_t(As,Bs,Cs,T), T=false)),
       T=false).

让我们查询并比较我们得到的答案!错误结果将突出显示(以粗体书写)

  • ?-附录([1,2],[3,4],Cs,T)。 T=true,Cs=[1,2,3,4] ; T=false,Cs=[1,2 | ux],dif(X,[3,4]) ; T=false,Cs=[1 | ux],dif(X,[2 | ux]) ; T=假,dif(Cs,[1 |])。 -附录RR([1,2],[3,4],Cs,T)。 T=false,Cs=[] ; T=false,Cs=[1] ; T=true,Cs=[1,2,3,4] ; T=false,Cs=[1,2 | ux],dif(X,[3,4]) ; T=false,Cs=[1,X | X],dif(X,2) ; T=false,Cs=dif(X,1)。 ?-附加_t([1,2],[3,4],Cs,t)。 T=true,Cs=[1,2,3,4] ; T=false,Cs=[1,2 | ux],dif(X,[3,4]) ; T=false,Cs=[1,X | X],dif(X,2) ; T=false,Cs=[1 | | | X],冻结(|X,|X\=[| | |]) ; T=false,Cs=dif(X,1) ; T=false,冻结(Cs,Cs\=[124; 124;]])。
  • ?-附录([1,2],Bs[1,2,3,4],T)。 T=true,Bs=[3,4] ; T=假,dif(Bs[3,4]) ; T=假 ; T=假。 ?-appendRR([1,2],Bs[1,2,3,4],T)。 T=true,Bs=[3,4] ; T=假,dif(Bs[3,4])。 ?-附加_t([1,2],Bs[1,2,3,4],t)。 T=true,Bs=[3,4] ; T=假,dif(Bs[3,4])。
  • ?-附录([1,2],[2,3,4],T)。 T=假。 ?-appendRR([1,2],[2,3,4],T)。 T=假。 -附加[1,2],[2,3,4],t)。 T=假。
  • ?-附录([1,2],u,非_列表,T)。 T=假。 ?-appendRR([1,2],u,非_列表,T)。 错。 ?-附加_t([1,2],_,非_列表,t)。 T=假。

  • 摘要:
    appender/4
    appenderr/4
    在某些测试用例中失败,
    append\u t/4
    没有失败。

    具有
    非列表的用例既不正确也不错误:它们超出了范围!想想
    append\t(非列表,\uu,\uu,t)
    ,所有版本都失败了。其他论点也是如此,对!o常见的
    append/3
    定义是不对称wrt。参数泛化、类型测试、索引和(可能)更多。
    append/3
    中的泛化是为了促进更高效的执行。没有别的。我仍然不知道一个好的答案,但就目前而言,
    append([],Xs,Xs)。
    是一个经过深思熟虑的概括。我不确定将概括本身具体化是否有意义。
    append_t([],Bs,Cs,T) :-
       =(Bs,Cs,T).
    append_t([A|As],Bs,Cs0,T) :-
       if_(cons_t(Cs0),
           (Cs0=[C|Cs], if_(A=C, append_t(As,Bs,Cs,T), T=false)),
           T=false).
    
    ?- appendR([1,2],[3,4],Cs,T). T = true , Cs=[1,2,3,4] ; T = false, Cs=[1,2|_X] , dif(_X,[3,4]) ; T = false, Cs=[1|_X] , dif(_X,[2|_]) ; T = false, dif(Cs,[1|_]). ?- appendRR([1,2],[3,4],Cs,T). T = false, Cs = [] ; T = false, Cs = [1] ; T = true , Cs = [1,2,3,4] ; T = false, Cs = [1,2|_X] , dif(_X,[3,4]) ; T = false, Cs = [1,_X|_] , dif(_X,2) ; T = false, Cs = [_X|_] , dif(_X,1). ?- append_t([1,2],[3,4],Cs,T). T = true , Cs = [1,2,3,4] ; T = false, Cs = [1,2|_X] , dif(_X,[3,4]) ; T = false, Cs = [1,_X|_] , dif(_X,2) ; T = false, Cs = [1|_X] , freeze(_X,_X\=[_|_]) ; T = false, Cs = [_X|_] , dif(_X,1) ; T = false, freeze(Cs,Cs\=[_|_]). ?- appendR([1,2],Bs,[1,2,3,4],T). T = true , Bs=[3,4] ; T = false, dif(Bs,[3,4]) ; T = false ; T = false. ?- appendRR([1,2],Bs,[1,2,3,4],T). T = true , Bs=[3,4] ; T = false, dif(Bs,[3,4]). ?- append_t([1,2],Bs,[1,2,3,4],T). T = true , Bs=[3,4] ; T = false, dif(Bs,[3,4]). ?- appendR([1,2],_,[2,3,4],T). T = false. ?- appendRR([1,2],_,[2,3,4],T). T = false. ?- append_t([1,2],_,[2,3,4],T). T = false. ?- appendR([1,2],_,non_list,T). T = false. ?- appendRR([1,2],_,non_list,T). false. ?- append_t([1,2],_,non_list,T). T = false.