Did you know ... Search Documentation:
SWI-Prolog owl logo Predicate include/3
Availability::- use_module(library(apply)).(can be autoloaded)
Source [det]include(:Goal, +List1, ?List2)
Filter elements for which Goal succeeds. True if List2 contains those elements Xi of List1 for which call(Goal, Xi) succeeds.
See also
exclude/3, partition/4, convlist/3.
Compatibility
Older versions of SWI-Prolog had sublist/3 with the same arguments and semantics.

Examples

Use include/3 to filter odd numbers

Use include/3 to filter odd numbers

is_odd(I) :-
 0 =\= I mod 2.
?- numlist(1, 6, List),
 include(is_odd, List, Odd).
List = [1, 2, 3, 4, 5, 6],
Odd = [1, 3, 5].
Tags are associated to your profile if you are logged in|Report abuse
Tags:
  • doc-needs-help
  • filter
LogicalCaptain said (2020年05月18日T11:51:29):0 upvotes 0 0 downvotes
Picture of user LogicalCaptain.

Example:

We want the Keys of Key-Value pairs which match a certain Value.

Data:

all_pairs([winter-1, summer-2, autumn-3, spring-4, hot-2, cold-1, flowers-4, mud-3]).

Create the "filter predicate" for include/3. It will be used in the form of a "closure" in the Prolog sense: an improper goal, i.e. it will be given to include/3 as a goal with the leftmost argument prefilled with "Value" and the rightmost argument missing.

my_filter(Value,_-Value). % Succeed for the second argument "Key-Value" if it ends in "Value"

Given a "Value", and a list of "Pairs", this predicate relates the "Value" to a list "KeysOfInterest" whereby an element can be found in "KeysOfInterest" iff it is the "Key" of a "Pair" from "Pairs" which has value "Value".

keys_with_value(Value,Pairs,KeysOfInterest) :-
 include(my_filter(Value),Pairs,PairsOfInterest), % Filter Pairs, retaining only those which pass filter/2
 maplist([K-_,K]>>true,PairsOfInterest,KeysOfInterest). % Retain only the keys of the "PairsOfInterest"

Run it:

?-
all_pairs(Pairs),
keys_with_value(2,Pairs,Keys).
Pairs = [winter-1,summer-2,autumn-3,spring-4,hot-2,cold-1,flowers-4,mud-3],
Keys = [summer,hot].

Alternatively one can define filter/2 inline using a library(yall) Lambda expression, just as we did for maplist/2:

keys_with_value_2(Value,Pairs,KeysOfInterest) :-
 include({Value}/[K-V]>>(V=Value),Pairs,PairsOfInterest),
 maplist([K-_,K]>>true,PairsOfInterest,KeysOfInterest).

Run it:

?-
all_pairs(Pairs),
keys_with_value_2(2,Pairs,Keys).
Pairs = [winter-1,summer-2,autumn-3,spring-4,hot-2,cold-1,flowers-4,mud-3],
Keys = [summer,hot].

Beware accidental instantiation

This is wrong:

keys_with_value_666(Value,Pairs,KeysOfInterest) :-
 include(=(_-Value),Pairs,PairsOfInterest),
 maplist([K-_,K]>>true,PairsOfInterest,KeysOfInterest).

and doesn't work:

?- all_pairs(Pairs),keys_with_value_666(2,Pairs,Keys).
Pairs = [winter-1,summer-2,autumn-3,spring-4,hot-2,cold-1,flowers-4,mud-3],
Keys = [summer].
?- all_pairs(Pairs),keys_with_value_666(3,Pairs,Keys).
Pairs = [winter-1,summer-2,autumn-3,spring-4,hot-2,cold-1,flowers-4,mud-3],
Keys = [autumn].

This is because in spite of being the anonymous variable, the _ in the closure is instantiated with the first argument of the first matching pair, summer in the first run above, autumn in the second, and then no other element Pairs will match. You get a single result.

login to add a new annotation post.

AltStyle によって変換されたページ (->オリジナル) /