home *** CD-ROM | disk | FTP | other *** search
- ############################################################################
- #
- # Name: allof.icn
- #
- # Title: Iterative Conjunction Control Operation
- #
- # Author: Robert J. Alexander
- #
- # Date: November 3, 1989
- #
- ############################################################################
- #
- # allof{expr1,expr2} -- Control operation that performs iterative
- # conjunction.
- #
- # Expr1 works like the control expression of "every-do"; it controls
- # iteration by being resumed to produce all of its possible results.
- # The allof{} expression produces the outcome of conjunction of all
- # of the resulting expr2s, one instance of expr2 created for each
- # iteration.
- #
- # For example:
- #
- # global c
- # ...
- # pattern := "ab*"
- # "abcdef" ? {
- # allof { c := !pattern ,
- # if c == "*" then move(0 to *&subject - &pos + 1) else =c
- # } & pos(0)
- # }
- #
- # This example will perform a wild card match on "abcdef" against
- # pattern "ab*", where "*" in a pattern matches 0 or more characters.
- # Since pos(0) will fail the first time it is evaluated, the allof{}
- # expression will be resumed just as a conjunction expression would,
- # and backtracking will propagate through all of the expr2s; the
- # expression will ultimately succeed (as its conjunctive equivalent
- # would).
- #
- # Note that, due to the scope of variables in co-expressions,
- # communication between expr1 and expr2 must be via global variables,
- # hence c in the above example must be global.
- #
- # The allof{} procedure models Icon's expression evaluation
- # mechanism in that it explicitly performs backtracking. The author of
- # this procedure knows of no way to use Icon's built-in goal directed
- # evaluation to perform conjunction of a arbitrary number of computed
- # expressions (suggestions welcome).
- #
- ############################################################################
- #
- # Requires: co-expressions
- #
- ############################################################################
-
- procedure allof(expr)
- local elist,i,x,v
- #
- # Initialize
- #
- elist := [] # expression list
- i := 1 # expression list pointer
- #
- # Loop until backtracking over all expr[2]s has failed.
- #
- while i > 0 do {
- if not (x := elist[i]) then
- #
- # If we're at the end of the list of expressions, attempt an
- # iteration to produce another expression.
- #
- if @expr[1] then
- put(elist,x := ^expr[2])
- else {
- #
- # If no further iterations, suspend a result.
- #
- suspend v
- #
- # We've been backed into -- back up to last expr[2].
- #
- i -:= 1
- }
- #
- # Evaluate the expression.
- #
- if v := @x then {
- #
- # If success, move on to the refreshed next expression.
- #
- i +:= 1
- elist[i] := ^elist[i]
- }
- else
- #
- # If failure, back up.
- #
- i -:= 1
- }
- end
-