Language Reference/Terms/in

From wiki.visual-prolog.com

< Language Reference‎ | Terms

Revision as of 04:25, 27 September 2024 by SergeMukhin (talk | contribs) (typo)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

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.

Example
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).


Example
predicates
    q : (Type* L).
clauses
    q(L) :-
        foreach X in L do
            writef("% is in L\n", X)
        end foreach.
q is a procedure that takes a list L as argument. The "in" operator is used to nondeterministically return the members of L, so that they can be written.

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.

Example
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.
Example
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.

Example
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