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.