// $Source$ // $Revision$ // $Date$ $use "rfpc"; $use "rfp_compile"; $use "rfp_format"; $use "rfp_helper"; $use "rfp_vars"; $use "rfp_debug"; $use Arithm Box Class List StdIO Table; // transform only e.targets and leave all the rest as it is $func Transform (e.targets) e.Items = e.Items; // transform { A; } : Pe into { A; } :: aux, aux : Pe $func Unstick-Blocks e.Sentence = e.Sentence (e.Fe); // remove blocks from Re $func Flatten-Result s.tail? (e.Re) e.items = e.assigns (e.Re); $func Generate-In-Vars (e.in) e.branch = (e.in) e.branch; // rename variables local for the {}-blocks //$func Rename-Vars s.num (e.upper-vars) (e.res-vars) e.Snt = e.new-Snt; $func Rename-Vars e = e; // is variable with e.QualifiedName in the e.vars list? //$func? Old-Var? e.vars (s t (e.QualifiedName)) = ; $func? Old-Var? e = e; //$func Rename s.num (s.tag t.p (e.QualifiedName)) = // (s.tag t.p ("ren" e.QualifiedName s.num)); $func Rename e = e; // build substitution for all occurrences of each e.var in e.Snt $func Build-Subst (e.vars) (e.substs) e.Snt = (e.patterns) (e.replacements); // build substitution for all occurrences of variable with the name t.n in e.Snt $func Var-Subst s.var-tag t.n t.s e.Snt = (e.patterns) (e.replacements); $box Free-Idx; RFP-As2As-Transform e.Items = { ;; } :: e.targets, ; Transform (e.targets) e.Items, { e.Items : t.item e.rest, { { e.targets : v = e.targets : e t.name e, t.item : (t t t t.name e);; }, t.item : (s.link s.tag t.pragma t.name (e.in) (e.out) (BRANCH t.p e.branch)) = { : e.in = ; (e.in) e.branch; } :: (e.in) e.branch, { = ; e.branch; } :: e.branch, , :: e.branch t, ) () e.branch> :: e.branch, (s.link s.tag t.pragma t.name (e.in) (e.out) (BRANCH t.p e.branch)); t.item; } :: t.item = t.item ;; }; /* * Next function gets use of the following proposition: * one can add (RESULT) term to the end of any sentence that isn't end in * (RESULT e.anything) and it won't change the result of program execution. * No, no, the proposition is WRONG!!! Such doings change the semantics of "=". * * The function returns the sentence with all { A; } : Pe constructions * turned into { A; } :: aux, aux : Pe ones and format of the last Re of * the sentence. */ Unstick-Blocks e.Sentence, e.Sentence : eL e.Snt, e.Snt : \{ (s.block t.Pragma e.branches) eR, s.block : \{ BLOCK; BLOCK?; } = e.branches () () $iter { e.branches : (BRANCH t.p e.branch) e.rest, :: e.new-branch (e.Fe), e.rest (e.br (BRANCH t.p e.new-branch)) (e.Fes (e.Fe)); } :: e.branches (e.br) (e.Fes), e.branches : /*empty*/ = { eR : \{ (BLOCK t (BRANCH t (LEFT e) e) e) e; (BLOCK t (BRANCH t (RIGHT e) e) e) e; (BLOCK? t (BRANCH t (LEFT e) e) e) e; (BLOCK? t (BRANCH t (RIGHT e) e) e) e; (LEFT e) e; (RIGHT e) e; } = : s.N, ) "aux" "alt"> :: e.aux s.N, , eL (s.block t.Pragma e.br) (FORMAT (PRAGMA) e.aux) (RESULT (PRAGMA) e.aux) ; eR : /*empty*/ = eL (s.block t.Pragma e.br) (); eL (s.block t.Pragma e.br) ; }; (RESULT t.Pragma (s.block e.branches)) eR, s.block : \{ BLOCK; BLOCK?; } = // FIXME: Comment this and search for BUGs! eL ; (RESULT t.Pragma e.Re) eR = :: e.assigns (e.Re), { e.Re : e1 (FAIL e2) = (RESULT t.Pragma e1) e2; (RESULT t.Pragma e.Re); } :: e.Result, { eR : v = eL e.assigns e.Result ; :: e.Fe, :: e.Fe, // hack for avoiding non-hard formats eL e.assigns e.Result (e.Fe); }; (NOT (BRANCH t.p1 e.body)) eR = :: e.body t.empty, eL (NOT (BRANCH t.p1 e.body)) ; (ITER (BRANCH t.p1 e.body) t.IterVars (BRANCH t.p2 e.condition)) = :: e.body t, :: e.condition (e.Format), eL (ITER (BRANCH t.p1 e.body) t.IterVars (BRANCH t.p2 e.condition)) (e.Format); (TRY (BRANCH t.p1 e.TrySnt) e.NOFAIL t.CatchBlock) = :: e.TrySnt t.Try-Fe, :: e.CatchBlock t.Catch-Fe, eL (TRY (BRANCH t.p1 e.TrySnt) e.NOFAIL e.CatchBlock) (); (FAIL e) = e.Sentence ((FAIL)); (ERROR t.Pragma) eR = :: eR t, eL (ERROR t.Pragma) eR ((FAIL)); }; Flatten-Result s.tail? (e.Re) e.items, e.items : { t1 e.rest, t1 : \{ (BLOCK e); (BLOCK? e); } = :: e1 (e.Format), { e.Format : (FAIL) = (e.Re (FAIL e1)); : s.N, :: e.aux s.N, , e1 (FORMAT (PRAGMA) e.aux) ; }; (CALL t.p t.name e.r) e.rest = :: e.assigns (e.r), (CALL t.p t.name e.r) :: t1, { e.rest : /*empty*/, s.tail? : Tail = e.assigns (e.Re t1); : s.N, ) "aux" "call"> :: e.aux1 s.N, , e.assigns (RESULT (PRAGMA) t1) (FORMAT (PRAGMA) e.aux1) ; }; (PAREN e.r) e.rest = :: e.assigns (e.r), e.assigns ; t1 e.rest = ; /*empty*/ = (e.Re); }; /* * Generate variable names for input function parameters. Change e.Sentence so * that it doesn't begin with pattern. */ Generate-In-Vars (e.in) e.Sentence, { /* * If input PAlt of a function is a sentence (not a block), format of * input pattern coincides t.InputFormat, and all variables in input * pattern have different indexes then we can drop the pattern and define * function as * func (Fname (pattern_vars) (res_..., res_..., ...)) * where pattern_vars means variables used in the pattern. */ e.Sentence : \{ (LEFT t e.Pe) e.Snt = (e.Pe) e.Snt; (RIGHT t e.Pe) e.Snt = (e.Pe) e.Snt; } :: (e.Pe) e.Snt = { : e.in, // FIXME: here should be checked format equality :: e.args, # \{ e.args : e (e t1) e (e t1) e; } = (e.Pe) e.Snt; :: e.in-expr s = (e.in-expr) (RESULT (PRAGMA) e.in-expr) e.Sentence; }; /* * Else if we have real PAlt then we can do that transformation with each * branch. Input parameters for the function will be arg_1...arg_N. If * first pattern in the branch satisfies the conditions then drop it out * and rename variables in the branch to arg_1...arg_N instead of pattern * variables. */ e.Sentence : (s.block t.Pragma e.branches) e.Snt = :: e.in-expr s, :: e.in-vars, (/*e.br*/) e.branches $iter { e.branches : (BRANCH t.p (s.dir t.pp e.Pe) e.br-snt) e.rest, { : e.in, // FIXME: here should be checked format equality :: e.vars, # \{ e.vars : e (e t1) e (e t1) e; } = :: (e.pats) (e.repls), (e.br (BRANCH t.p )) e.rest; (e.br (BRANCH t.p (s.dir t.pp e.Pe) e.br-snt)) e.rest; }; } :: (e.br) e.branches, e.branches : /*empty*/ = (e.in-expr) (s.block t.Pragma e.br) e.Snt; /* * Else sentence already hasn't begun with pattern, so left it as it is. * It can be only if e.in and e.out are both empty. */ //! (e.in) e.Sentence; } :: (e.in) e.Sentence = (e.in) e.Sentence; /* * Each {}-block is seen as inlined function. e.upper-vars and e.res-vars are * correspondingly input and output parameters for that function. e.Snt is its * body. * Rename all variables local for inlined function, for those to be * distinguishable from the outer world when the function is inlined in * imperative language. */ Rename-Vars s.num (e.upper-vars) (e.res-vars) e.Snt = (e.upper-vars) (/*e.new-Snt*/) e.Snt $iter { e.Snt : t.Statement e.rest, { /* * If we meet a pattern then add each unknown variable from it to * the list and rename local variables which intersect with out * parameters of the block. */ t.Statement : \{ (LEFT t e.Pe) = e.Pe; (RIGHT t e.Pe) = e.Pe; } :: e.Pe = )> :: (e.old-vars) (e.new-vars), :: e.renames, :: (e.pats) (e.repls), : (s.tag t.p e.Pe1) e.rest-Snt, (>) (e.new-Snt (s.tag t.p e.Pe1)) e.rest-Snt; /* * If we meet format expression then for each already used * variable in it select new name by adding prefix "ren". */ t.Statement : (FORMAT t e.He) = )> :: (e.old-vars) (e.new-vars), :: e.renames, :: (e.pats) (e.repls), : (FORMAT t.p e.He1) e.rest-Snt, (>) (e.new-Snt (FORMAT t.p e.He1)) e.rest-Snt; /* * We shouldn't rename variable if its duplicate is appeared on * a parallel branch of the block. So process all branches * iteratively with the same list of variables (known before * block). */ t.Statement : (s.block t.Pragma e.branches), s.block : \{ BLOCK; BLOCK?; } = /* * As well as after-block patterns, formats should be scaned * for res-vars. See samples/Syntax/block1.rf for example. */ e.rest : { (LEFT t e.Pe) e = ; (RIGHT t e.Pe) e = ; (FORMAT t e.He) e = ; /*empty*/ = e.res-vars; e = /*empty*/; } :: e.bl-res-vars, /* * Left as res-vars only variables which were unknown before * block. Those are local if meet in pattern and need * renaming. */ (/*e.brv*/) e.bl-res-vars $iter { e.bl-res-vars : e1 (e t.name) e2, e.vars : e (e t.name) e = (e.brv e1) e2; (e.brv e.bl-res-vars); } :: (e.brv) e.bl-res-vars, e.bl-res-vars : /*empty*/ = (e.vars) (e.brv) (e.branches)> :: e.branches, (e.vars) (e.new-Snt (s.block t.Pragma e.branches)) e.rest; t.Statement : (BRANCH t.Pragma e.Sentence) = () (e.new-Snt (BRANCH t.Pragma )); t.Statement : (ITER t.IterBody t.IterVars t.IterCondition) = : t t.NewBody, :: e.IterCondition, () (e.new-Snt (ITER t.NewBody e.IterCondition)); t.Statement : (TRY t.TryBranch e.NOFAIL t.Catch) = :: e.TryBranch, :: e.Catch, () (e.new-Snt (TRY e.TryBranch e.NOFAIL e.Catch)); /* * Else proceed with the rest. */ (e.vars) (e.new-Snt t.Statement) e.rest; }; } :: (e.vars) (e.new-Snt) e.Snt, e.Snt : /*empty*/ = e.new-Snt; //Old-Var? e.vars (s.tag t (e.QualifiedName)) = e.vars : e (s.tag t (e.QualifiedName)) e; Old-Var? e.vars (e t.name) = e.vars : e (e t.name) e; Rename s.num (s.tag t.p (e.QualifiedName)) = (s.tag t.p (e.QualifiedName "_" s.num)); /* * Build substitution for all occurrences of each e.var in e.Snt. */ Build-Subst { ((s.tag t t.name) e.vars) ((s t t.s) e.substs) e.Snt = :: (e.var-pats) (e.var-repls), :: (e.pats) (e.repls), (e.var-pats e.pats) (e.var-repls e.repls); () () e = () (); }; /* * Build substitution for all occurrences of variable with the name t.n in e.Snt. */ Var-Subst s.tag t.n t.s e.Snt, { e.Snt : t.Statement e.rest, { t.Statement : (s.tag t.p t.name) = { t.name : t.n = ((s.tag t.p t.name)) (((s.tag t.p t.s))); () (); }; t.Statement : (expr) = ; () (); } :: (e.st-pats) (e.st-repls), :: (e.pats) (e.repls), (e.st-pats e.pats) (e.st-repls e.repls); () (); }; /////////////////////////// Variables Using Analysis ///////////////////////// // //$func Post-Comp (e.used-vars) e.comp-func = (e.used-vars) e.result-func; // //Post-Comp (e.used-vars) e.comp-func, e.comp-func : { // /* // * As well as "Used" shouldn't be "Declare" statements added? // */ // e.something (Used e.vars) = // ) e.something>; // e.something (If-used (e.vars) e.statements), { // : (v.true-used) (e.yet-not-used) = // :: (e.expr-vars) e.expr, // ) e.something> e.expr; // ; // }; // e.something (e.expr) = // :: (e.expr-vars) e.expr, // (e.expr); // e.something s.symbol = // s.symbol; // /*empty*/ = (e.used-vars); //}; /////////////////////////// Static Clash Analysis /////////////////////////// // //$func? Split-Clashes (e.clashes) e.Snt = // (e.greater) (e.less) (e.hards) (e.clashes) e.Snt; // //$func? Improve-Clash (e.Re) (s.dir e.Pe) (e1) (e2) e.Snt = e.clashes (e.Snt); // //$func? Self-Occur (e.Re) e.Pe = e; // //$func Cyclic e.expr = e.cyclic-vars; // //$func Hard e.expr = e.hard-part; // //$func Exchange (e.var-holder) (e.new-expr) e.clashes (e.Snt) = // e.clashes (e.Snt); // //$func Exchange-Exp (e.change) (e1) (e2) e.Snt = (e1) (e2) e.Snt; // //$func Minimize (e.expr) (e.clashes) e.Snt = (e.clashes) (e.less) e.Snt; // //$func? Intersect s.k (e.l) s.m (e.n) = s.x (e.y); // //$func Min-Length e.expr = s.min-length; // //$func Max-Length e.expr = e.max-length; // //$func? Add-Less-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt = // (e.clashes1) (e.clashes2) e.Snt; // //$func? Add-Greater-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt = // (e.clashes1) (e.clashes2) e.Snt; // //$func Get-Min e.vars = s.min; // //$func Get-Max e.vars = e.max; // //$func Mults e.vars = e.mults; // //$func Mark-Unw-Hard (e.vars) e.clashes = e.clashes; // //$func Ceil s1 s2 = s; // //$func? Match-Exp (e.Re) e.Pe = s.left s.right; // //$func? Match e.clash = ; // //$func? Match-Term t.Rt t.Pt e.clashes = e.clashes; // //$func? Match-Cyclic (e.Re) (e.Pe) e.clashes = e.clashes; // //$func Granulate e.expr = e.expr; // //$func? Left-Exp s.left s.len e.expr = (e.expr) e.change; // //$func? Right-Exp s.right s.len e.expr = (e.expr) e.change; // //$func? Middle-Exp s.left s.right e.expr = (e.expr) e.change; // *$func Comp-Pattern t.Pattern e.Snt = e.asail-Snt; * *Comp-Pattern (s.dir e.PatternExp) e.Sentence = * ) (s.dir e.PatternExp) e.Sentence> * : t t.Pattern e.Snt, *// (Unwatched () t.Pattern) e.Snt $iter { * /* * * Uncomment previous line and delete next one to activate Split-Clashes * * function * */ * (() t.Pattern) e.Snt $iter { * e.Snt : (RESULT e.Re) (s.d e.Pe) e = *// , * ) e.Snt> : t t.R t.P e.rest, *// (e.clashes Unwatched (e.Re) t.P) e.rest; * /* * * Uncomment previous line and delete next one to activate * * Split-Clashes function * */ * (e.clashes (e.Re) t.P) e.rest; * } :: (e.clashes) e.Snt, * # \{ * e.Snt : \{ * (RESULT e.Re) (LEFT e) e = e.Re; * (RESULT e.Re) (RIGHT e) e = e.Re; * } :: e.Re, * ; * } = * e.Snt : e.Current-Snt (Comp Sentence) e.Other-Snts = * :: e.asail-Others, * { *// *// :: (e.greater) (e.less) (e.hards) (e.clashes) e.Current-Snt = *// , *// , *// , *// , *//! :: e.asail-Clashes, *// e.asail-Clashes (e.greater) $iter { *// e.greater : (e.vars s.num) e.rest, *// :: e.vars, // temporary step *// (IF ((INFIX ">=" ((LENGTH e.vars)) (s.num))) *// e.asail-Clashes *// ) (e.rest); *// } :: e.asail-Clashes (e.greater), *// e.greater : /*empty*/ = *// e.asail-Clashes (e.less) $iter { *// e.less : (e.vars s.num) e.rest, *// :: e.vars, // temporary step *// (IF ((INFIX "<=" ((LENGTH e.vars)) (s.num))) *// e.asail-Clashes *// ) (e.rest); *// } :: e.asail-Clashes (e.less), *// e.less : /*empty*/ = *// e.asail-Clashes (e.hards) $iter { *// e.hards : (e.Re) (e.Pe) e.rest, *// :: e.Re, // temporary step *// :: e.Pe, // temporary step *// (IF ((INFIX "==" (e.Re) (e.Pe))) e.asail-Clashes) (e.rest); *// } :: e.asail-Clashes (e.hards), *// e.hards : /*empty*/ = *//! e.asail-Clashes e.asail-Others; * e.asail-Others; *// ; * }; // //Split-Clashes (e.clashes) e.Snt = // e.clashes (e.Snt) () () () $iter e.clashes : { // e1 Unwatched (e.Re) (s.dir e.Pe) e2, { \? // \{ // \{ // : { // Occur e.vars = // // :: (e.clashes) (e.new-less) e.Snt, // e.clashes (e.Snt) // (e.greater) (e.less e.new-less) (e.hards); // /*empty*/ \! $fail; // }; // : { // Occur e.vars = // // :: (e.clashes) (e.new-less) e.Snt, // e.clashes (e.Snt) // (e.greater) (e.less e.new-less) (e.hards); // /*empty*/ \! $fail; // }; // }; // : /*empty*/, \{ // e.Re is ground expression // : /*empty*/ \! // e.Pe is ground expression // $fail; // e.Pe : \{ // /* // * If e.Pe is symbol then e.Re should be a symbol and if // * e.Pe is "old" variable then we should remember clash // * "e.Re : e.Pe" as hard. // */ // (SVAR 1 (1) e.name) \! // e.Re : s, // { // = (e.Re) (e.Pe); // /*empty*/; // } :: e.new-hard, // // (e.greater) (e.less) (e.hards e.new-hard); // /* // * If e.Pe is parenthesized expression then e.Re should be // * parenthesized expression too and we can take parentheses // * off. // */ // (PAREN e.pat-expr) \! // e.Re : (PAREN e.re-expr), // e1 Unwatched (e.re-expr) (s.dir e.pat-expr) e2 // (e.Snt) (e.greater) (e.less) (e.hards); // /* // * If e.Pe is any other variable then length of e.Re (which // * can be zero) should belong to its range. If e.Pe is // * "old" variable and e.Re is empty expression then we // * should remember that length of e.Pe is less or equal to // * 0 and if e.Re isn't empty then we should remember clash // * "e.Re : e.Pe" as hard. // */ // (s.var-tag s.m (e.n) e.name) \! // ()> : e, // { // , // { // e.Re : /*empty*/ = (e.Pe 0) (); // /*empty*/ ((e.Re) (e.Pe)); // }; // /*empty*/ (); // } :: e.new-less (e.new-hard), // // (e.greater) (e.less e.new-less) (e.hards e.new-hard); // }; // }; // : /*empty*/, e.Re : \{ // (SVAR 1 (1) e.name) \! // e.Pe : s, // { // = (e.Re) (e.Pe); // /*empty*/; // } :: e.new-hard, // // (e.greater) (e.less) (e.hards e.new-hard); // (PAREN e.re-expr) \! // e.Pe : (PAREN e.pe-expr), // e1 Unwatched (e.re-expr) (s.dir e.pe-expr) e2 // (e.Snt) (e.greater) (e.less) (e.hards); // (s.var-tag s.m (e.n) e.name) \! // ()> : e, // { // , // { // e.Pe : /*empty*/ = (e.Re 0) (); // /*empty*/ ((e.Re) (e.Pe)); // }; // /*empty*/ (); // } :: e.new-less (e.new-hard), // // (e.greater) (e.less e.new-less) (e.hards e.new-hard); // }; // e.Re : \{ // (PAREN e.re-expr), e.Pe : \{ // (PAREN e.pe-expr) = // e1 Unwatched (e.re-expr) (s.dir e.pe-expr) e2 // (e.Snt) (e.greater) (e.less) (e.hards); // (SVAR e) \! // $fail; // (s.tag s.m (e.n) e.var-id) \! // e.var-id : e.NEW (e.QualifiedName), // :: e, // (s.tag 0 () NEW ("paren" e.QualifiedName)) :: t.new-var, // { // = // Watched (e.Pe) (s.dir (PAREN t.new-var)); // /*empty*/; // } :: e.new-clash, // :: e1 t, // e.new-clash e1 Unwatched (e.re-expr) (s.dir t.new-var) // // (e.greater) (e.less) (e.hards); // }; // (SVAR 1 (1) e.name), e.Pe : \{ // s.ObjectSymbol = // { // = (e.Re) (e.Pe); // /*empty*/; // } :: e.new-hard, // // (e.greater) (e.less) (e.hards e.new-hard); // (PAREN e) \! // $fail; // (s.tag s.m (e.n) e.var-id) \! // :: e, // { // , { // = // ((e.Re) (e.Pe)) (); // () (Watched (e.Pe) (s.dir e.Re)); // }; // () (); // } :: (e.new-hard) (e.new-clash), // e.new-clash // (e.greater) (e.less) (e.hards e.new-hard); // }; // (s.tag s.m (e.n) e.var-id), TVAR VVAR EVAR : e s.tag e, \{ // e.Pe : (s.tag1 s.k (e.l) e.var-id1), // TVAR VVAR EVAR : e s.tag1 e \! // :: s.x (e.y), // { // , { // = // (s.tag s.x (e.y) e.var-id) (e.Re) (e.Pe); // (s.tag s.x (e.y) e.var-id) /*empty*/; // }; // (s.tag1 s.x (e.y) e.var-id1) /*empty*/; // } :: t.new-var e.new-hards, // // :: e.clashes (e.Snt), // // (e.greater) (e.less) (e.hards e.new-hards); // }; // }; // e.Pe : \{ // (PAREN e.pe-expr), e.Re : \{ // (s.tag s.m (e.n) e.var-id) \! // e.var-id : e.NEW (e.QualifiedName), // :: e, // (s.tag 0 () NEW ("paren" e.QualifiedName)) :: t.new-var, // { // = // Watched (e.Re) (s.dir (PAREN t.new-var)); // /*empty*/; // } :: e.new-clash, // :: e1 t, // e.new-clash e1 Unwatched (t.new-var) (s.dir e.pe-expr) // // (e.greater) (e.less) (e.hards); // }; // (SVAR 1 (1) e.name), e.Re : \{ // (s.tag s.m (e.n) e.var-id) \! // :: e, // { // , { // = // ((e.Re) (e.Pe)) (); // () (Watched (e.Re) (s.dir e.Pe)); // }; // () (); // } :: (e.new-hard) (e.new-clash), // e.new-clash // (e.greater) (e.less) (e.hards e.new-hard); // }; // }; // e.Re : t.Rt e.Re1, e.Pe : t.Pt e.Pe1, // :: s.rt-min, :: s.pt-min, // # \{ s.rt-min : 0; s.pt-min : 0; } = // { // (); // (); // } :: t e.change1 (t e.change2), // e1 Unwatched (e.Re) (e.Pe) :: e1, // > // :: (e1) (e2) e.Snt, // { // e.change1 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2, // = // Watched // ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2); // /*empty*/; // } :: e.new-clash1, // { // e.change2 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2, // = // Watched // ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2); // /*empty*/; // } :: e.new-clash2, // e1 : e11 (t.Rt1 e.Re2) (t.Pt1 e.Pe2), // e.new-clash1 e.new-clash2 e11 (t.Rt1) (s.dir t.Pt1) // Unwatched (e.Re2) (s.dir e.Pe2) e2 // (e.Snt) (e.greater) (e.less) (e.hards); // e.Re : e.Re1 t.Rt, e.Pe : e.Pe1 t.Pt, // :: s.rt-min, :: s.pt-min, // # \{ s.rt-min : 0; s.pt-min : 0; } = // { // (); // (); // } :: t e.change1 (t e.change2), // e1 Unwatched (e.Re) (e.Pe) :: e1, // > // :: (e1) (e2) e.Snt, // { // e.change1 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2, // = // Watched // ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2); // /*empty*/; // } :: e.new-clash1, // { // e.change2 : (s.tag t.m t.n e.var-id) t.new-1 t.new-2, // = // Watched // ((s.tag t.m t.n e.var-id)) (s.dir t.new-1 t.new-2); // /*empty*/; // } :: e.new-clash2, // e1 : e11 (e.Re2 t.Rt1) (e.Pe2 t.Pt1), // e.new-clash1 e.new-clash2 e11 (e.Re2) (s.dir e.Pe2) // Unwatched (t.Rt1) (s.dir t.Pt1) e2 // (e.Snt) (e.greater) (e.less) (e.hards); // : /*empty*/, : /*empty*/ \! // :: s.re-min, // :: s.pe-min, // e1 Unwatched Hard (e.Re) (s.dir e.Pe) :: e1, // { // <"<" (s.re-min) (s.pe-min)> = // s.pe-min) // (e1) (e2) e.Snt>; // <">" (s.re-min) (s.pe-min)> = // s.re-min) // (e1) (e2) e.Snt>; // (e1) (e2) e.Snt; // } :: (e1) (e2) e.Snt, // e1 e2 (e.Snt) (e.greater) (e.less) (e.hards); // { // : s.re-max, { // : s.pe-max, { // <"<" (s.re-max) (s.pe-max)> = e.Pe s.re-max; // e.Re s.pe-max; // }; // e.Pe s.re-max; // }; // e.Re ; // } : e.ineq s.max \! // <"-" s.max >> :: s.max, // :: e.cyclic, // // :: (e1) (e2) e.Snt \? // { // e1 : e Unwatched Hard t t \! // :: s.re-min, // :: s.pe-min, // { // <"<" (s.re-min) (s.pe-min)> = e.Re s.pe-min; // e.Pe s.re-min; // } :: e.ineq s.min, // <"-" s.min >> :: s.min, // :: e.cyclic, // // :: (e1) (e2) e.Snt, // e1 e2 (e.Snt) (e.greater) (e.less) (e.hards); // e1 e2 (e.Snt) (e.greater) (e.less) (e.hards); // }; // }; // = , $fail; // }; // e1 Unwatched Hard (e.Re) (s.dir e.Pe) e2, { // : /*empty*/, { // e.Re is hard expression // // (e.greater) (e.less) (e.hards); // // = $fail; // }; //// : /*empty*/ = // e.Pe is hard expression //// //// (e.greater) (e.less) (e.hards); // e1 (e.Re) (s.dir e.Pe) e2 (e.Snt) (e.greater) (e.less) (e.hards); // }; // e1 Watched t.Re t.Pe e2 = // e1 t.Re t.Pe e2 (e.Snt) (e.greater) (e.less) (e.hards); // } :: e.clashes (e.Snt) (e.greater) (e.less) (e.hards), //// , //// >, //// >, // # \{ e.clashes : e s e; } = // (e.greater) (e.less) (e.hards) (e.clashes) e.Snt; // //Improve-Clash (e.Re) (s.dir e.Pe) (e1) (e2) e.Snt = //// , // /* // * Find all non-empty hard parts in e.Pe and remember them in // * e.hard-parts. // */ // e.Pe : t.l e.right, // () (t.l) (e.right) $iter { // e.cyclic : t.var e.rest, // e.right : e.new-hard t.var e.new-right, { // e.new-hard : v = // (e.hard-parts // ((e.left) e.new-hard (t.var e.new-right)) // ) (e.left e.new-hard t.var) (e.new-right) e.rest; // (e.hard-parts) (e.left t.var) (e.new-right) e.rest; // }; // } :: (e.hard-parts) (e.left) (e.right) e.cyclic, // e.cyclic : /*empty*/ = //// , // /* // * For each hard part (or until some variables ranges are // * changed or some inequalitys are added) try to match it with // * corresponding part of e.Re. // */ // (e.hard-parts) // (e1 (e.Re) (s.dir e.Pe)) (e2) e.Snt $iter { // e.hard-parts : ((e.left-i) e.hard-i (e.right-i)) e.rest, // :: e.cyc-left, // :: e.hard-left, // > :: e.cyc-right, // :: e.hard-right, // :: s.left-len, // :: s.right-len, // <"+" s.left-len> :: s.left-min, // : s.left-max, // <"+" s.left-max s.left-len> :: s.left-max, // <"+" s.right-len> :: s.right-min, // : s.right-max, // <"+" s.right-max s.right-len> :: s.right-max, // :: s.hard-len, // :: s.len, // <"-" s.len <"+" s.right-max s.hard-len>> :: s.left, // <"-" s.len <"+" s.left-max s.hard-len>> :: s.right, // , // , // , // , // , // , // , // , // , // , // , // { // s.left-min : s.left, s.right-min : s.right = // :: (e.middle) e.change, // , // :: (e1) (e2) e.Snt, // :: s.new-left s.new-right, // , // { // s.new-left : 0, s.new-right : 0 = // (e.rest) (e1) (e2) e.Snt; // /* // * If founded matchings are coinsided then split our // * clash into three new ones. // */ // <"+" s.hard-len <"+" s.new-left s.new-right>> // : s.len = // <"+" s.left s.new-left> :: s.left, // <"+" s.right s.new-right> :: s.right, // :: (e.left-Re) e.change, // :: (e1) (e2) e.Snt, // Unwatched (e.left-Re) (s.dir e.hard-i) :: e.new-hard, // :: (e.left-Re) e.change, // :: (e1) (e2) e.Snt, // Unwatched (e.left-Re) (s.dir e.left-i) :: e.new-left, // :: (e.right-Re) e.change, // :: (e1) (e2) e.Snt, // Unwatched (e.right-Re) (s.dir e.right-i) :: e.new-right, // s.dir : { // LEFT = // e.new-hard e.new-left e.new-right; // RIGHT = // e.new-hard e.new-right e.new-left; // } :: e.new-clashes, // e1 : e1-new t t, // () (e1-new e.new-clashes) (e2) e.Snt; // /* // * Else we've got some new inequalites... // */ // = // <"+" s.left <"-" s.new-left s.left-len>> :: s.num, // , // // :: (e1) (e2) e.Snt, // <"+" s.right <"-" s.new-right s.right-len>> :: s.num, // , // // :: (e1) (e2) e.Snt, // <"-" s.len <"+" s.right <"+" s.new-right // <"+" s.hard-len s.left-len>>>> :: s.num, // , // // :: (e1) (e2) e.Snt, // <"-" s.len <"+" s.left <"+" s.new-left // <"+" s.hard-len s.right-len>>>> :: s.num, // , // // :: (e1) (e2) e.Snt, // (e.rest) (e1) (e2) e.Snt; // }; // /* // * At least one inequlity shurely will be added, so we'll go // * out of the $iter. // */ // = { // <"<" (s.left-min) (s.left)> = // ; // (e1) (e2) e.Snt; // } :: (e1) (e2) e.Snt, { // <">" (s.left-min) (s.left)> = // <"-" s.len <"+" s.left-min <"+" s.hard-len s.right-len>>> // :: s.left, // ; // (e1) (e2) e.Snt; // } :: (e1) (e2) e.Snt, { // <"<" (s.right-min) (s.right)> = // ; // (e1) (e2) e.Snt; // } :: (e1) (e2) e.Snt, { // <">" (s.right-min) (s.right)> = // <"-" s.len <"+" s.right-min <"+" s.hard-len s.left-len>>> // :: s.right, // ; // (e1) (e2) e.Snt; // } :: (e1) (e2) e.Snt, // () (e1) (e2) e.Snt; // }; // } :: (e.hard-parts) (e1) (e2) e.Snt, // \{ // e1 : \{ e Unwatched (e) (e); e Unwatched Hard (e) (e); }; // e.hard-parts : /*empty*/; // } = // e1 e2 (e.Snt); // ///* // * If occurrence of e.Pe is found in e.Re and it can be there then return // * variables which should be minimized. // * If found occurence of e.Re isn't legal then return empty expression. // * And return $fail if there are no occurences of e.Re in e.Pe. // */ //Self-Occur (e.Re) e.Pe, , { // e.Re : e1 e.Pe e2 , { // : 0 = Occur e1 e2; // /*empty*/; // }; // e.Pe Not-Found $iter { // e.Pe : e (PAREN v.pe-expr) e, { // e.Re : e v.pe-expr e = Found; // v.pe-expr Not-Found; // }; // } :: e.Pe s.found?, // \{ // s.found? : Found = /*empty*/; // # \{ e.Pe : e (PAREN v) e; } = $fail; // }; //}; // //Cyclic e.expr = // () e.expr $iter { // e.expr : t1 e2, t1 : { // s.ObjectSymbol = /*empty*/; //// (REF t.name) = ??? // (PAREN e) = /*empty*/; // (s.var-tag s.m (e.n) e.var-id), # \{ s.m : e.n; } = t1; // t = /*empty*/; // } :: e.new-cyclic, // (e.cyclic e.new-cyclic) e2; // } :: (e.cyclic) e.expr, // e.expr : /*empty*/ = // e.cyclic; // //Hard e.expr = // () e.expr $iter { // e.expr : t1 e2, t1 : { // s.ObjectSymbol = t1; //// (REF t.name) = ??? // (PAREN e) = t1; // (s.var-tag s.m (e.n) e.var-id), # \{ s.m : e.n; } = /*empty*/; // t = t1; // } :: e.new-hard, // (e.hard e.new-hard) e2; // } :: (e.hard) e.expr, // e.expr : /*empty*/ = // e.hard; // ////Hard-Exp? e.expr = //// e.expr () $iter \{ //// () $iter { //// e.cyclic : (s.tag t t e.var-id) e.rest, { //// = e.rest (e.num); //// e.rest (e.num I); //// }; //// } :: e.cyclic (e.num), //// , //// \{ //// e.num : I I = $fail; //// e.cyclic : /*empty*/, { //// e.expr : e1 (PAREN e.paren) e2 = e.paren (e.watched e2); //// e.watched : e1 (PAREN e.paren) e2 = e.paren (e2); //// /*empty*/ (); //// }; //// }; //// } :: e.expr (e.watched), //// e.expr : /*empty*/; // //Exchange (e.var-holder) (e.new-expr) e.clashes (e.Snt) = // e.var-holder : t.var, // /* // * Mark containing t.var clashes as "Unwatched" and change t.var to // * t.new-var in them. // */ // () e.clashes $iter { // e.clashes : e.tag (e.Re) (e.Pe) e.rest, // { // e.tag : Watched = Watched; // Unwatched; // } :: s.watched?, // { // : e t.var e = // (e.new-clashes // s.watched? // ) e.rest; // (e.new-clashes e.tag (e.Re) (e.Pe)) e.rest; // }; // } :: (e.new-clashes) e.clashes, // e.clashes : /*empty*/ = // /* // * Remove all inequalitys wich contain t.var. // */ // () $iter { // e.ineqs : t.ineq e.rest, // { // t.ineq : (e t.var e) = /*empty*/; // t.ineq; // } :: e.ineq, // (e.new-ineqs e.ineq) e.rest; // } :: (e.new-ineqs) e.ineqs, // e.ineqs : /*empty*/ = // , // () $iter { // e.ineqs : t.ineq e.rest, // { // t.ineq : (e t.var e) = /*empty*/; // t.ineq; // } :: e.ineq, // (e.new-ineqs e.ineq) e.rest; // } :: (e.new-ineqs) e.ineqs, // e.ineqs : /*empty*/ = // , // /* // * Rename t.var in the rest of current sentence. // */ // t.var : (s.tag t t e.var-id), // temporary step //// :: e.new-expr, // temporary step // e.new-clashes (); // //Exchange-Exp (e.change) (e1) (e2) e.Snt = //{ // e.change : t.old-1 t.new-1 t.new-2 e.change1 = // :: e1 t, // :: e2 (e.Snt), // { // e.change1 : t.old-2 e.new-3 = // :: e1 t, // :: e2 (e.Snt), // (e1) (e2) e.Snt; // (e1) (e2) e.Snt; // }; // (e1) (e2) e.Snt; //}; // //Minimize (e.expr) (e.clashes) e.Snt = // (e.expr) () e.clashes (e.Snt) $iter { // e.expr : t.var e.rest, // t.var : (s.tag t t e.var-id), // { // = (t.var 0); // /*empty*/; // } :: e.new-less, // (e.rest) (e.less e.new-less) ; // } :: (e.expr) (e.less) e.clashes (e.Snt), // e.expr : /*empty*/ = // (e.clashes) (e.less) e.Snt; // //Intersect s.k (e.l) s.m (e.n) = // { // <"<" (s.k) (s.m)> = s.m; // s.k; // } :: s.x, // { // e.l e.n : /*empty*/ = /*empty*/; // e.l : /*empty*/ = e.n; // e.n : /*empty*/ = e.l; // <"<" (e.n) (e.l)> = e.n; // e.l; // } :: e.y, // \{ // e.y : /*empty*/ = s.x (); // <"<=" (s.x) (e.y)> = s.x (e.y); // }; // //Min-Length e.expr = // 0 e.expr $iter { // e.expr : t1 e2, t1 : { // s.ObjectSymbol = <"+" s.len 1>; //// (REF t.name) = ??? // (PAREN e) = <"+" s.len 1>; // (s.var-tag s.m (e.n) e.var-id) = <"+" s.len s.m>; // } :: s.len, // s.len e2; // } :: s.len e.expr, // e.expr : /*empty*/ = // s.len; // //Max-Length e.expr = // 0 e.expr $iter { // e.expr : t1 e2, t1 : { // s.ObjectSymbol = <"+" s.len 1>; //// (REF t.name) = ??? // (PAREN e) = <"+" s.len 1>; // (s.var-tag s.m (s.n) e.var-id) = <"+" s.len s.n>; // (s.var-tag s.m () e.var-id) = Empty; // } :: s.len, // s.len e2; // } :: s.len e.expr, // \{ // s.len : Empty = /*empty*/; // e.expr : /*empty*/ = s.len; // }; // //Add-Less-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt = // :: s.min, { // <">" (s.min) (s.len)> = $fail; // :: e.mults, // :: s.min-len, // /* // * For each variable form new inequality recompute its maximum: // * new_max = (s.len - s.min-len + s.mult * min) / s.mult // */ // () e.vars $iter { // e.tmp-vars : (s.tag s.m (e.n) e.var-id) e.rest, // e.mults : e (s.tag s.m (e.n) e.var-id) s.mult e, //
<"*" s.mult s.m>> s.mult> // :: s.max, // { // e.n : /*empty*/ = s.max; // <"<" (e.n) (s.max)> = e.n; // s.max; // } :: e.max, // (e.new-vars (s.tag s.m (e.max) e.var-id)) e.rest; // } :: (e.new-vars) e.tmp-vars, // e.tmp-vars : /*empty*/ = // : s.max-len, { // /* // * Check that maximums weren't decreased too much. // */ // <">" (s.min) (s.max-len)> = $fail; // /* // * If max-len == <> then change all // * e*[min,max] to e*[max,max]. If max == 0 then change variable // * to empty expression. // */ // s.min : s.max-len = // e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter { // e.vars : t.var e.rest, // e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest, { // s.n : 0 = //// //// :: e.clashes1 t, //// //// :: e.clashes2 (e.Snt), // e.rest (e.new-rest) // (e.clashes1 Unwatched (t.var) (LEFT)) // (e.clashes2) (e.Snt); // :: e.clashes1 t, // :: e.clashes2 (e.Snt), // e.rest (e.new-rest) (e.clashes1) // (e.clashes2) (e.Snt); // }; // } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt), // e.vars : /*empty*/ = // (e.clashes1) (e.clashes2) e.Snt; // /* // * If no maximums were changed then see whether we should add // * new inequality to storage and if so then mark clashes // * containing e.vars in the begining or reversed e.vars in the // * end as "Unwatched Hard". // */ // e.vars : e.new-vars, { // <">" () (s.len)>, // () $iter e.tmp-ineqs : { // e1 (e.vars e.ineq s.in-len) e2, // : s.ineq-max, // <"<=" (<"+" s.len s.ineq-max>) (s.in-len)>, // (e.ineqs e1) e2; // e1 = (e.ineqs e1); // } :: (e.ineqs) e.tmp-ineqs, // e.tmp-ineqs : /*empty*/ = // { // e.ineqs : e1 (e.vars e.ineq) e2 = // e1 (e.vars s.len) (e.vars e.ineq) e2; // e.ineqs (e.vars s.len); // } :: e.ineqs, // , // () // () // e.Snt; // (e.clashes1) (e.clashes2) e.Snt; // }; // /* // * Else, if some maximums were changed, then change them in all // * clashes and in Snt. For each variable maximum can't be less // * then minimum because it would mean that s.len < s.min. // * If max == 0 then change variable to empty expression. // */ // e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter { // e.vars : t.var e.rest, // e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest, { // t.var : (s.tag s.m (s.n) e.var-id) = // e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt); // s.n : 0 = //// //// :: e.clashes1 t, //// //// :: e.clashes2 (e.Snt), // e.rest (e.new-rest) // (e.clashes1 Unwatched (t.var) (LEFT)) (e.clashes2) // (e.Snt); // :: e.clashes1 t, // :: e.clashes2 (e.Snt), // e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt); // }; // } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt), // e.vars : /*empty*/ = // (e.clashes1) (e.clashes2) e.Snt; // }; // }; // //Add-Greater-Ineq (e.vars s.len) (e.clashes1) (e.clashes2) e.Snt, { // : s.max, { // <"<" (s.max) (s.len)> = $fail; // :: e.mults, // : s.max-len, // /* // * For each variable from new inequality recompute its minimum: // * new_min = ceil ((s.len - s.max-len + s.mult * max) / s.mult) // */ // () e.vars $iter { // e.tmp-vars : (s.tag s.m (s.n) e.var-id) e.rest, // e.mults : e (s.tag s.m (s.n) e.var-id) s.mult e, // <"*" s.mult s.n>> s.mult> // :: s.min, // { // <"<" (s.min) (0)> = 0; // <">" (s.m) (s.min)> = s.m; // s.min; // } :: s.min, // (e.new-vars (s.tag s.min (s.n) e.var-id)) e.rest; // } :: (e.new-vars) e.tmp-vars, // e.tmp-vars : /*empty*/ = // :: s.min-len, { // /* // * Check that minimums weren't increased too much. // */ // <"<" (s.max) (s.min-len)> = $fail; // /* // * If min-len == <> then change all // * e*[min,max] to e*[min,min]. // */ // s.max : s.min-len = // e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter { // e.vars : t.var e.rest, // e.new-vars : (s.tag s.m (s.n) e.var-id) e.new-rest, // :: e.clashes1 t, // :: e.clashes2 (e.Snt), // e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt); // } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt), // e.vars : /*empty*/ = // (e.clashes1) (e.clashes2) e.Snt; // /* // * If no minimums were changed then see whether we should add // * new inequality to storage and if so then mark clashes // * containing e.vars in the begining or reversed e.vars in the // * end as "Unwatched Hard". // */ // e.vars : e.new-vars, { // <"<" () (s.len)>, // () $iter e.tmp-ineqs : { // e1 (e.vars e.ineq s.in-len) e2, // <">=" (<"+" s.len >) (s.in-len)>, // (e.ineqs e1) e2; // e1 = (e.ineqs e1); // } :: (e.ineqs) e.tmp-ineqs, // e.tmp-ineqs : /*empty*/ = // { // e.ineqs : e1 (e.vars e.ineq) e2 = // e1 (e.vars s.len) (e.vars e.ineq) e2; // e.ineqs (e.vars s.len); // } :: e.ineqs, // , // () // () // e.Snt; // (e.clashes1) (e.clashes2) e.Snt; // }; // /* // * Else, if some minimums were changed, then change them in all // * clashes and in Snt. For each variable minimum can't be greater // * then maximum because it would mean that s.len > s.max. // */ // e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt) $iter { // e.vars : t.var e.rest, // e.new-vars : t.new-var e.new-rest, { // t.var : t.new-var = // e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt); // // :: e.clashes1 t, // // :: e.clashes2 (e.Snt), // e.rest (e.new-rest) (e.clashes1) (e.clashes2) (e.Snt); // }; // } :: e.vars (e.new-vars) (e.clashes1) (e.clashes2) (e.Snt), // e.vars : /*empty*/ = // (e.clashes1) (e.clashes2) e.Snt; // }; // }; // e.vars : (s.tag s.n () e.var-id), { // <">" (s.len) (s.n)> = // :: e.clashes1 t, // :: e.clashes2 (e.Snt), // (e.clashes1) (e.clashes2) e.Snt; // (e.clashes1) (e.clashes2) e.Snt; // }; // (e.clashes1) (e.clashes2) e.Snt; // STUB!!! Add inequality to the storage? //}; // //Get-Min e.vars, { // : $r e (e.ineq s.len) e, // e.vars : e.ineq e.other, // <"+" s.len >; // ; //}; // //Get-Max e.vars, { // : $r e (e.ineq s.len) e, // e.vars : e.ineq e.other, // : s.other-len, // <"+" s.len s.other-len>; // ; //}; // ///* // * Computes variables multiplicitys and returns them in the form: // * e.mults ::= t.var s.mult e.mults | [] // */ //Mults e.vars = // () e.vars $iter { // e.vars : t.var e.rest, // 1 e.rest $iter { // e.rest : e1 t.var e2, // <"+" s.mult 1> e1 e2; // } :: s.mult e.rest, // # \{ e.rest : e t.var e; } = // (e.mults t.var s.mult) e.rest; // } :: (e.mults) e.vars, // e.vars : /*empty*/ = // e.mults; // //Mark-Unw-Hard (e.vars) e.clashes = // :: e.rev-vars, // () e.clashes $iter e.clashes : { // (e.Re) (e.Pe) e.rest, // :: e.cyc-Re, // :: e.cyc-Pe, // { // \{ // e.cyc-Re : e.vars e; // e.cyc-Re : e e.rev-vars; // e.cyc-Pe : e.vars e; // e.cyc-Pe : e e.rev-vars; // }, // (e.new-clashes Unwatched Hard (e.Re) (e.Pe)) e.rest; // (e.new-clashes (e.Re) (e.Pe)) e.rest; // }; // e.tag (e.Re) (e.Pe) e.rest = // (e.new-clashes e.tag (e.Re) (e.Pe)) e.rest; // } :: (e.new-clashes) e.clashes, // e.clashes : /*empty*/ = // e.new-clashes; // //Ceil s1 s2, { // : 0 =
; // <"+"
1>; //}; // //Match-Exp (e.Re) e.Pe = // :: e.Re, // :: e.Pe, // :: s.len, // e.Re : e1 e2, // ) (e.Pe)>, // e2 : $r e3 e4, // ) (e.Pe)>, // ; // //Match e.clash = // e.clash $iter e.clashes : \{ // e1 (e.expr) (e.expr) e2 = e1 e2; // e1 (t.Rt e.Re) (t.Pt e.Pe) e2, // # \{ t.Rt : (EVAR e); t.Pt : (EVAR e); } = // ; // e1 (e.Re t.Rt) (e.Pe t.Pt) e2, // # \{ t.Rt : (EVAR e); t.Pt : (EVAR e); } = // ; // e1 (e.Re) (e.Pe) e2, \{ // e.Re : (EVAR e) e (EVAR e) = ; // e.Pe : (EVAR e) e (EVAR e) = ; // \{ // e.Re : (EVAR e) e, e.Pe : e (EVAR e); // e.Re : (EVAR e) e, e.Pe : e (EVAR e); // } = // () // ()>; // This is STUB!!! // }; // } :: e.clashes, // , // e.clashes : /*empty*/; // //Match-Term { // term term e.clashes = e.clashes; // t.Rt t.Pt e.clashes, t.Rt : { // s.ObjectSymbol = // t.Pt : (s.tag e), // SVAR TVAR : e s.tag e, // check that s.tag isn't PAREN // ; // (SVAR e), t.Pt : { // s.ObjectSymbol = ; // (s.tag e) = // SVAR TVAR : e s.tag e, // check that s.tag isn't PAREN // ; // }; // (TVAR e) = // ; // (PAREN e.Re) = t.Pt : \{ // (TVAR e) = ; // (PAREN e.Pe) = (e.Re) (e.Pe) e.clashes; // }; // }; //}; // //Match-Cyclic (e.Re) (e.Pe) e.clashes = ; // This is STUB!!! // //Granulate e.expr = // (e.expr) $iter { // e.vars : t.var e.rest, // t.var : { // (s.tag 1 (1) e.var-id), { // SVAR TVAR : e s.tag e = e.expr; // ; // }; // (s.tag s.n (s.n) e.NEW (e.QualifiedName)) = // s.n /*empty*/ $iter // <"-" s.n 1> // (TVAR 1 (1) NEW ("gran" e.QualifiedName s.n)) e.new-vars // :: s.n e.new-vars, // s.n : 0 = // ; // (s.tag e.something), { // cyclic variable // s.tag : EVAR = e.expr; // ; // }; // } :: e.expr, // (e.expr) e.rest; // } :: (e.expr) e.vars, // e.vars : /*empty*/ = // e.expr; // //Left-Exp s.left s.len e.expr, \{ // <"<" () (<"+" s.left s.len>)> // = $fail; // s.len : 0 = (); // s.left : 0 = // 0 () e.expr $iter \{ // e.expr : t1 e2, t1 : { // s.ObjectSymbol = <"+" s.num 1>; //// (REF t.name) = ??? // (PAREN e) = <"+" s.num 1> ; // (s.var-tag s.n (s.n) e.var-id) = <"+" s.num s.n>; // (s.var-tag s.m (e.n) e.var-id) = // <"+" s.num s.m> :: s.num, // <"<=" (s.len) (s.num)>, // s.num; // } :: s.num, // s.num (e.left t1) e2; // } :: s.num (e.left) e.expr, // <"<=" (s.len) (s.num)> = // <"-" s.num s.len> :: s.r-min, // e.left : e.first t.var, // t.var : { // s.ObjectSymbol = (e.left); // (PAREN e) = (e.left); // (s.tag s.m (e.n) e.NEW (e.QualifiedName)) = // <"-" s.m s.r-min> :: s.l-len, // e.n : { // /*empty*/ = /*empty*/; // s.x = <"-" <"+" s.x > s.l-len>; // } : { // 0 = (e.left); // e.r-max, // (s.tag s.l-len (s.l-len) NEW ("l-split" e.QualifiedName)) // :: t.l-var, // (s.tag s.r-min (e.r-max) NEW ("r-split" e.QualifiedName)) // :: t.r-var, // :: e.expr, // (e.expr t.l-var) t.var t.l-var t.r-var; // }; // }; // :: (e.left) e.change, // { // e.change : t.old-var t.new-1 t.new-2 = // ; // e.expr; // } : e.left e.right, // e.change; //}; // //Right-Exp s.right s.len e.expr, \{ // <"<" () (<"+" s.right s.len>)> // = $fail; // s.len : 0 = (); // s.right : 0 = // 0 () e.expr $iter \{ // e.expr : e2 t1, t1 : { // s.ObjectSymbol = <"+" s.num 1>; //// (REF t.name) = ??? // (PAREN e) = <"+" s.num 1> ; // (s.var-tag s.n (s.n) e.var-id) = <"+" s.num s.n>; // (s.var-tag s.m (e.n) e.var-id) = // <"+" s.num s.m> :: s.num, // <"<=" (s.len) (s.num)>, // s.num; // } :: s.num, // s.num (t1 e.right) e2; // } :: s.num (e.right) e.expr, // <"<=" (s.len) (s.num)> = // <"-" s.num s.len> :: s.l-min, // e.right : t.var e.last, // t.var : { // s.ObjectSymbol = (e.right); // (PAREN e) = (e.right); // (s.tag s.m (e.n) e.NEW (e.QualifiedName)) = // <"-" s.m s.l-min> :: s.r-len, // e.n : { // /*empty*/ = /*empty*/; // s.x = <"-" <"+" s.x > s.r-len>; // } : { // 0 = (e.right); // e.l-max, // (s.tag s.r-len (s.r-len) NEW ("r-split" e.QualifiedName)) // :: t.r-var, // (s.tag s.l-min (e.l-max) NEW ("l-split" e.QualifiedName)) // :: t.l-var, // :: e.expr, // (e.expr t.r-var) t.var t.l-var t.r-var; // }; // }; // :: (e.right) e.change, // { // e.change : t.old-var t.new-1 t.new-2 = // ; // e.expr; // } : e.left e.right, // e.change; //}; // //// Right-Exp s.right s.len e.expr = //// :: s.expr-len, //// <"+" s.right s.len> :: s.sum, //// \{ //// <"<" (s.expr-len) (s.sum)> = $fail; //// s.len e.expr>; //// }; // //Middle-Exp s.left s.right e.expr, \{ // <"<" () (<"+" s.left s.right>)> // = $fail; // :: (e.left) e.l-change, // :: (e.right) e.r-change, // e.expr : e.left e.sought e.right, // (e.sought) e.l-change e.r-change; //};