Re: Boundary conditions

"Richard A. O'Keefe" <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>
On 14/11/2013, at 6:46 AM, Bengbers wrote:

> I am a novice to Prolog so please excuse this maybe stupid question.
> 
> I have two lists:
> Control = [1,2,3,4]
> Check = [4,5,6]
> and I am looking for those items in Check that are not member from Control
> ([5,6])

wanted_member(X, Check, Control) :-
    member(X, Check),
    \+ memberchk(X, Control).

If you are sure that the lists will always be sorted,

all_wanted_members(Check, Control, Wanted) :-
    ord_subtract(Check, Control, Wanted).



wanted_element(Check, Control
> 
> I have written the following code:

Hang on a minute, you said that you want elements that ARE in Check
and are NOT in Control.  *Nothing* in that says anything about any
kind of uniqueness.  So where does "uniques" come from?
> 
> 1 uniques_list( Control, Check, Unique) :- uniques_list( Control, Check, [],
> Unique).

Why on _earth_ do you put spaces after left parentheses?
If you _do_ put spaces after left parentheses, then you
really ought to put them before right parentheses to match.
This lopsided layout is amazingly distracting.

The word "_list" here doesn't add any information either.

Actually, what you are doing here is just an unordered set
difference.  (Actually, duplicates are accepted, but it's not
a proper multiset difference.)

> 
> 2 uniques_list( Control, [H|Tail], Accu, Unique) :-
>    \+member( H, Control), Accu2=[H|Accu], uniques_list( Control, Tail,
> Accu2, Unique).

Why have you switched from the name "Check" to the name "Tail"?
This is confusing?
"Accu" is a state of Unique;
the standard naming convention here would be

	uniques_list(Control, [X|Check], Unique0, Unique) :-
	    \+ member(X, Control),
	    !, % you need this so the next clause isn't tried.
	    Unique0 = [X|Unique1],
	    uniques_list(Control, Check, Unique1, Unique).

Oh whoops.  I see that for no apparent reason you are reversing
the list Check as you filter it to Unique.  Why bother?

> 3 uniques_list( Control, [_|Tail], Accu, Unique) :-
>    uniques_list( Control, Tail, Accu, Unique).
> 4 uniques_List( Control, [], Unique, Unique). 

Here you switched from calling the 3rd parameter Accu to
calling it Unique.  The names in an accumulator pair (or list
difference pair) should have a common prefix.

Let's rewrite this:

subtract([X|Xs], Ys, Zs) :-
    memberchk(X, Ys),
    !,
    subtract(Xs, Ys, Zs).
subtract([X|Xs], Ys, [X|Zs]) :-
    subtract(Xs, Ys, Zs).
subtract([], _, []).

uniques_list(Control, Check, Unique) :-
    subtract(Check, Control, Unique).

The subtract/3 predicate is in the DEC-10 Prolog
library file SETS.PL, the Quintus library(sets) module.

This will take O(|Control| * |Check|) time; if you can
ensure the lists are ordered it is better to use ord_subtract/3
 as that takes O(|Control| + |Check|) time.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.