home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / OL.LZH / PROCS.LZH / ALLOF.ICN < prev    next >
Text File  |  1991-07-13  |  4KB  |  110 lines

  1.  
  2. ############################################################################
  3. #
  4. #       Name:   allof.icn
  5. #
  6. #       Title:  Iterative Conjunction Control Operation
  7. #
  8. #       Author: Robert J. Alexander
  9. #
  10. #       Date:   April 28, 1990
  11. #
  12. ############################################################################
  13. #
  14. #  allof{expr1,expr2} -- Control operation that performs iterative
  15. #                        conjunction.
  16. #
  17. #     Iterative conjunction permits a conjunction expression to be built
  18. #  at run time which supports full backtracking among the created terms
  19. #  of the expression.  The computed expression can be of arbitrary
  20. #  length, and is built via an iterative loop in which one term is
  21. #  appended to the expression (as if connected with a "&" operator) per
  22. #  iteration.
  23. #
  24. #     Expr1 works like the control expression of "every-do"; it controls
  25. #  iteration by being resumed to produce all of its possible results.
  26. #  The allof{} expression produces the outcome of conjunction of all of
  27. #  the resulting instances of expr2.
  28. #
  29. #     For example:
  30. #
  31. #       global c
  32. #       ...
  33. #       pattern := "ab*"
  34. #       "abcdef" ? {
  35. #          allof { c := !pattern ,
  36. #             if c == "*" then move(0 to *&subject - &pos + 1) else =c
  37. #             } & pos(0)
  38. #          }
  39. #
  40. #  This example will perform a wild card match on "abcdef" against
  41. #  pattern "ab*", where "*" in a pattern matches 0 or more characters.
  42. #  Since pos(0) will fail the first time it is evaluated, the allof{}
  43. #  expression will be resumed just as a conjunction expression would,
  44. #  and backtracking will propagate through all of the instances of
  45. #  expr2; the expression will ultimately succeed (as its conjunctive
  46. #  equivalent would).
  47. #
  48. #     Note that, due to the scope of variables in co-expressions,
  49. #  variables shared between expr1 and expr2 must have global scope,
  50. #  hence c in the above example must be global.
  51. #
  52. #     The allof{} procedure models Icon's expression evaluation
  53. #  mechanism in that it explicitly performs backtracking.  The author of
  54. #  this procedure knows of no way to invoke Icon's built-in goal
  55. #  directed evaluation to perform conjunction of a arbitrary number of
  56. #  computed expressions (suggestions welcome).
  57. #
  58. ############################################################################
  59. #
  60. #  Requires:  co-expressions
  61. #
  62. ############################################################################
  63.  
  64. procedure allof(expr)
  65.    local elist,i,x,v
  66.    #
  67.    #  Initialize
  68.    #
  69.    elist := []          # expression list
  70.    i := 1               # expression list index
  71.    
  72.    #
  73.    #  Loop until backtracking over all expr[2]s has failed.
  74.    #
  75.    while i > 0 do {
  76.       if not (x := elist[i]) then
  77.          #
  78.          #  If we're at the end of the list of expressions, attempt an
  79.          #  iteration to produce another expression.
  80.          #
  81.          if @expr[1] then
  82.             put(elist,x := ^expr[2])
  83.          else {
  84.             #
  85.             #  If no further iterations, suspend a result.
  86.             #
  87.             suspend v
  88.             #
  89.             #  We've been backed into -- reset to last expr[2].
  90.             #
  91.             i -:= 1
  92.             }
  93.       #
  94.       #  Evaluate the expression.
  95.       #
  96.       if v := @\x then {
  97.          #
  98.          #  If success, move on to the refreshed next expression.
  99.          #
  100.          i +:= 1
  101.          elist[i] := ^elist[i]
  102.          }
  103.       else
  104.          #
  105.          #  If failure, back up.
  106.          #
  107.          i -:= 1
  108.       }
  109. end
  110.