Declarative uses of memberchk/2

前端 未结 3 908
逝去的感伤
逝去的感伤 2020-12-10 12:09

memberchk/2 is a commonly defined predicate that is defined in terms of member/2 like so:

memberchk(X, Xs) :-
   once(member(X, Xs)         


        
3条回答
  •  离开以前
    2020-12-10 12:38

    memberb/2 is a typical example from constructive negation. You can turn the requirement upside down, and for example require:

    ?- ~ member(X, [a,b,c]).
    dif(X, a),
    dif(X, b),
    dif(X, c)
    

    Where ~ would be constructive negation. For a discussion on how constructive negation relates to if_ see for example here.

    The disadvantage of fully declarative inductive definitions, for memberd/2 or somesuch is that the Prolog disjunction (;)/2 is not able to simplify constraints, and that Prolog doesn't have a forall that would also simplify constraints such as diff/2.

    So that in the end when you do it correctly with the limited (;)/2 and missig forall you get in the best case complete solutions that contain a lot of redundant constraints when you look at the full solution sets that the interpreter would produce.

    Here is an example in Jekejeke Prolog, it requires the Minlog extension for the predicate diff/2 to be available:

    :- use_module(library(term/diff)).
    :- use_module(library(basic/lists)).
    test(Y) :- diff(X, a), member(Y, [a,X]).
    
    ?- test(X).
    X = a ;
    diff([X], [a])
    

    The above two answers basically say X = a or ~(X = a) which is in most logics the same as a single answer true.

    You would need a Prolog interpreter, that at some points works set oriented. And maybe some operators that would force a set oriented processing. But it might break traditional Prolog code. You can probably not just sneak in fully declarative definitions into code that was based on not so declarative definitions.

    Bye

提交回复
热议问题