Language Reference/Terms/in
< Language Reference | Terms
InOperator: in
The in operator is used to test for member ship of a collection (e.g. a list) and to nondeterministically generate the members of a collection.
predicates p : (Type X, Type* L). clauses p(X, L) :- if X in L then write("X is in L\n") end if.
p is a procedure that takes a value X and a list L as arguments. If X is in the list L then it will write "X is in L". In this case in is used as an in-test (membership test).
predicates q : (Type* L). clauses q(L) :- foreach X in L do writef("% is in L\n", X) end foreach.
The in operator can be defined for any domain and interface using the in_test and in_iterate attributes.
The in_test(<predicate name>) attribute defines the predicate that is used as in-test for a certain domain or interface. Likewise the in_iterate attribute defines the predicate that is used as in-iterator for the domain/interface.
domains tree{E} = empty; node(tree{E} Left, E Value, tree{E} Right) [in_test(isMemberTree), in_iterate(getAll_nd)].
When the program contains A in B where A is bound B is a tree{E} then isMemberTree is actually called.
In that case A in B corresponds to isMemberTree(A, B).
If A is free the call corresponds to A = getAll_nd(B).For a domain <collection> the predicate must have the type:
predicates <predicate> : (<some-type> Elem, <collection> Collection) determ.
interface collection [in_test(contains), in_iterate(getAll_nd)] ... end interface collection
When the program contains A in B where A is bound B is a collection then contains is actually called.
In that case A in B corresponds to B:contains(A).
If A is free the call corresponds to A = B:getAll_nd().For a domain <collection> the in_test and in_iterate predicate must fulfill these schematic declarations:
domains <collection> = ... [in_test(<in_test>), in_iterate(<in_iterate>)]. class predicates <in_test> : (<some-type> Elem, <collection> Collection) determ. <in_iterate : (<collection> Collection) -> <some-type> Elem nondeterm.
For an interface <collection> the in_test and in_iterate predicate must fulfill these schematic declarations:
interface <collection> [in_test(<in_test>), in_iterate(<in_iterate>)] predicates <in_test> : (<some-type> Elem) determ. <in_iterate : () -> <some-type> Elem nondeterm. ... end interface <collection>
The in operator is predefined on list domains, and in PFC the collections have suitable attributes.
clauses p() :- foreach X in [1, 2, 3, 4] do % in_iterate if X in [2, 4] then % in_test ... end if end foreach.
The first in is the predefined in_iterate for the list domain, and the second one is the predefined in_test.
clauses q() :- M1 = setM_redBlack::new(), M1:inset("a"), M1:inset("b"), M2 = setM_redBlack::new(), M2:inset("b"), foreach X in M1 do % in_iterate if X in M2 then % in_test ... end if end foreach.
For collections the in operators resolve to contains and getAll_nd:
interface collection{@Type} [in_test(contains), in_iterate(getAll_nd)] predicates contains : (@Type Value) determ. % @short Succeeds if the collection contains the value @Type % @end predicates getAll_nd : () -> @Type Value nondeterm. % @short @Type is nondeterministic iteration of the elements in the collection. % @end ... end interface collection