Prolog delete: doesn't delete all elements that unify with Element

前端 未结 3 1482
一个人的身影
一个人的身影 2021-01-21 07:58

I\'m having an issue with SWI-Prolog\'s delete/3 predicate. The easiest way is just a quick example:

?- delete([(1,1),(1,2),(3,2)], (1,_), List).
L         


        
3条回答
  •  隐瞒了意图╮
    2021-01-21 08:30

    Use meta-predicate texclude/3 in combination with the reified term equality predicate (=)/3!

    First, we try using (=)/3 directly...

    ?- texclude(=((1,V)), [(1,1),(1,2),(3,2)], KVs).
    KVs = [      (1,2),(3,2)],     V=1            ;
    KVs = [(1,1),      (3,2)],               V=2  ;
    KVs = [(1,1),(1,2),(3,2)], dif(V,1), dif(V,2).
    

    Not quite! For our next tries we are going to use lambda expressions.

    :- use_module(library(lambda)).
    

    Let's query---once with texclude/3, once with tinclude/3, and once with tpartition/4:

    ?- texclude(  \ (K,_)^(K=1), [(1,1),(1,2),(3,2)], Fs).
    Fs = [(3,2)].                                     % succeeds deterministically
    
    ?- tinclude(  \ (K,_)^(K=1), [(1,1),(1,2),(3,2)], Ts).
    Ts = [(1,1),(1,2)].                               % succeeds deterministically
    
    ?- tpartition(\ (K,_)^(K=1), [(1,1),(1,2),(3,2)], Ts,Fs).
    Ts = [(1,1),(1,2)], Fs = [(3,2)].                 % succeeds deterministically
    

    Alright! Do we get the same solutions if the list items are bound after the texclude/3 call?

    ?- texclude(\ (K,_)^(K=1), [A,B,C], Fs), A = (1,1), B = (1,2), C = (3,2).
    A = (1,1), B = (1,2), C = (3,2), Fs = [(3,2)] ;   % succeeds with choice point
    false.
    

    Yes! At last, consider the following quite general query:

    ?- texclude(\ (K,_)^(K=1), [A,B], Fs).
    Fs = [   ], A = (  1,_A1), B = (  1,_B1)                         ;
    Fs = [  B], A = (  1,_A1), B = (_B0,_B1),             dif(_B0,1) ;
    Fs = [A  ], A = (_A0,_A1), B = (  1,_B1), dif(_A0,1)             ;
    Fs = [A,B], A = (_A0,_A1), B = (_B0,_B1), dif(_A0,1), dif(_B0,1).
    

    Note that above goals restrict all list items to have the form (_,_). Thus the following query fails:

    ?- texclude(\ (K,_)^(K=1), [x,_], _).
    false.
    

提交回复
热议问题