source: to-imperative/trunk/compiler/rfp_as2as.rf @ 2034

Last change on this file since 2034 was 2034, checked in by orlov, 14 years ago
  • Proper generation of debug info for use with Debug library (-dbg option).
  • Result expressions can contain blocks.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 59.5 KB
Line 
1// $Source$
2// $Revision: 2034 $
3// $Date: 2006-07-27 04:40:44 +0000 (Thu, 27 Jul 2006) $
4
5$use "rfpc";
6$use "rfp_compile";
7$use "rfp_format";
8$use "rfp_helper";
9$use "rfp_vars";
10$use "rfp_debug";
11
12$use Arithm Class List StdIO Table;
13
14// transform only e.targets and leave all the rest as it is
15$func Transform (e.targets) e.Items = e.Items;
16
17// transform { A; } : Pe into { A; } :: aux, aux : Pe
18$func Unstick-Blocks e.Sentence = e.Sentence (e.Fe);
19
20// remove blocks from Re
21$func Flatten-Result s.N (e.Re) e.items = e.assigns s.N (e.Re);
22
23$func Generate-In-Vars (e.in) e.branch = (e.in) e.branch;
24
25// rename variables local for the {}-blocks
26//$func Rename-Vars s.num (e.upper-vars) (e.res-vars) e.Snt = e.new-Snt;
27$func Rename-Vars e = e;
28
29// is variable with e.QualifiedName in the e.vars list?
30//$func? Old-Var? e.vars (s t (e.QualifiedName)) = ;
31$func? Old-Var? e = e;
32
33//$func Rename s.num (s.tag t.p (e.QualifiedName)) =
34//                      (s.tag t.p ("ren" e.QualifiedName s.num));
35$func Rename e = e;
36
37// build substitution for all occurrences of each e.var in e.Snt
38$func Build-Subst (e.vars) (e.substs) e.Snt = (e.patterns) (e.replacements);
39
40// build substitution for all occurrences of variable with the name t.n in e.Snt
41$func Var-Subst t.n t.s e.Snt = (e.patterns) (e.replacements);
42
43
44RFP-As2As-Transform e.Items =
45  { <Lookup &RFP-Options ITEMS>;; } :: e.targets,
46  <Transform (e.targets) e.Items>;
47
48Transform (e.targets) e.Items, {
49  e.Items : t.item e.rest, {
50    {
51      e.targets : v =
52        e.targets : e t.name e,
53        t.item : (t t t t.name e);;
54    },
55      t.item : (s.link s.tag t.pragma t.name (e.in) (e.out) (BRANCH t.p e.branch)) =
56      {
57        <Format-Exp e.in> : e.in =
58          <Generate-In-Vars (e.in) e.branch>;
59        (e.in) e.branch;
60      } :: (e.in) e.branch,
61      {
62        <In-Table? &RFP-Options DBG> =
63          <Add-Debug (RESULT t.p e.in) e.branch>;
64        e.branch;
65      } :: e.branch,
66      <Unstick-Blocks e.branch> :: e.branch t,
67      <Rename-Vars 0 (<Vars e.in>) () e.branch> :: e.branch,
68      (s.link s.tag t.pragma t.name (e.in) (e.out) (BRANCH t.p e.branch));
69    t.item;
70  } :: t.item =
71    t.item <Transform (e.targets) e.rest>;;
72};
73
74/*
75 * Next function gets use of the following proposition:
76 *  one can add (RESULT) term to the end of any sentence that isn't end in
77 *  (RESULT e.anything) and it won't change the result of program execution.
78 * No, no, the proposition is WRONG!!! Such doings change the semantics of "=".
79 *
80 * The function returns the sentence with all { A; } : Pe constructions
81 * turned into { A; } :: aux, aux : Pe ones and format of the last Re of
82 * the sentence.
83 */
84Unstick-Blocks e.Sentence, e.Sentence : eL e.Snt, e.Snt : \{
85  (s.block t.Pragma e.branches) eR, s.block : \{ BLOCK; BLOCK?; } =
86    e.branches () () $iter {
87      e.branches : (BRANCH t.p e.branch) e.rest,
88        <Unstick-Blocks e.branch> :: e.new-branch (e.Fe),
89        { e.Fe : FAIL; (e.Fe); } :: e.Fe,
90        e.rest (e.br (BRANCH t.p e.new-branch)) (e.Fes e.Fe);
91    } :: e.branches (e.br) (e.Fes),
92    e.branches : /*empty*/ =
93    {
94      eR : \{
95        (BLOCK  t (BRANCH t (LEFT e) e) e) e;
96        (BLOCK  t (BRANCH t (RIGHT e) e) e) e;
97        (BLOCK? t (BRANCH t (LEFT e) e) e) e;
98        (BLOCK? t (BRANCH t (RIGHT e) e) e) e;
99        (LEFT e) e;
100        (RIGHT e) e;
101      } =
102        <Gener-Var-Indices 1 (<MSG e.Fes>) "aux" "block"> :: e.aux s,
103        eL (s.block t.Pragma e.br) (FORMAT (PRAGMA) e.aux)
104        (RESULT (PRAGMA) e.aux) <Unstick-Blocks eR>;
105      eR : /*empty*/ =
106        eL (s.block t.Pragma e.br) (<MSG e.Fes>);
107      eL (s.block t.Pragma e.br) <Unstick-Blocks eR>;
108    };
109  (RESULT t.Pragma e.Re) eR =
110    <Flatten-Result 1 () e.Re> :: e.assigns s (e.Re),
111    {
112      eR : v =
113        eL e.assigns (RESULT t.Pragma e.Re) <Unstick-Blocks eR>;
114      eL e.assigns (RESULT t.Pragma e.Re) (<Format-Exp e.Re>);
115    };
116  (ITER (BRANCH t.p1 e.body) t.IterVars (BRANCH t.p2 e.condition)) =
117    <Unstick-Blocks e.body> :: e.body t,
118    <Unstick-Blocks e.condition> :: e.condition (e.Format),
119    eL (ITER (BRANCH t.p1 e.body) t.IterVars (BRANCH t.p2 e.condition)) (e.Format);
120  (TRY (BRANCH t.p1 e.TrySnt) e.NOFAIL t.CatchBlock) =
121    <Unstick-Blocks e.TrySnt> :: e.TrySnt t.Try-Fe,
122    <Unstick-Blocks t.CatchBlock> :: e.CatchBlock t.Catch-Fe,
123    eL (TRY (BRANCH t.p1 e.TrySnt) e.NOFAIL e.CatchBlock) (<MSG t.Try-Fe t.Catch-Fe>);
124  (FAIL e) = e.Sentence (FAIL);
125  (ERROR t.Pragma) eR =
126    <Unstick-Blocks eR> :: eR t,
127    eL (ERROR t.Pragma) eR (FAIL);
128};
129
130Flatten-Result s.N (e.Re) e.items, e.items : {
131  t1 e.rest, t1 : \{ (BLOCK e); (BLOCK? e); } =
132    <Gener-Var-Indices s.N (<Format-Exp e.Re>) "aux" "result"> :: e.aux1 s.N,
133    <Unstick-Blocks t1> :: e1 (e.Format),
134    <Gener-Var-Indices s.N (e.Format) "aux" "block"> :: e.aux2 s.N,
135    (RESULT (PRAGMA) e.Re) (FORMAT (PRAGMA) e.aux1)
136    e1 (FORMAT (PRAGMA) e.aux2)
137    <Flatten-Result s.N (e.aux1 e.aux2) e.rest>;
138  (PAREN e.r) e.rest =
139    <Flatten-Result s.N () e.r> :: e.assigns s.N (e.r),
140    e.assigns <Flatten-Result s.N (e.Re (PAREN e.r)) e.rest>;
141  (CALL t.p t.name e.r) e.rest =
142    <Flatten-Result s.N () e.r> :: e.assigns s.N (e.r),
143    e.assigns <Flatten-Result s.N (e.Re (CALL t.p t.name e.r)) e.rest>;
144  t1 e.rest = <Flatten-Result s.N (e.Re t1) e.rest>;
145  /*empty*/ = s.N (e.Re);
146};
147
148
149/*
150 * Generate variable names for input function parameters. Change e.Sentence so
151 * that it doesn't begin with pattern.
152 */
153Generate-In-Vars (e.in) e.Sentence, {
154  /*
155   * If input PAlt of a function is a sentence (not a block), format of
156   * input pattern coincides t.InputFormat, and all variables in input
157   * pattern have different indexes then we can drop the pattern and define
158   * function as
159   *    func (Fname (pattern_vars) (res_..., res_..., ...))
160   * where pattern_vars means variables used in the pattern.
161   */
162  e.Sentence : \{
163    (LEFT t e.Pe) e.Snt = (e.Pe) e.Snt;
164    (RIGHT t e.Pe) e.Snt = (e.Pe) e.Snt;
165  } :: (e.Pe) e.Snt =
166    {
167      <Format-Exp e.Pe> : e.in,  // FIXME: here should be checked format equality
168        <Vars e.Pe> :: e.args,
169        # \{ e.args : e (e t1) e (e t1) e; } =
170        (e.Pe) e.Snt;
171      <Gener-Var-Indices 1 (e.in) "arg"> :: e.in-expr s =
172        (e.in-expr) (RESULT (PRAGMA) e.in-expr) e.Sentence;
173    };
174  /*
175   * Else if we have real PAlt then we can do that transformation with each
176   * branch. Input parameters for the function will be arg_1...arg_N. If
177   * first pattern in the branch satisfies the conditions then drop it out
178   * and rename variables in the branch to arg_1...arg_N instead of pattern
179   * variables.
180   */
181  e.Sentence : (s.block t.Pragma e.branches) e.Snt =
182    <Gener-Var-Indices 1 (e.in) "arg"> :: e.in-expr s,
183    <Vars e.in-expr> :: e.in-vars,
184    (/*e.br*/) e.branches $iter {
185      e.branches : (BRANCH t.p (s.dir t.pp e.Pe) e.br-snt) e.rest, {
186        <Format-Exp e.Pe> : e.in,  // FIXME: here should be checked format equality
187          <Vars e.Pe> :: e.vars,
188          # \{ e.vars : e (e t1) e (e t1) e; } =
189          <Build-Subst (e.vars) (e.in-vars) e.br-snt> :: (e.pats) (e.repls),
190          (e.br (BRANCH t.p <Subst (e.pats) (e.repls) e.br-snt>)) e.rest;
191        (e.br (BRANCH t.p (s.dir t.pp e.Pe) e.br-snt)) e.rest;
192      };
193    } :: (e.br) e.branches,
194    e.branches : /*empty*/ =
195    (e.in-expr) (s.block t.Pragma e.br) e.Snt;
196  /*
197   * Else sentence already hasn't begun with pattern, so left it as it is.
198   * It can be only if e.in and e.out are both empty.
199   */
200//!     (e.in) e.Sentence;
201} :: (e.in) e.Sentence =
202  (e.in) e.Sentence;
203
204/*
205 * Each {}-block is seen as inlined function. e.upper-vars and e.res-vars are
206 * correspondingly input and output parameters for that function. e.Snt is its
207 * body.
208 * Rename all variables local for inlined function, for those to be
209 * distinguishable from the outer world when the function is inlined in
210 * imperative language.
211 */
212Rename-Vars s.num (e.upper-vars) (e.res-vars) e.Snt =
213  (e.upper-vars) (/*e.new-Snt*/) e.Snt $iter {
214    e.Snt : t.Statement e.rest, {
215      /*
216       * If we meet a pattern then add each unknown variable from it to
217       * the list and rename local variables which intersect with out
218       * parameters of the block.
219       */
220      t.Statement : \{
221        (LEFT t e.Pe) = e.Pe;
222        (RIGHT t e.Pe) = e.Pe;
223      } :: e.Pe =
224        <Split &Old-Var? e.res-vars (<Vars e.Pe>)> :: (e.old-vars) (e.new-vars),
225        <Map &Rename s.num (e.old-vars)> :: e.renames,
226        <Build-Subst (e.old-vars) (e.renames) e.Snt> :: (e.pats) (e.repls),
227        <Subst (e.pats) (e.repls) e.Snt> : (s.tag t.p e.Pe1) e.rest-Snt,
228        (<Or (e.vars) <Vars e.Pe1>>) (e.new-Snt (s.tag t.p e.Pe1)) e.rest-Snt;
229      /*
230       * If we meet format expression then for each already used
231       * variable in it select new name by adding prefix "ren".
232       */
233      t.Statement : (FORMAT t e.He) =
234        <Split &Old-Var? e.upper-vars e.res-vars (<Vars e.He>)>
235          :: (e.old-vars) (e.new-vars),
236        <Map &Rename s.num (e.old-vars)> :: e.renames,
237        <Build-Subst (e.old-vars) (e.renames) e.Snt> :: (e.pats) (e.repls),
238        <Subst (e.pats) (e.repls) e.Snt> : (FORMAT t.p e.He1) e.rest-Snt,
239        (<Or (e.vars) <Vars e.He1>>) (e.new-Snt (FORMAT t.p e.He1)) e.rest-Snt;
240      /*
241       * We shouldn't rename variable if its duplicate is appeared on
242       * a parallel branch of the block. So process all branches
243       * iteratively with the same list of variables (known before
244       * block).
245       */
246      t.Statement : (s.block t.Pragma e.branches), s.block : \{ BLOCK; BLOCK?; } =
247        /*
248         * As well as after-block patterns, formats should be scaned
249         * for res-vars.  See samples/Syntax/block1.rf for example.
250         */
251        e.rest : {
252          (LEFT t e.Pe) e = <Vars e.Pe>;
253          (RIGHT t e.Pe) e = <Vars e.Pe>;
254          (FORMAT t e.He) e = <Vars e.He>;
255          /*empty*/ = e.res-vars;
256          e = /*empty*/;
257        } :: e.bl-res-vars,
258        /*
259         * Left as res-vars only variables which were unknown before
260         * block. Those are local if meet in pattern and need
261         * renaming.
262         */
263        (/*e.brv*/) e.bl-res-vars $iter {
264          e.bl-res-vars : e1 (e t.name) e2, e.vars : e (e t.name) e =
265            (e.brv e1) e2;
266          (e.brv e.bl-res-vars);
267        } :: (e.brv) e.bl-res-vars,
268        e.bl-res-vars : /*empty*/ =
269        <Map &Rename-Vars <"+" s.num 1> (e.vars) (e.brv) (e.branches)>
270          :: e.branches,
271        (e.vars) (e.new-Snt (s.block t.Pragma e.branches)) e.rest;
272      t.Statement : (BRANCH t.Pragma e.Sentence) =
273        () (e.new-Snt (BRANCH t.Pragma
274            <Rename-Vars s.num (e.vars) (e.res-vars) e.Sentence>));
275      t.Statement : (ITER t.IterBody t.IterVars t.IterCondition) =
276        <Rename-Vars
277          s.num (e.upper-vars) (e.res-vars) t.IterVars t.IterBody
278        > : t t.NewBody,
279        <Rename-Vars
280          s.num (e.upper-vars) (e.res-vars) t.IterVars t.IterCondition
281        > :: e.IterCondition,
282        () (e.new-Snt (ITER t.NewBody e.IterCondition));
283      t.Statement : (TRY t.TryBranch e.NOFAIL t.Catch) =
284        <Rename-Vars s.num (e.upper-vars) (e.res-vars) t.TryBranch> :: e.TryBranch,
285        <Rename-Vars s.num (e.upper-vars) (e.res-vars) t.Catch> :: e.Catch,
286        () (e.new-Snt (TRY e.TryBranch e.NOFAIL e.Catch));
287      /*
288       * Else proceed with the rest.
289       */
290      (e.vars) (e.new-Snt t.Statement) e.rest;
291    };
292  } :: (e.vars) (e.new-Snt) e.Snt,
293  e.Snt : /*empty*/ =
294  e.new-Snt;
295
296Old-Var? e.vars (s.tag t (e.QualifiedName)) = e.vars : e (s.tag t (e.QualifiedName)) e;
297
298Rename s.num (s.tag t.p (e.QualifiedName)) =
299  (s.tag t.p (e.QualifiedName "_" s.num));
300
301/*
302 * Build substitution for all occurrences of each e.var in e.Snt.
303 */
304Build-Subst {
305  ((s t t.name) e.vars) ((s t t.s) e.substs) e.Snt =
306    <Var-Subst t.name t.s e.Snt> :: (e.var-pats) (e.var-repls),
307    <Build-Subst (e.vars) (e.substs) e.Snt> :: (e.pats) (e.repls),
308    (e.var-pats e.pats) (e.var-repls e.repls);
309  () () e = () ();
310};
311
312/*
313 * Build substitution for all occurrences of variable with the name t.n in e.Snt.
314 */
315Var-Subst t.n t.s e.Snt, {
316  e.Snt : t.Statement e.rest, {
317    t.Statement : \{
318      (SVAR t.p t.name) = SVAR t.p t.name;
319      (TVAR t.p t.name) = TVAR t.p t.name;
320      (VVAR t.p t.name) = VVAR t.p t.name;
321      (EVAR t.p t.name) = EVAR t.p t.name;
322    } :: s.tag t.p t.name,
323      {
324        t.name : t.n = ((s.tag t.p t.name)) (((s.tag t.p t.s)));
325        () ();
326      };
327    t.Statement : (expr) = <Var-Subst t.n t.s expr>;
328    () ();
329  } :: (e.st-pats) (e.st-repls),
330    <Var-Subst t.n t.s e.rest> :: (e.pats) (e.repls),
331    (e.st-pats e.pats) (e.st-repls e.repls);
332  () ();
333};
334
335
336/////////////////////////// Variables Using Analysis /////////////////////////
337//
338//$func Post-Comp (e.used-vars) e.comp-func = (e.used-vars) e.result-func;
339//
340//Post-Comp (e.used-vars) e.comp-func, e.comp-func : {
341//  /*
342//   * As well as "Used" shouldn't be "Declare" statements added?
343//   */
344//  e.something (Used e.vars) =
345//    <Post-Comp (<Or (e.used-vars) e.vars>) e.something>;
346//  e.something (If-used (e.vars) e.statements), {
347//    <Split &Elem? e.vars (e.used-vars)> : (v.true-used) (e.yet-not-used) =
348//      <Post-Comp (v.true-used) e.statements> :: (e.expr-vars) e.expr,
349//      <Post-Comp (<Or (e.yet-not-used) e.expr-vars>) e.something> e.expr;
350//    <Post-Comp (e.used-vars) e.something>;
351//  };
352//  e.something (e.expr) =
353//    <Post-Comp (e.used-vars) e.expr> :: (e.expr-vars) e.expr,
354//    <Post-Comp (e.expr-vars) e.something> (e.expr);
355//  e.something s.symbol =
356//    <Post-Comp (e.used-vars) e.something> s.symbol;
357//  /*empty*/ = (e.used-vars);
358//};
359
360
361/////////////////////////// Static Clash Analysis ///////////////////////////
362//
363//$func? Split-Clashes (e.clashes) e.Snt =
364//  (e.greater) (e.less) (e.hards) (e.clashes) e.Snt;
365//
366//$func? Improve-Clash (e.Re) (s.dir e.Pe) (e1) (e2) e.Snt = e.clashes (e.Snt);
367//
368//$func? Self-Occur (e.Re) e.Pe = e;
369//
370//$func Cyclic e.expr = e.cyclic-vars;
371//
372//$func Hard e.expr = e.hard-part;
373//
374//$func Exchange (e.var-holder) (e.new-expr) e.clashes (e.Snt) =
375//  e.clashes (e.Snt);
376//
377//$func Exchange-Exp (e.change) (e1) (e2) e.Snt = (e1) (e2) e.Snt;
378//
379//$func Minimize (e.expr) (e.clashes) e.Snt = (e.clashes) (e.less) e.Snt;
380//
381//$func? Intersect s.k (e.l) s.m (e.n) = s.x (e.y);
382//
383//$func Min-Length e.expr = s.min-length;
384//
385//$func Max-Length e.expr = e.max-length;
386//
387//$func? Add-Less-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt =
388//  (e.clashes1) (e.clashes2) e.Snt;
389//
390//$func? Add-Greater-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt =
391//  (e.clashes1) (e.clashes2) e.Snt;
392//
393//$func Get-Min e.vars = s.min;
394//
395//$func Get-Max e.vars = e.max;
396//
397//$func Mults e.vars = e.mults;
398//
399//$func Mark-Unw-Hard (e.vars) e.clashes = e.clashes;
400//
401//$func Ceil s1 s2 = s;
402//
403//$func? Match-Exp (e.Re) e.Pe = s.left s.right;
404//
405//$func? Match e.clash = ;
406//
407//$func? Match-Term t.Rt t.Pt e.clashes = e.clashes;
408//
409//$func? Match-Cyclic (e.Re) (e.Pe) e.clashes = e.clashes;
410//
411//$func Granulate e.expr = e.expr;
412//
413//$func? Left-Exp s.left s.len e.expr = (e.expr) e.change;
414//
415//$func? Right-Exp s.right s.len e.expr = (e.expr) e.change;
416//
417//$func? Middle-Exp s.left s.right e.expr = (e.expr) e.change;
418//
419*$func Comp-Pattern t.Pattern e.Snt = e.asail-Snt;
420*
421*Comp-Pattern (s.dir e.PatternExp) e.Sentence =
422*       <Norm-Vars (<Vars e.PatternExp>) (s.dir e.PatternExp) e.Sentence>
423*               : t t.Pattern e.Snt,
424*//     (Unwatched (<? &Last-Re>) t.Pattern) e.Snt $iter {
425*       /*
426*        * Uncomment previous line and delete next one to activate Split-Clashes
427*        * function
428*        */
429*       ((<? &Last-Re>) t.Pattern) e.Snt $iter {
430*               e.Snt : (RESULT e.Re) (s.d e.Pe) e =
431*//                     <WriteLN Matching (RESULT e.Re) (s.d e.Pe)>,
432*                       <Norm-Vars (<Vars e.Pe>) e.Snt> : t t.R t.P e.rest,
433*//                     (e.clashes Unwatched (e.Re) t.P) e.rest;
434*                       /*
435*                        * Uncomment previous line and delete next one to activate
436*                        * Split-Clashes function
437*                        */
438*                       (e.clashes (e.Re) t.P) e.rest;
439*       } :: (e.clashes) e.Snt,
440*       # \{
441*               e.Snt : \{
442*                       (RESULT e.Re) (LEFT e) e = e.Re;
443*                       (RESULT e.Re) (RIGHT e) e = e.Re;
444*               } :: e.Re,
445*                       <Without-Calls? e.Re>;
446*       } =
447*       e.Snt : e.Current-Snt (Comp Sentence) e.Other-Snts =
448*       <Comp-Sentence () e.Other-Snts> :: e.asail-Others,
449*       {
450*//             <Split-Clashes (e.clashes) e.Current-Snt>
451*//             :: (e.greater) (e.less) (e.hards) (e.clashes) e.Current-Snt =
452*//                     <WriteLN "Hards: " e.hards>,
453*//                     <WriteLN "Less: " e.less>,
454*//                     <WriteLN "Greater: " e.greater>,
455*//                     <WriteLN "Current-Snt: " e.Current-Snt>,
456*//!                    <Comp-Clashes (e.clashes)
457*//!                            (e.Current-Snt (Comp Sentence)) e.Other-Snts> :: e.asail-Clashes,
458*//                     e.asail-Clashes (e.greater) $iter {
459*//                             e.greater : (e.vars s.num) e.rest,
460*//                                     <Old-Vars e.vars> :: e.vars,  // temporary step
461*//                                     (IF ((INFIX ">=" ((LENGTH e.vars)) (s.num)))
462*//                                             e.asail-Clashes
463*//                                     ) (e.rest);
464*//                     } :: e.asail-Clashes (e.greater),
465*//                     e.greater : /*empty*/ =
466*//                     e.asail-Clashes (e.less) $iter {
467*//                             e.less : (e.vars s.num) e.rest,
468*//                                     <Old-Vars e.vars> :: e.vars,  // temporary step
469*//                                     (IF ((INFIX "<=" ((LENGTH e.vars)) (s.num)))
470*//                                             e.asail-Clashes
471*//                                     ) (e.rest);
472*//                     } :: e.asail-Clashes (e.less),
473*//                     e.less : /*empty*/ =
474*//                     e.asail-Clashes (e.hards) $iter {
475*//                             e.hards : (e.Re) (e.Pe) e.rest,
476*//                                     <Old-Vars e.Re> :: e.Re,    // temporary step
477*//                                     <Old-Vars e.Pe> :: e.Pe,    // temporary step
478*//                                     (IF ((INFIX "==" (e.Re) (e.Pe))) e.asail-Clashes) (e.rest);
479*//                     } :: e.asail-Clashes (e.hards),
480*//                     e.hards : /*empty*/ =
481*//!                    e.asail-Clashes e.asail-Others;
482*               e.asail-Others;
483*//             <Comp-Sentence () e.Other-Snts>;
484*       };
485//
486//Split-Clashes (e.clashes) e.Snt =
487//  e.clashes (e.Snt) () () () $iter e.clashes : {
488//    e1 Unwatched (e.Re) (s.dir e.Pe) e2, { \?
489//      \{
490//        \{
491//          <Self-Occur (e.Re) e.Pe> : {
492//            Occur e.vars =
493//              <Minimize (e.vars) (e1 e2) e.Snt>
494//                :: (e.clashes) (e.new-less) e.Snt,
495//              e.clashes (e.Snt)
496//              (e.greater) (e.less e.new-less) (e.hards);
497//            /*empty*/ \! $fail;
498//          };
499//          <Self-Occur (e.Pe) e.Re> : {
500//            Occur e.vars =
501//              <Minimize (e.vars) (e1 e2) e.Snt>
502//                :: (e.clashes) (e.new-less) e.Snt,
503//              e.clashes (e.Snt)
504//              (e.greater) (e.less e.new-less) (e.hards);
505//            /*empty*/ \! $fail;
506//          };
507//        };
508//        <Vars e.Re> : /*empty*/, \{ // e.Re is ground expression
509//          <Vars e.Pe> : /*empty*/ \! // e.Pe is ground expression
510//            $fail;
511//          e.Pe : \{
512//            /*
513//             * If e.Pe is symbol then e.Re should be a symbol and if
514//             * e.Pe is "old" variable then we should remember clash
515//             * "e.Re : e.Pe" as hard.
516//             */
517//            (SVAR 1 (1) e.name) \!
518//              e.Re : s,
519//              {
520//                <Known-Vars? (SVAR e.name)> = (e.Re) (e.Pe);
521//                /*empty*/;
522//              } :: e.new-hard,
523//              <Exchange (e.Pe) (e.Re) e1 e2 (e.Snt)>
524//                (e.greater) (e.less) (e.hards e.new-hard);
525//            /*
526//             * If e.Pe is parenthesized expression then e.Re should be
527//             * parenthesized expression too and we can take parentheses
528//             * off.
529//             */
530//            (PAREN e.pat-expr) \!
531//              e.Re : (PAREN e.re-expr),
532//              e1 Unwatched (e.re-expr) (s.dir e.pat-expr) e2
533//              (e.Snt) (e.greater) (e.less) (e.hards);
534//            /*
535//             * If e.Pe is any other variable then length of e.Re (which
536//             * can be zero) should belong to its range. If e.Pe is
537//             * "old" variable and e.Re is empty expression then we
538//             * should remember that length of e.Pe is less or equal to
539//             * 0 and if e.Re isn't empty then we should remember clash
540//             * "e.Re : e.Pe" as hard.
541//             */
542//            (s.var-tag s.m (e.n) e.name) \!
543//              <Intersect s.m (e.n) <Length e.Re> (<Length e.Re>)> : e,
544//              {
545//                <Known-Vars? (s.var-tag e.name)>,
546//                  {
547//                    e.Re : /*empty*/ = (e.Pe 0) ();
548//                    /*empty*/ ((e.Re) (e.Pe));
549//                  };
550//                /*empty*/ ();
551//              } :: e.new-less (e.new-hard),
552//              <Exchange (e.Pe) (e.Re) e1 e2 (e.Snt)>
553//              (e.greater) (e.less e.new-less) (e.hards e.new-hard);
554//          };
555//        };
556//        <Vars e.Pe> : /*empty*/, e.Re : \{
557//          (SVAR 1 (1) e.name) \!
558//            e.Pe : s,
559//            {
560//              <Known-Vars? (SVAR e.name)> = (e.Re) (e.Pe);
561//              /*empty*/;
562//            } :: e.new-hard,
563//            <Exchange (e.Re) (e.Pe) e1 e2 (e.Snt)>
564//              (e.greater) (e.less) (e.hards e.new-hard);
565//          (PAREN e.re-expr) \!
566//            e.Pe : (PAREN e.pe-expr),
567//            e1 Unwatched (e.re-expr) (s.dir e.pe-expr) e2
568//            (e.Snt) (e.greater) (e.less) (e.hards);
569//          (s.var-tag s.m (e.n) e.name) \!
570//            <Intersect s.m (e.n) <Length e.Pe> (<Length e.Pe>)> : e,
571//            {
572//              <Known-Vars? (s.var-tag e.name)>,
573//                {
574//                  e.Pe : /*empty*/ = (e.Re 0) ();
575//                  /*empty*/ ((e.Re) (e.Pe));
576//                };
577//              /*empty*/ ();
578//            } :: e.new-less (e.new-hard),
579//            <Exchange (e.Re) (e.Pe) e1 e2 (e.Snt)>
580//            (e.greater) (e.less e.new-less) (e.hards e.new-hard);
581//        };
582//        e.Re : \{
583//          (PAREN e.re-expr), e.Pe : \{
584//            (PAREN e.pe-expr) =
585//              e1 Unwatched (e.re-expr) (s.dir e.pe-expr) e2
586//              (e.Snt) (e.greater) (e.less) (e.hards);
587//            (SVAR e) \!
588//              $fail;
589//            (s.tag s.m (e.n) e.var-id) \!
590//              e.var-id : e.NEW (e.QualifiedName),
591//              <Intersect 1 (1) s.m (e.n)> :: e,
592//              (s.tag 0 () NEW ("paren" e.QualifiedName)) :: t.new-var,
593//              {
594//                <Known-Vars? (s.tag e.var-id)> =
595//                  Watched (e.Pe) (s.dir (PAREN t.new-var));
596//                /*empty*/;
597//              } :: e.new-clash,
598//              <Exchange (e.Pe) ((PAREN t.new-var)) e1 ()> :: e1 t,
599//              e.new-clash e1 Unwatched (e.re-expr) (s.dir t.new-var)
600//              <Exchange (e.Pe) ((PAREN t.new-var)) e2 (e.Snt)>
601//              (e.greater) (e.less) (e.hards);
602//          };
603//          (SVAR 1 (1) e.name), e.Pe : \{
604//            s.ObjectSymbol =
605//              {
606//                <Known-Vars? (SVAR e.name)> = (e.Re) (e.Pe);
607//                /*empty*/;
608//              } :: e.new-hard,
609//              <Exchange (e.Re) (e.Pe) e1 e2 (e.Snt)>
610//              (e.greater) (e.less) (e.hards e.new-hard);
611//            (PAREN e) \!
612//              $fail;
613//            (s.tag s.m (e.n) e.var-id) \!
614//              <Intersect 1 (1) s.m (e.n)> :: e,
615//              {
616//                <Known-Vars? (s.tag e.var-id)>, {
617//                  <Known-Vars? (SVAR e.name)> =
618//                    ((e.Re) (e.Pe)) ();
619//                  () (Watched (e.Pe) (s.dir e.Re));
620//                };
621//                () ();
622//              } :: (e.new-hard) (e.new-clash),
623//              e.new-clash <Exchange (e.Pe) (e.Re) e1 e2 (e.Snt)>
624//              (e.greater) (e.less) (e.hards e.new-hard);
625//          };
626//          (s.tag s.m (e.n) e.var-id), TVAR VVAR EVAR : e s.tag e, \{
627//            e.Pe : (s.tag1 s.k (e.l) e.var-id1),
628//              TVAR VVAR EVAR : e s.tag1 e \!
629//              <Intersect s.m (e.n) s.k (e.l)> :: s.x (e.y),
630//              {
631//                <Known-Vars? (s.tag e.var-id)>, {
632//                  <Known-Vars? (s.tag1 e.var-id1)> =
633//                    (s.tag s.x (e.y) e.var-id) (e.Re) (e.Pe);
634//                  (s.tag s.x (e.y) e.var-id) /*empty*/;
635//                };
636//                (s.tag1 s.x (e.y) e.var-id1) /*empty*/;
637//              } :: t.new-var e.new-hards,
638//              <Exchange (e.Re) (t.new-var) e1 e2 (e.Snt)>
639//                :: e.clashes (e.Snt),
640//              <Exchange (e.Pe) (t.new-var) e.clashes (e.Snt)>
641//              (e.greater) (e.less) (e.hards e.new-hards);
642//          };
643//        };
644//        e.Pe : \{
645//          (PAREN e.pe-expr), e.Re : \{
646//            (s.tag s.m (e.n) e.var-id) \!
647//              e.var-id : e.NEW (e.QualifiedName),
648//              <Intersect 1 (1) s.m (e.n)> :: e,
649//              (s.tag 0 () NEW ("paren" e.QualifiedName)) :: t.new-var,
650//              {
651//                <Known-Vars? (s.tag e.var-id)> =
652//                  Watched (e.Re) (s.dir (PAREN t.new-var));
653//                /*empty*/;
654//              } :: e.new-clash,
655//              <Exchange (e.Re) ((PAREN t.new-var)) e1 ()> :: e1 t,
656//              e.new-clash e1 Unwatched (t.new-var) (s.dir e.pe-expr)
657//              <Exchange (e.Re) ((PAREN t.new-var)) e2 (e.Snt)>
658//              (e.greater) (e.less) (e.hards);
659//          };
660//          (SVAR 1 (1) e.name), e.Re : \{
661//            (s.tag s.m (e.n) e.var-id) \!
662//              <Intersect 1 (1) s.m (e.n)> :: e,
663//              {
664//                <Known-Vars? (s.tag e.var-id)>, {
665//                  <Known-Vars? (SVAR e.name)> =
666//                    ((e.Re) (e.Pe)) ();
667//                  () (Watched (e.Re) (s.dir e.Pe));
668//                };
669//                () ();
670//              } :: (e.new-hard) (e.new-clash),
671//              e.new-clash <Exchange (e.Re) (e.Pe) e1 e2 (e.Snt)>
672//              (e.greater) (e.less) (e.hards e.new-hard);
673//          };
674//        };
675//        e.Re : t.Rt e.Re1, e.Pe : t.Pt e.Pe1,
676//          <Min-Length t.Rt> :: s.rt-min, <Min-Length t.Pt> :: s.pt-min,
677//          # \{ s.rt-min : 0; s.pt-min : 0; } =
678//          {
679//            <Left-Exp 0 s.rt-min t.Pt> (<Left-Exp 0 s.rt-min t.Rt>);
680//            <Left-Exp 0 s.pt-min t.Rt> (<Left-Exp 0 s.pt-min t.Pt>);
681//          } :: t e.change1 (t e.change2),
682//          e1 Unwatched (e.Re) (e.Pe) :: e1,
683//          <Exchange-Exp (e.change1)
684//            <Exchange-Exp (e.change2) (e1) (e2) e.Snt>>
685//            :: (e1) (e2) e.Snt,
686//          {
687//            e.change1 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2,
688//              <Known-Vars? (s.tag e.var-id)> =
689//              Watched
690//              ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2);
691//            /*empty*/;
692//          } :: e.new-clash1,
693//          {
694//            e.change2 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2,
695//              <Known-Vars? (s.tag e.var-id)> =
696//              Watched
697//              ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2);
698//            /*empty*/;
699//          } :: e.new-clash2,
700//          e1 : e11 (t.Rt1 e.Re2) (t.Pt1 e.Pe2),
701//          e.new-clash1 e.new-clash2 e11 (t.Rt1) (s.dir t.Pt1)
702//          Unwatched (e.Re2) (s.dir e.Pe2) e2
703//          (e.Snt) (e.greater) (e.less) (e.hards);
704//        e.Re : e.Re1 t.Rt, e.Pe : e.Pe1 t.Pt,
705//          <Min-Length t.Rt> :: s.rt-min, <Min-Length t.Pt> :: s.pt-min,
706//          # \{ s.rt-min : 0; s.pt-min : 0; } =
707//          {
708//            <Right-Exp 0 s.rt-min t.Pt> (<Right-Exp 0 s.rt-min t.Rt>);
709//            <Right-Exp 0 s.pt-min t.Rt> (<Right-Exp 0 s.pt-min t.Pt>);
710//          } :: t e.change1 (t e.change2),
711//          e1 Unwatched (e.Re) (e.Pe) :: e1,
712//          <Exchange-Exp (e.change1)
713//            <Exchange-Exp (e.change2) (e1) (e2) e.Snt>>
714//            :: (e1) (e2) e.Snt,
715//          {
716//            e.change1 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2,
717//              <Known-Vars? (s.tag e.var-id)> =
718//              Watched
719//              ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2);
720//            /*empty*/;
721//          } :: e.new-clash1,
722//          {
723//            e.change2 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2,
724//              <Known-Vars? (s.tag e.var-id)> =
725//              Watched
726//              ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2);
727//            /*empty*/;
728//          } :: e.new-clash2,
729//          e1 : e11 (e.Re2 t.Rt1) (e.Pe2 t.Pt1),
730//          e.new-clash1 e.new-clash2 e11 (e.Re2) (s.dir e.Pe2)
731//          Unwatched (t.Rt1) (s.dir t.Pt1) e2
732//          (e.Snt) (e.greater) (e.less) (e.hards);
733//        <Max-Length e.Re> : /*empty*/, <Max-Length e.Pe> : /*empty*/ \!
734//          <Min-Length e.Re> :: s.re-min,
735//          <Min-Length e.Pe> :: s.pe-min,
736//          e1 Unwatched Hard (e.Re) (s.dir e.Pe) :: e1,
737//          {
738//            <"<" (s.re-min) (s.pe-min)> =
739//              <Add-Greater-Ineq (<Cyclic e.Re> s.pe-min)
740//                (e1) (e2) e.Snt>;
741//            <">" (s.re-min) (s.pe-min)> =
742//              <Add-Greater-Ineq (<Cyclic e.Pe> s.re-min)
743//                (e1) (e2) e.Snt>;
744//            (e1) (e2) e.Snt;
745//          } :: (e1) (e2) e.Snt,
746//          e1 e2 (e.Snt) (e.greater) (e.less) (e.hards);
747//        {
748//          <Max-Length e.Re> : s.re-max, {
749//            <Max-Length e.Pe> : s.pe-max, {
750//              <"<" (s.re-max) (s.pe-max)> = e.Pe s.re-max;
751//              e.Re s.pe-max;
752//            };
753//            e.Pe s.re-max;
754//          };
755//          e.Re <Max-Length e.Pe>;
756//        } : e.ineq s.max \!
757//          <"-" s.max <Min-Length <Hard e.ineq>>> :: s.max,
758//          <Cyclic e.ineq> :: e.cyclic,
759//          <Add-Less-Ineq (e.cyclic s.max)
760//            (e1 Unwatched Hard (e.Re) (s.dir e.Pe)) (e2) e.Snt>
761//            :: (e1) (e2) e.Snt \?
762//          {
763//            e1 : e Unwatched Hard t t \!
764//              <Min-Length e.Re> :: s.re-min,
765//              <Min-Length e.Pe> :: s.pe-min,
766//              {
767//                <"<" (s.re-min) (s.pe-min)> = e.Re s.pe-min;
768//                e.Pe s.re-min;
769//              } :: e.ineq s.min,
770//              <"-" s.min <Min-Length <Hard e.ineq>>> :: s.min,
771//              <Cyclic e.ineq> :: e.cyclic,
772//              <Add-Greater-Ineq (e.cyclic s.min) (e1) (e2) e.Snt>
773//                :: (e1) (e2) e.Snt,
774//              e1 e2 (e.Snt) (e.greater) (e.less) (e.hards);
775//            e1 e2 (e.Snt) (e.greater) (e.less) (e.hards);
776//          };
777//      };
778//      = <Print-Error Warning! Pattern (e.Re ' : ' e.Pe)>, $fail;
779//    };
780//    e1 Unwatched Hard (e.Re) (s.dir e.Pe) e2, {
781//      <Cyclic e.Re> : /*empty*/, {  // e.Re is hard expression
782//        <Improve-Clash (e.Re) (s.dir e.Pe) (e1) (e2) e.Snt>
783//          (e.greater) (e.less) (e.hards);
784//        <Print-Error Warning! Pattern (e.Re ' : ' e.Pe)>
785//          = $fail;
786//      };
787////      <Cyclic e.Pe> : /*empty*/ = // e.Pe is hard expression
788////        <Improve-Clash (e.Pe) (e.Re) (e1) (e2) e.Snt>
789////        (e.greater) (e.less) (e.hards);
790//      e1 (e.Re) (s.dir e.Pe) e2 (e.Snt) (e.greater) (e.less) (e.hards);
791//    };
792//    e1 Watched t.Re t.Pe e2 =
793//      e1 t.Re t.Pe e2 (e.Snt) (e.greater) (e.less) (e.hards);
794//  } :: e.clashes (e.Snt) (e.greater) (e.less) (e.hards),
795////  <WriteLN Sp-Clashes e.clashes>,
796////  <WriteLN G <? &Greater-Ineqs>>,
797////  <WriteLN L <? &Less-Ineqs>>,
798//  # \{ e.clashes : e s e; } =
799//  (e.greater) (e.less) (e.hards) (e.clashes) e.Snt;
800//
801//Improve-Clash (e.Re) (s.dir e.Pe) (e1) (e2) e.Snt =
802////  <WriteLN Improve-Clash (e.Re) (s.dir e.Pe)>,
803//  /*
804//   * Find all non-empty hard parts in e.Pe and remember them in
805//   * e.hard-parts.
806//   */
807//  e.Pe : t.l e.right,
808//  () (t.l) (e.right) <Cyclic e.right> $iter {
809//    e.cyclic : t.var e.rest,
810//      e.right : e.new-hard t.var e.new-right, {
811//        e.new-hard : v =
812//          (e.hard-parts
813//            ((e.left) e.new-hard (t.var e.new-right))
814//          ) (e.left e.new-hard t.var) (e.new-right) e.rest;
815//        (e.hard-parts) (e.left t.var) (e.new-right) e.rest;
816//      };
817//  } :: (e.hard-parts) (e.left) (e.right) e.cyclic,
818//  e.cyclic : /*empty*/ =
819////  <WriteLN Hard-parts e.hard-parts>,
820//  /*
821//   * For each hard part (or until some variables ranges are
822//   * changed or some inequalitys are added) try to match it with
823//   * corresponding part of e.Re.
824//   */
825//  (e.hard-parts)
826//  (e1 (e.Re) (s.dir e.Pe)) (e2) e.Snt $iter {
827//    e.hard-parts : ((e.left-i) e.hard-i (e.right-i)) e.rest,
828//      <Cyclic e.left-i> :: e.cyc-left,
829//      <Hard e.left-i> :: e.hard-left,
830//      <Reverse <Cyclic e.right-i>> :: e.cyc-right,
831//      <Hard e.right-i> :: e.hard-right,
832//      <Min-Length e.hard-left> :: s.left-len,
833//      <Min-Length e.hard-right> :: s.right-len,
834//      <"+" <Get-Min e.cyc-left> s.left-len> :: s.left-min,
835//      <Get-Max e.cyc-left> : s.left-max,
836//      <"+" s.left-max s.left-len> :: s.left-max,
837//      <"+" <Get-Min e.cyc-right> s.right-len> :: s.right-min,
838//      <Get-Max e.cyc-right> : s.right-max,
839//      <"+" s.right-max s.right-len> :: s.right-max,
840//      <Min-Length e.hard-i> :: s.hard-len,
841//      <Min-Length e.Re> :: s.len,
842//      <"-" s.len <"+" s.right-max s.hard-len>> :: s.left,
843//      <"-" s.len <"+" s.left-max s.hard-len>> :: s.right,
844//      <WriteLN Hard e.hard-i>,
845//      <WriteLN Hard-len s.hard-len>,
846//      <WriteLN Left-len s.left-len>,
847//      <WriteLN Right-len s.right-len>,
848//      <WriteLN Len s.len>,
849//      <WriteLN Left s.left>,
850//      <WriteLN Left-min s.left-min>,
851//      <WriteLN Left-max s.left-max>,
852//      <WriteLN Right s.right>,
853//      <WriteLN Right-min s.right-min>,
854//      <WriteLN Right-max s.right-max>,
855//      {
856//        s.left-min : s.left, s.right-min : s.right =
857//          <Middle-Exp s.left s.right e.Re> :: (e.middle) e.change,
858//          <WriteLN Middle-Exp e.middle>,
859//          <Exchange-Exp (e.change) (e1) (e2) e.Snt> :: (e1) (e2) e.Snt,
860//          <Match-Exp (e.middle) e.hard-i> :: s.new-left s.new-right,
861//          <WriteLN Match-Exp s.new-left s.new-right>,
862//          {
863//            s.new-left : 0, s.new-right : 0 =
864//              (e.rest) (e1) (e2) e.Snt;
865//            /*
866//             * If founded matchings are coinsided then split our
867//             * clash into three new ones.
868//             */
869//            <"+" s.hard-len <"+" s.new-left s.new-right>>
870//            : s.len =
871//              <"+" s.left s.new-left> :: s.left,
872//              <"+" s.right s.new-right> :: s.right,
873//              <Left-Exp s.left s.hard-len e.Re> :: (e.left-Re) e.change,
874//              <Exchange-Exp (e.change) (e1) (e2) e.Snt> :: (e1) (e2) e.Snt,
875//              Unwatched (e.left-Re) (s.dir e.hard-i) :: e.new-hard,
876//              <Left-Exp 0 s.left e.Re> :: (e.left-Re) e.change,
877//              <Exchange-Exp (e.change) (e1) (e2) e.Snt> :: (e1) (e2) e.Snt,
878//              Unwatched (e.left-Re) (s.dir e.left-i) :: e.new-left,
879//              <Right-Exp 0 s.right e.Re> :: (e.right-Re) e.change,
880//              <Exchange-Exp (e.change) (e1) (e2) e.Snt> :: (e1) (e2) e.Snt,
881//              Unwatched (e.right-Re) (s.dir e.right-i) :: e.new-right,
882//              s.dir : {
883//                LEFT =
884//                  e.new-hard e.new-left e.new-right;
885//                RIGHT =
886//                  e.new-hard e.new-right e.new-left;
887//              } :: e.new-clashes,
888//              e1 : e1-new t t,
889//              () (e1-new e.new-clashes) (e2) e.Snt;
890//            /*
891//             * Else we've got some new inequalites...
892//             */
893//            =
894//              <"+" s.left <"-" s.new-left s.left-len>> :: s.num,
895//              <WriteLN NUM s.num>,
896//              <Add-Greater-Ineq (e.cyc-left s.num) (e1) (e2) e.Snt>
897//                :: (e1) (e2) e.Snt,
898//              <"+" s.right <"-" s.new-right s.right-len>> :: s.num,
899//              <WriteLN NUM s.num>,
900//              <Add-Greater-Ineq (e.cyc-right s.num) (e1) (e2) e.Snt>
901//                :: (e1) (e2) e.Snt,
902//              <"-" s.len <"+" s.right <"+" s.new-right
903//                <"+" s.hard-len s.left-len>>>> :: s.num,
904//              <WriteLN NUM s.num>,
905//              <Add-Less-Ineq (e.cyc-left s.num) (e1) (e2) e.Snt>
906//                :: (e1) (e2) e.Snt,
907//              <"-" s.len <"+" s.left <"+" s.new-left
908//                <"+" s.hard-len s.right-len>>>> :: s.num,
909//              <WriteLN NUM s.num>,
910//              <Add-Less-Ineq (e.cyc-right s.num) (e1) (e2) e.Snt>
911//                :: (e1) (e2) e.Snt,
912//              (e.rest) (e1) (e2) e.Snt;
913//          };
914//        /*
915//         * At least one inequlity shurely will be added, so we'll go
916//         * out of the $iter.
917//         */
918//        = {
919//          <"<" (s.left-min) (s.left)> =
920//            <Add-Greater-Ineq (e.cyc-left s.left) (e1) (e2) e.Snt>;
921//          (e1) (e2) e.Snt;
922//        } :: (e1) (e2) e.Snt, {
923//          <">" (s.left-min) (s.left)> =
924//            <"-" s.len <"+" s.left-min <"+" s.hard-len s.right-len>>>
925//              :: s.left,
926//            <Add-Less-Ineq (e.cyc-right s.left) (e1) (e2) e.Snt>;
927//          (e1) (e2) e.Snt;
928//        } :: (e1) (e2) e.Snt, {
929//          <"<" (s.right-min) (s.right)> =
930//            <Add-Greater-Ineq (e.cyc-right s.right) (e1) (e2) e.Snt>;
931//          (e1) (e2) e.Snt;
932//        } :: (e1) (e2) e.Snt, {
933//          <">" (s.right-min) (s.right)> =
934//            <"-" s.len <"+" s.right-min <"+" s.hard-len s.left-len>>>
935//              :: s.right,
936//            <Add-Less-Ineq (e.cyc-left s.right) (e1) (e2) e.Snt>;
937//          (e1) (e2) e.Snt;
938//        } :: (e1) (e2) e.Snt,
939//          () (e1) (e2) e.Snt;
940//      };
941//  } :: (e.hard-parts) (e1) (e2) e.Snt,
942//  \{
943//    e1 : \{ e Unwatched (e) (e); e Unwatched Hard (e) (e); };
944//    e.hard-parts : /*empty*/;
945//  } =
946//  e1 e2 (e.Snt);
947//
948///*
949// * If occurrence of e.Pe is found in e.Re and it can be there then return
950// * variables which should be minimized.
951// * If found occurence of e.Re isn't legal then return empty expression.
952// * And return $fail if there are no occurences of e.Re in e.Pe.
953// */
954//Self-Occur (e.Re) e.Pe, <WriteLN Occur (e.Re) e.Pe>, {
955//  e.Re : e1 e.Pe e2 , {
956//    <Min-Length e1 e2> : 0 = Occur e1 e2;
957//    /*empty*/;
958//  };
959//  e.Pe Not-Found $iter {
960//    e.Pe : e (PAREN v.pe-expr) e, {
961//      e.Re : e v.pe-expr e = Found;
962//      v.pe-expr Not-Found;
963//    };
964//  } :: e.Pe s.found?,
965//  \{
966//    s.found? : Found = /*empty*/;
967//    # \{ e.Pe : e (PAREN v) e; } = $fail;
968//  };
969//};
970//
971//Cyclic e.expr =
972//  () e.expr $iter {
973//    e.expr : t1 e2, t1 : {
974//      s.ObjectSymbol = /*empty*/;
975////      (REF t.name) = ???
976//      (PAREN e) = /*empty*/;
977//      (s.var-tag s.m (e.n) e.var-id), # \{ s.m : e.n; } = t1;
978//      t = /*empty*/;
979//    } :: e.new-cyclic,
980//    (e.cyclic e.new-cyclic) e2;
981//  } :: (e.cyclic) e.expr,
982//  e.expr : /*empty*/ =
983//  e.cyclic;
984//
985//Hard e.expr =
986//  () e.expr $iter {
987//    e.expr : t1 e2, t1 : {
988//      s.ObjectSymbol = t1;
989////      (REF t.name) = ???
990//      (PAREN e) = t1;
991//      (s.var-tag s.m (e.n) e.var-id), # \{ s.m : e.n; } = /*empty*/;
992//      t = t1;
993//    } :: e.new-hard,
994//    (e.hard e.new-hard) e2;
995//  } :: (e.hard) e.expr,
996//  e.expr : /*empty*/ =
997//  e.hard;
998//
999////Hard-Exp? e.expr =
1000////  e.expr () $iter \{
1001////    <Cyclic e.expr> () $iter {
1002////      e.cyclic : (s.tag t t e.var-id) e.rest, {
1003////        <Known-Vars? (s.tag e.var-id)> = e.rest (e.num);
1004////        e.rest (e.num I);
1005////      };
1006////    } :: e.cyclic (e.num),
1007////      <WriteLN Hard-Exp e.cyclic (e.num)>,
1008////      \{
1009////        e.num : I I = $fail;
1010////        e.cyclic : /*empty*/, {
1011////          e.expr : e1 (PAREN e.paren) e2 = e.paren (e.watched e2);
1012////          e.watched : e1 (PAREN e.paren) e2 = e.paren (e2);
1013////          /*empty*/ ();
1014////        };
1015////      };
1016////  } :: e.expr (e.watched),
1017////  e.expr : /*empty*/;
1018//
1019//Exchange (e.var-holder) (e.new-expr) e.clashes (e.Snt) =
1020//  e.var-holder : t.var,
1021//  /*
1022//   * Mark containing t.var clashes as "Unwatched" and change t.var to
1023//   * t.new-var in them.
1024//   */
1025//  () e.clashes $iter {
1026//    e.clashes : e.tag (e.Re) (e.Pe) e.rest,
1027//      {
1028//        e.tag : Watched = Watched;
1029//        Unwatched;
1030//      } :: s.watched?,
1031//      {
1032//        <Vars e.Re> <Vars e.Pe> : e t.var e =
1033//          (e.new-clashes
1034//          s.watched? <Subst (t.var) ((e.new-expr)) (e.Re) (e.Pe)>
1035//          ) e.rest;
1036//        (e.new-clashes e.tag (e.Re) (e.Pe)) e.rest;
1037//      };
1038//  } :: (e.new-clashes) e.clashes,
1039//  e.clashes : /*empty*/ =
1040//  /*
1041//   * Remove all inequalitys wich contain t.var.
1042//   */
1043//  () <? &Greater-Ineqs> $iter {
1044//    e.ineqs : t.ineq e.rest,
1045//      {
1046//        t.ineq : (e t.var e) = /*empty*/;
1047//        t.ineq;
1048//      } :: e.ineq,
1049//      (e.new-ineqs e.ineq) e.rest;
1050//  } :: (e.new-ineqs) e.ineqs,
1051//  e.ineqs : /*empty*/ =
1052//  <Store &Greater-Ineqs e.new-ineqs>,
1053//  () <? &Less-Ineqs> $iter {
1054//    e.ineqs : t.ineq e.rest,
1055//      {
1056//        t.ineq : (e t.var e) = /*empty*/;
1057//        t.ineq;
1058//      } :: e.ineq,
1059//      (e.new-ineqs e.ineq) e.rest;
1060//  } :: (e.new-ineqs) e.ineqs,
1061//  e.ineqs : /*empty*/ =
1062//  <Store &Less-Ineqs e.new-ineqs>,
1063//  /*
1064//   * Rename t.var in the rest of current sentence.
1065//   */
1066//  t.var : (s.tag t t e.var-id),     // temporary step
1067////  <Old-Vars e.new-expr> :: e.new-expr,  // temporary step
1068//  e.new-clashes (<Subst ((s.tag e.var-id)) ((e.new-expr)) e.Snt>);
1069//
1070//Exchange-Exp (e.change) (e1) (e2) e.Snt =
1071//{
1072//  e.change : t.old-1 t.new-1 t.new-2 e.change1 =
1073//    <Exchange (t.old-1) (t.new-1 t.new-2) e1 ()> :: e1 t,
1074//    <Exchange (t.old-1) (t.new-1 t.new-2) e2 (e.Snt)> :: e2 (e.Snt),
1075//    {
1076//      e.change1 : t.old-2 e.new-3 =
1077//        <Exchange (t.old-2) (e.new-3) e1 ()> :: e1 t,
1078//        <Exchange (t.old-2) (e.new-3) e2 (e.Snt)> :: e2 (e.Snt),
1079//        (e1) (e2) e.Snt;
1080//      (e1) (e2) e.Snt;
1081//    };
1082//  (e1) (e2) e.Snt;
1083//};
1084//
1085//Minimize (e.expr) (e.clashes) e.Snt =
1086//  (e.expr) () e.clashes (e.Snt) $iter {
1087//    e.expr : t.var e.rest,
1088//      t.var : (s.tag t t e.var-id),
1089//      {
1090//        <Known-Vars? (s.tag e.var-id)> = (t.var 0);
1091//        /*empty*/;
1092//      } :: e.new-less,
1093//      (e.rest) (e.less e.new-less) <Exchange (t.var) () e.clashes (e.Snt)>;
1094//  } :: (e.expr) (e.less) e.clashes (e.Snt),
1095//  e.expr : /*empty*/ =
1096//  (e.clashes) (e.less) e.Snt;
1097//
1098//Intersect s.k (e.l) s.m (e.n) =
1099//  {
1100//    <"<" (s.k) (s.m)> = s.m;
1101//    s.k;
1102//  } :: s.x,
1103//  {
1104//    e.l e.n : /*empty*/ = /*empty*/;
1105//    e.l : /*empty*/ = e.n;
1106//    e.n : /*empty*/ = e.l;
1107//    <"<" (e.n) (e.l)> = e.n;
1108//    e.l;
1109//  } :: e.y,
1110//  \{
1111//    e.y : /*empty*/ = s.x ();
1112//    <"<=" (s.x) (e.y)> = s.x (e.y);
1113//  };
1114//
1115//Min-Length e.expr =
1116//  0 e.expr $iter {
1117//    e.expr : t1 e2, t1 : {
1118//      s.ObjectSymbol = <"+" s.len 1>;
1119////      (REF t.name) = ???
1120//      (PAREN e) = <"+" s.len 1>;
1121//      (s.var-tag s.m (e.n) e.var-id) = <"+" s.len s.m>;
1122//    } :: s.len,
1123//    s.len e2;
1124//  } :: s.len e.expr,
1125//  e.expr : /*empty*/ =
1126//  s.len;
1127//
1128//Max-Length e.expr =
1129//  0 e.expr $iter {
1130//    e.expr : t1 e2, t1 : {
1131//      s.ObjectSymbol = <"+" s.len 1>;
1132////      (REF t.name) = ???
1133//      (PAREN e) = <"+" s.len 1>;
1134//      (s.var-tag s.m (s.n) e.var-id) = <"+" s.len s.n>;
1135//      (s.var-tag s.m () e.var-id) = Empty;
1136//    } :: s.len,
1137//    s.len e2;
1138//  } :: s.len e.expr,
1139//  \{
1140//    s.len : Empty = /*empty*/;
1141//    e.expr : /*empty*/ = s.len;
1142//  };
1143//
1144//Add-Less-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt =
1145//  <Get-Min e.vars> :: s.min, {
1146//    <">" (s.min) (s.len)> = $fail;
1147//    <Mults e.vars> :: e.mults,
1148//      <Min-Length e.vars> :: s.min-len,
1149//      /*
1150//       * For each variable form new inequality recompute its maximum:
1151//       *  new_max = (s.len - s.min-len + s.mult * min) / s.mult
1152//       */
1153//      () e.vars $iter {
1154//        e.tmp-vars : (s.tag s.m (e.n) e.var-id) e.rest,
1155//          e.mults : e (s.tag s.m (e.n) e.var-id) s.mult e,
1156//          <Div <"+" <"-" s.len s.min-len> <"*" s.mult s.m>> s.mult>
1157//            :: s.max,
1158//          {
1159//            e.n : /*empty*/ = s.max;
1160//            <"<" (e.n) (s.max)> = e.n;
1161//            s.max;
1162//          } :: e.max,
1163//          (e.new-vars (s.tag s.m (e.max) e.var-id)) e.rest;
1164//      } :: (e.new-vars) e.tmp-vars,
1165//      e.tmp-vars : /*empty*/ =
1166//      <Max-Length e.new-vars> : s.max-len, {
1167//        /*
1168//         * Check that maximums weren't decreased too much.
1169//         */
1170//        <">" (s.min) (s.max-len)> = $fail;
1171//        /*
1172//         * If max-len == <<minimal valid value>> then change all
1173//         * e*[min,max] to e*[max,max]. If max == 0 then change variable
1174//         * to empty expression.
1175//         */
1176//        s.min : s.max-len =
1177//          e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter {
1178//            e.vars : t.var e.rest,
1179//              e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest, {
1180//                s.n : 0 =
1181////                  <Exchange (t.var) () e.clashes1 ()>
1182////                    :: e.clashes1 t,
1183////                  <Exchange (t.var) () e.clashes2 (e.Snt)>
1184////                    :: e.clashes2 (e.Snt),
1185//                  e.rest (e.new-rest)
1186//                  (e.clashes1 Unwatched (t.var) (LEFT))
1187//                  (e.clashes2) (e.Snt);
1188//                <Exchange (t.var) ((s.tag s.n (s.n) e.var-id))
1189//                  e.clashes1 ()> :: e.clashes1 t,
1190//                  <Exchange (t.var) ((s.tag s.n (s.n) e.var-id))
1191//                    e.clashes2 (e.Snt)> :: e.clashes2 (e.Snt),
1192//                  e.rest (e.new-rest) (e.clashes1)
1193//                    (e.clashes2) (e.Snt);
1194//              };
1195//          } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt),
1196//          e.vars : /*empty*/ =
1197//          (e.clashes1) (e.clashes2) e.Snt;
1198//        /*
1199//         * If no maximums were changed then see whether we should add
1200//         * new inequality to storage and if so then mark clashes
1201//         * containing e.vars in the begining or reversed e.vars in the
1202//         * end as "Unwatched Hard".
1203//         */
1204//        e.vars : e.new-vars, {
1205//          <">" (<Get-Max e.vars>) (s.len)>,
1206//            () <? &Less-Ineqs> $iter e.tmp-ineqs : {
1207//              e1 (e.vars e.ineq s.in-len) e2,
1208//                <Max-Length e.ineq> : s.ineq-max,
1209//                <"<=" (<"+" s.len s.ineq-max>) (s.in-len)>,
1210//                (e.ineqs e1) e2;
1211//              e1 = (e.ineqs e1);
1212//            } :: (e.ineqs) e.tmp-ineqs,
1213//            e.tmp-ineqs : /*empty*/ =
1214//            {
1215//              e.ineqs : e1 (e.vars e.ineq) e2 =
1216//                e1 (e.vars s.len) (e.vars e.ineq) e2;
1217//              e.ineqs (e.vars s.len);
1218//            } :: e.ineqs,
1219//            <Store &Less-Ineqs e.ineqs>,
1220//            (<Mark-Unw-Hard (e.vars) e.clashes1>)
1221//            (<Mark-Unw-Hard (e.vars) e.clashes2>)
1222//            e.Snt;
1223//          (e.clashes1) (e.clashes2) e.Snt;
1224//        };
1225//        /*
1226//         * Else, if some maximums were changed, then change them in all
1227//         * clashes and in Snt. For each variable maximum can't be less
1228//         * then minimum because it would mean that s.len < s.min.
1229//         * If max == 0 then change variable to empty expression.
1230//         */
1231//        e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter {
1232//          e.vars : t.var e.rest,
1233//            e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest, {
1234//              t.var : (s.tag s.m (s.n) e.var-id) =
1235//                e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt);
1236//              s.n : 0 =
1237////                <Exchange (t.var) () e.clashes1 ()>
1238////                  :: e.clashes1 t,
1239////                <Exchange (t.var) () e.clashes2 (e.Snt)>
1240////                  :: e.clashes2 (e.Snt),
1241//                e.rest (e.new-rest)
1242//                (e.clashes1 Unwatched (t.var) (LEFT)) (e.clashes2)
1243//                (e.Snt);
1244//              <Exchange (t.var) ((s.tag s.m (s.n) e.var-id))
1245//                e.clashes1 ()> :: e.clashes1 t,
1246//                <Exchange (t.var) ((s.tag s.m (s.n) e.var-id))
1247//                  e.clashes2 (e.Snt)> :: e.clashes2 (e.Snt),
1248//                e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt);
1249//            };
1250//        } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt),
1251//        e.vars : /*empty*/ =
1252//        (e.clashes1) (e.clashes2) e.Snt;
1253//      };
1254//  };
1255//
1256//Add-Greater-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt, {
1257//  <Get-Max e.vars> : s.max, {
1258//    <"<" (s.max) (s.len)> = $fail;
1259//    <Mults e.vars> :: e.mults,
1260//      <Max-Length e.vars> : s.max-len,
1261//      /*
1262//       * For each variable from new inequality recompute its minimum:
1263//       *  new_min = ceil ((s.len - s.max-len + s.mult * max) / s.mult)
1264//       */
1265//      () e.vars $iter {
1266//        e.tmp-vars : (s.tag s.m (s.n) e.var-id) e.rest,
1267//          e.mults : e (s.tag s.m (s.n) e.var-id) s.mult e,
1268//          <Ceil <"+" <"-" s.len s.max-len> <"*" s.mult s.n>> s.mult>
1269//            :: s.min,
1270//          {
1271//            <"<" (s.min) (0)> = 0;
1272//            <">" (s.m) (s.min)> = s.m;
1273//            s.min;
1274//          } :: s.min,
1275//          (e.new-vars (s.tag s.min (s.n) e.var-id)) e.rest;
1276//      } :: (e.new-vars) e.tmp-vars,
1277//      e.tmp-vars : /*empty*/ =
1278//      <Min-Length e.new-vars> :: s.min-len, {
1279//        /*
1280//         * Check that minimums weren't increased too much.
1281//         */
1282//        <"<" (s.max) (s.min-len)> = $fail;
1283//        /*
1284//         * If min-len == <<maximum valid value>> then change all
1285//         * e*[min,max] to e*[min,min].
1286//         */
1287//        s.max : s.min-len =
1288//          e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter {
1289//            e.vars : t.var e.rest,
1290//              e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest,
1291//              <Exchange (t.var) ((s.tag s.m (s.m) e.var-id))
1292//                e.clashes1 ()> :: e.clashes1 t,
1293//              <Exchange (t.var) ((s.tag s.m (s.m) e.var-id))
1294//                e.clashes2 (e.Snt)> :: e.clashes2 (e.Snt),
1295//              e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt);
1296//          } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt),
1297//          e.vars : /*empty*/ =
1298//          (e.clashes1) (e.clashes2) e.Snt;
1299//        /*
1300//         * If no minimums were changed then see whether we should add
1301//         * new inequality to storage and if so then mark clashes
1302//         * containing e.vars in the begining or reversed e.vars in the
1303//         * end as "Unwatched Hard".
1304//         */
1305//        e.vars : e.new-vars, {
1306//          <"<" (<Get-Min e.vars>) (s.len)>,
1307//            () <? &Greater-Ineqs> $iter e.tmp-ineqs : {
1308//              e1 (e.vars e.ineq s.in-len) e2,
1309//                <">=" (<"+" s.len <Min-Length e.ineq>>) (s.in-len)>,
1310//                (e.ineqs e1) e2;
1311//              e1 = (e.ineqs e1);
1312//            } :: (e.ineqs) e.tmp-ineqs,
1313//            e.tmp-ineqs : /*empty*/ =
1314//            {
1315//              e.ineqs : e1 (e.vars e.ineq) e2 =
1316//                e1 (e.vars s.len) (e.vars e.ineq) e2;
1317//              e.ineqs (e.vars s.len);
1318//            } :: e.ineqs,
1319//            <Store &Greater-Ineqs e.ineqs>,
1320//            (<Mark-Unw-Hard (e.vars) e.clashes1>)
1321//            (<Mark-Unw-Hard (e.vars) e.clashes2>)
1322//            e.Snt;
1323//          (e.clashes1) (e.clashes2) e.Snt;
1324//        };
1325//        /*
1326//         * Else, if some minimums were changed, then change them in all
1327//         * clashes and in Snt. For each variable minimum can't be greater
1328//         * then maximum because it would mean that s.len > s.max.
1329//         */
1330//        e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter {
1331//          e.vars : t.var e.rest,
1332//            e.new-vars : t.new-var e.new-rest, {
1333//              t.var : t.new-var =
1334//                e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt);
1335//              <Exchange (t.var) (t.new-var) e.clashes1 ()>
1336//                :: e.clashes1 t,
1337//                <Exchange (t.var) (t.new-var) e.clashes2 (e.Snt)>
1338//                  :: e.clashes2 (e.Snt),
1339//                e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt);
1340//            };
1341//        } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt),
1342//        e.vars : /*empty*/ =
1343//        (e.clashes1) (e.clashes2) e.Snt;
1344//      };
1345//  };
1346//  e.vars : (s.tag s.n () e.var-id), {
1347//    <">" (s.len) (s.n)> =
1348//      <Exchange ((s.tag s.n () e.var-id)) ((s.tag s.len () e.var-id))
1349//        e.clashes1 ()> :: e.clashes1 t,
1350//      <Exchange ((s.tag s.n () e.var-id)) ((s.tag s.len () e.var-id))
1351//        e.clashes2 (e.Snt)> :: e.clashes2 (e.Snt),
1352//      (e.clashes1) (e.clashes2) e.Snt;
1353//    (e.clashes1) (e.clashes2) e.Snt;
1354//  };
1355//  (e.clashes1) (e.clashes2) e.Snt;  // STUB!!! Add inequality to the storage?
1356//};
1357//
1358//Get-Min e.vars, {
1359//  <? &Greater-Ineqs> : $r e (e.ineq s.len) e,
1360//    e.vars : e.ineq e.other,
1361//    <"+" s.len <Min-Length e.other>>;
1362//  <Min-Length e.vars>;
1363//};
1364//
1365//Get-Max e.vars, {
1366//  <? &Less-Ineqs> : $r e (e.ineq s.len) e,
1367//    e.vars : e.ineq e.other,
1368//    <Max-Length e.other> : s.other-len,
1369//    <"+" s.len s.other-len>;
1370//  <Max-Length e.vars>;
1371//};
1372//
1373///*
1374// * Computes variables multiplicitys and returns them in the form:
1375// *  e.mults ::= t.var s.mult e.mults | []
1376// */
1377//Mults e.vars =
1378//  () e.vars $iter {
1379//    e.vars : t.var e.rest,
1380//      1 e.rest $iter {
1381//        e.rest : e1 t.var e2,
1382//          <"+" s.mult 1> e1 e2;
1383//      } :: s.mult e.rest,
1384//      # \{ e.rest : e t.var e; } =
1385//      (e.mults t.var s.mult) e.rest;
1386//  } :: (e.mults) e.vars,
1387//  e.vars : /*empty*/ =
1388//  e.mults;
1389//
1390//Mark-Unw-Hard (e.vars) e.clashes =
1391//  <Reverse e.vars> :: e.rev-vars,
1392//  () e.clashes $iter e.clashes : {
1393//    (e.Re) (e.Pe) e.rest,
1394//      <Cyclic e.Re> :: e.cyc-Re,
1395//      <Cyclic e.Pe> :: e.cyc-Pe,
1396//      {
1397//        \{
1398//          e.cyc-Re : e.vars e;
1399//          e.cyc-Re : e e.rev-vars;
1400//          e.cyc-Pe : e.vars e;
1401//          e.cyc-Pe : e e.rev-vars;
1402//        },
1403//          (e.new-clashes Unwatched Hard (e.Re) (e.Pe)) e.rest;
1404//        (e.new-clashes (e.Re) (e.Pe)) e.rest;
1405//      };
1406//    e.tag (e.Re) (e.Pe) e.rest =
1407//      (e.new-clashes e.tag (e.Re) (e.Pe)) e.rest;
1408//  } :: (e.new-clashes) e.clashes,
1409//  e.clashes : /*empty*/ =
1410//  e.new-clashes;
1411//
1412//Ceil s1 s2, {
1413//  <Rem s1 s2> : 0 = <Div s1 s2>;
1414//  <"+" <Div s1 s2> 1>;
1415//};
1416//
1417//Match-Exp (e.Re) e.Pe =
1418//  <Granulate e.Re> :: e.Re,
1419//  <Granulate e.Pe> :: e.Pe,
1420//  <Length e.Pe> :: s.len,
1421//  e.Re : e1 e2,
1422//  <Match (<Left 0 s.len e2>) (e.Pe)>,
1423//  e2 : $r e3 e4,
1424//  <Match (<Right 0 s.len e3>) (e.Pe)>,
1425//  <Length e1> <Length e4>;
1426//
1427//Match e.clash =
1428//  e.clash $iter e.clashes : \{
1429//    e1 (e.expr) (e.expr) e2 = e1 e2;
1430//    e1 (t.Rt e.Re) (t.Pt e.Pe) e2,
1431//      # \{ t.Rt : (EVAR e); t.Pt : (EVAR e); } =
1432//      <Match-Term t.Rt t.Pt e1 (e.Re) (e.Pe) e2>;
1433//    e1 (e.Re t.Rt) (e.Pe t.Pt) e2,
1434//      # \{ t.Rt : (EVAR e); t.Pt : (EVAR e); } =
1435//      <Match-Term t.Rt t.Pt e1 (e.Re) (e.Pe) e2>;
1436//    e1 (e.Re) (e.Pe) e2, \{
1437//      e.Re : (EVAR e) e (EVAR e) = <Match-Cyclic (e.Re) (e.Pe) e1 e2>;
1438//      e.Pe : (EVAR e) e (EVAR e) = <Match-Cyclic (e.Pe) (e.Re) e1 e2>;
1439//      \{
1440//        e.Re : (EVAR e) e, e.Pe : e (EVAR e);
1441//        e.Re : (EVAR e) e, e.Pe : e (EVAR e);
1442//      } =
1443//        <Intersect <Min-Length e.Re> (<Max-Length e.Re>)
1444//          <Min-Length e.Pe> (<Max-Length e.Pe>)>; // This is STUB!!!
1445//    };
1446//  } :: e.clashes,
1447//  <WriteLN Match e.clashes>,
1448//  e.clashes : /*empty*/;
1449//
1450//Match-Term {
1451//  term term e.clashes = e.clashes;
1452//  t.Rt t.Pt e.clashes, t.Rt : {
1453//    s.ObjectSymbol =
1454//      t.Pt : (s.tag e),
1455//      SVAR TVAR : e s.tag e,  // check that s.tag isn't PAREN
1456//      <Subst (t.Pt) ((t.Rt)) e.clashes>;
1457//    (SVAR e), t.Pt : {
1458//      s.ObjectSymbol = <Subst (t.Rt) ((t.Pt)) e.clashes>;
1459//      (s.tag e) =
1460//        SVAR TVAR : e s.tag e,  // check that s.tag isn't PAREN
1461//        <Subst (t.Pt) ((t.Rt)) e.clashes>;
1462//    };
1463//    (TVAR e) =
1464//      <Subst (t.Rt) ((t.Pt)) e.clashes>;
1465//    (PAREN e.Re) = t.Pt : \{
1466//      (TVAR e) = <Subst (t.Pt) ((t.Rt)) e.clashes>;
1467//      (PAREN e.Pe) = (e.Re) (e.Pe) e.clashes;
1468//    };
1469//  };
1470//};
1471//
1472//Match-Cyclic (e.Re) (e.Pe) e.clashes = ;  // This is STUB!!!
1473//
1474//Granulate e.expr =
1475//  (e.expr) <Vars e.expr> $iter {
1476//    e.vars : t.var e.rest,
1477//      t.var : {
1478//        (s.tag 1 (1) e.var-id), {
1479//          SVAR TVAR : e s.tag e = e.expr;
1480//          <Subst (t.var) (((TVAR 1 (1)) e.var-id)) e.expr>;
1481//        };
1482//        (s.tag s.n (s.n) e.NEW (e.QualifiedName)) =
1483//          s.n /*empty*/ $iter
1484//            <"-" s.n 1>
1485//            (TVAR 1 (1) NEW ("gran" e.QualifiedName s.n)) e.new-vars
1486//          :: s.n e.new-vars,
1487//          s.n : 0 =
1488//          <Subst (t.var) ((e.new-vars)) e.expr>;
1489//        (s.tag e.something), {  // cyclic variable
1490//          s.tag : EVAR = e.expr;
1491//          <Subst (t.var) (((EVAR e.something))) e.expr>;
1492//        };
1493//      } :: e.expr,
1494//      (e.expr) e.rest;
1495//  } :: (e.expr) e.vars,
1496//  e.vars : /*empty*/ =
1497//  e.expr;
1498//
1499//Left-Exp s.left s.len e.expr, \{
1500//  <"<" (<Min-Length e.expr>) (<"+" s.left s.len>)>
1501//    = $fail;
1502//  s.len : 0 = ();
1503//  s.left : 0 =
1504//    0 () e.expr $iter \{
1505//      e.expr : t1 e2, t1 : {
1506//        s.ObjectSymbol = <"+" s.num 1>;
1507////        (REF t.name) = ???
1508//        (PAREN e) = <"+" s.num 1> ;
1509//        (s.var-tag s.n (s.n) e.var-id) = <"+" s.num s.n>;
1510//        (s.var-tag s.m (e.n) e.var-id) =
1511//          <"+" s.num s.m> :: s.num,
1512//          <"<=" (s.len) (s.num)>,
1513//          s.num;
1514//      } :: s.num,
1515//        s.num (e.left t1) e2;
1516//    } :: s.num (e.left) e.expr,
1517//    <"<=" (s.len) (s.num)> =
1518//    <"-" s.num s.len> :: s.r-min,
1519//    e.left : e.first t.var,
1520//    t.var : {
1521//      s.ObjectSymbol = (e.left);
1522//      (PAREN e) = (e.left);
1523//      (s.tag s.m (e.n) e.NEW (e.QualifiedName)) =
1524//        <"-" s.m s.r-min> :: s.l-len,
1525//        e.n : {
1526//          /*empty*/ = /*empty*/;
1527//          s.x = <"-" <"+" s.x <Min-Length e.first>> s.l-len>;
1528//        } : {
1529//          0 = (e.left);
1530//          e.r-max,
1531//            (s.tag s.l-len (s.l-len) NEW ("l-split" e.QualifiedName))
1532//              :: t.l-var,
1533//            (s.tag s.r-min (e.r-max) NEW ("r-split" e.QualifiedName))
1534//              :: t.r-var,
1535//            <Subst (t.var) ((t.l-var t.r-var)) e.first> :: e.expr,
1536//            (e.expr t.l-var) t.var t.l-var t.r-var;
1537//        };
1538//    };
1539//  <Left-Exp 0 s.left e.expr> :: (e.left) e.change,
1540//    {
1541//      e.change : t.old-var t.new-1 t.new-2 =
1542//        <Subst (t.old-var) ((t.new-1 t.new-2)) e.expr>;
1543//      e.expr;
1544//    } : e.left e.right,
1545//    <Left-Exp 0 s.len e.right> e.change;
1546//};
1547//
1548//Right-Exp s.right s.len e.expr, \{
1549//  <"<" (<Min-Length e.expr>) (<"+" s.right s.len>)>
1550//    = $fail;
1551//  s.len : 0 = ();
1552//  s.right : 0 =
1553//    0 () e.expr $iter \{
1554//      e.expr : e2 t1, t1 : {
1555//        s.ObjectSymbol = <"+" s.num 1>;
1556////        (REF t.name) = ???
1557//        (PAREN e) = <"+" s.num 1> ;
1558//        (s.var-tag s.n (s.n) e.var-id) = <"+" s.num s.n>;
1559//        (s.var-tag s.m (e.n) e.var-id) =
1560//          <"+" s.num s.m> :: s.num,
1561//          <"<=" (s.len) (s.num)>,
1562//          s.num;
1563//      } :: s.num,
1564//        s.num (t1 e.right) e2;
1565//    } :: s.num (e.right) e.expr,
1566//    <"<=" (s.len) (s.num)> =
1567//    <"-" s.num s.len> :: s.l-min,
1568//    e.right : t.var e.last,
1569//    t.var : {
1570//      s.ObjectSymbol = (e.right);
1571//      (PAREN e) = (e.right);
1572//      (s.tag s.m (e.n) e.NEW (e.QualifiedName)) =
1573//        <"-" s.m s.l-min> :: s.r-len,
1574//        e.n : {
1575//          /*empty*/ = /*empty*/;
1576//          s.x = <"-" <"+" s.x <Min-Length e.last>> s.r-len>;
1577//        } : {
1578//          0 = (e.right);
1579//          e.l-max,
1580//            (s.tag s.r-len (s.r-len) NEW ("r-split" e.QualifiedName))
1581//              :: t.r-var,
1582//            (s.tag s.l-min (e.l-max) NEW ("l-split" e.QualifiedName))
1583//              :: t.l-var,
1584//            <Subst (t.var) ((t.l-var t.r-var)) e.last> :: e.expr,
1585//            (e.expr t.r-var) t.var t.l-var t.r-var;
1586//        };
1587//    };
1588//  <Right-Exp 0 s.right e.expr> :: (e.right) e.change,
1589//    {
1590//      e.change : t.old-var t.new-1 t.new-2 =
1591//        <Subst (t.old-var) ((t.new-1 t.new-2)) e.expr>;
1592//      e.expr;
1593//    } : e.left e.right,
1594//    <Right-Exp 0 s.len e.left> e.change;
1595//};
1596//
1597////  Right-Exp s.right s.len e.expr =
1598////    <Min-Length e.expr> :: s.expr-len,
1599////    <"+" s.right s.len> :: s.sum,
1600////    \{
1601////      <"<" (s.expr-len) (s.sum)> = $fail;
1602////      <Left-Exp <"-" s.expr-len s.sum> s.len e.expr>;
1603////    };
1604// 
1605//Middle-Exp s.left s.right e.expr, \{
1606//  <"<" (<Min-Length e.expr>) (<"+" s.left s.right>)>
1607//    = $fail;
1608//  <Left-Exp 0 s.left e.expr> :: (e.left) e.l-change,
1609//    <Right-Exp 0 s.right e.expr> :: (e.right) e.r-change,
1610//    e.expr : e.left e.sought e.right,
1611//    (e.sought) e.l-change e.r-change;
1612//};
1613
Note: See TracBrowser for help on using the repository browser.