Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Parallel Parsing with Attributes and Not: Technical Discussion W.Pasman, 4.6.7 Overview 1. Strategy specification 2. Tracking the student's actions: Chart Parser 3. Attribute Parser What is a Strategy • Describes all possible paths to the solution, as sequences of rewrite rules • Some of the sequences may not be applicable to the term at hand, and therefore are not a path to the solution after all (discussed in detail soon) • Basic method to generate all these paths: repeat(rule), rule1 or rule 2, rule1 followedby rule2 or, as I do, by a context free grammar: S::=N N::=rule1 rule2 N::=rule3 Extra Primitives // operator strategy1 parallelwith strategy2 testing non- not(strategy) applicability of strategy attributes code snippets Multrow with $rowtomultiply=1 and $factor=1/2 MathematicaCode[..$factor=...] Examples of Extra Primitives Parallel operator to handle multiple substitutions term:{ R=x+y+z,x=1, y=2, z=3 } rules: subX, subY, subZ strategy: S::= repeatexh(subX//subY//subZ//simplify) Not operator: for instance to implement repeatexh: repeatexh($x)::=$x repeatexh($x) repeatexh($x)::=not($x) Attributes to enable parameterized rules. mul($matrix,$row,$k)$matrix with $row multiplied with $k Typically, the user is asked in these cases to enter the parameters Computation and Fail in Rules Attributes empower code snippets in rules In Rewrite Rules multrow[$row,$k,$pos]: M_matrix Code[If[$k===0,$Failure, ReplacePart[M,$k*Extract[M,$row],$row]]] In Grammar Rules N::=Code[$y=(7,2)] multrow[3,4,$y] M[$y,$z]::=Code[If[$y===0,$Failure]] ... Strategy Specification • is specific for one problem term (it might be more generic) • generates rewrite sequences that may apply to the problem term: mul[s[0],plus[0,s[0]]] rules RewriteRule["zeroadd", plus[0, x_] x] zeroadd: plus[0,x_]x RewriteRule["onemul", mul[s[0], x_] x] onemul: mul[s[0],x_]x strategy S::=N S | N::=zeroadd | onemul GrammarRule["S", {"N","S"}] GrammarRule["S", {}] GrammarRule["N", {"zeroadd"}] GrammarRule["S", {"onemul"}] • generates rewrite sequences that may apply to the problem rules zeroadd: plus[0,x_]x onemul: mul[s[0],x_]x strategy S::=N S | N::=zeroadd | onemul 0+x=x 1*x=x This generates the rewrite sequence zeroadd onemul and that is applicable on mul[s[0],plus[0,s[0]]]: mul[s[0],plus[0,s[0]]] mul[s[0],s[0]] s[0] *(1, +(0,1) ) = *(1,1) = 1 1*(0+1) = 1*1 =1 But this rewrite sequence zeroadd onemul is not applicable to mul[s[0],0] If a generated rewrite sequence is applicable then the solution (the result of applying the rewrite sequence to the term) is a good one. 2. Student Tracking Student Tracking: Chart Parser • Suitable for ambiguous grammars • eliminates backtracking • prevents combinatorial explosion • Breath first search • Incremental parsing: next student step takes same time • Explicit representation of all steps done in the parser • Parser at any time compactly represents succesful parses so far Example Grammar: S::=a b. input string: a b add shift possibility scanner: if item a•Nb in set and there is shift possibility for N to set X then add item aN•b to set X add another shift do another scanner step completer: recognise nonterminal if item I:N::=...• in set Xe and item J:N::=•... in set Xs and J is linked to I then make shiftpossibility <N,Xs,Xe> Applicable(S) input: parser state and start terminal return: the shortest strategy that is applicable or failure if no strategy is applicable Always terminates as parsing always terminates Not(S) Not(S) means: we can NOT parse an S More specifically, Every rewrite sequence generated by S is NOT applicable. Not(S) = not(Applicable(S)) P//Q Scan P and Q in parallel Deep permutation: P//Q means that the rewrite steps generated by P and Q can be permutated Example: P::=abc, Q::= fgh Then one permutation is afgbch P//Q Parser Try ALL permutations of the input symbols over P and Q Expensive: potentially 2n costs in order of input length n But usually not all permutations are applicable. Example G={S::=P//Q, P::=aa, Q::=b}, input aba Note distribution numbers. In implementation we keep all within set 0. 0 2 1 S::=•(P//Q) 0 P::=a•a P::=•aa Q::=•b 3 S::=•(P//Q) 010 P::=aa• 00 Q::=•b 1 P::=•aa Q::=b• 01 P::=a•a Q::=b• 011 P::=a•a Q::=b• a b P//Q S a Position of Rewrite Rules are extended for explicit control of position of application becomes (...) is path from root to term. e.g. (1,2) is 2nd child of 1st child of root. Examples plus0atroot: plus[0,x_]@()x @(...) 3. Attributes Attributes for Rules $x etc are attributes: a variable similar to x_ This allows us to rules like swap[$i,$j]: M_matrix@$posM with row $i and row $j swapped plus0at[$pos]: plus[0,x_]@$posx and a grammar rule like N[$x]::=P[$x,3] Inheriting Attributes Inheriting: passing values downward. rewriterule: swap[$i,$j]:.... item: S::=•swap[3,4] Result: rule applied as $i=3, $j=4 grammarrule: M[$y,$z]::=... item: S::=•M[3,4] Result: new item M[3,4]::=•... with local vars {$y=3,$z=4} Note, vars are local, consider M[$y,$z]::=Code[$z=5] where $z is locally manipulated in M without effect on higher levels. Synthesizing Attributes Synthesizing: propagating local results upwards Only uninstantiated variables can be synthesized S::=M[$x] M[$x]::=Code[$x=3] or the special case, where $pos is instantiated from where the student actually applies the rule: S::=ruleplus0[$pos] ...use $pos... ruleplus0[$pos]: plus[0,x_]@$posx Parsing Not with Attri's Not[S[$x]] still means: we can NOT parse an S[$x] (for any value of $x) • $x MUST be set at the time a rewrite rule is encountered that uses $x. • Exception: $pos may be unset in @$pos in this case, ALL possible $pos are tried separately Tricky cases: for example S::=N[$x,3] (result will be $x=3) N[$x,$x]::=... Shared Attri + Parallel Operator Example with Problem with shared attri handling. term=times[s[0],plus[0,s[0]]] rulemult1[$pos]: times[s[0],x_]@$posx ruleplus0[$pos]: plus[0,x_]@$posx S::=M[$posofplus]//P[$posofplus] M[$posofplus]::=Code[$posofplus=(2)] rulemult1[()] $posofplus=() P[$posofplus]::=Code[$posofplus=(2)] ruleplus0[$posofplus] Idea: we want P and Q to share the var $posofplus, such that it KEEPS pointing to the plus[0,s[0]] Parallel Issues Now take careful look S::=M[$posofplus]//P[$posofplus] M[$posofplus]::=Code[$posofplus=(2)] rulemult1[()] $posofplus=() P[$posofplus]::=Code[$posofplus=(2)] ruleplus0[$posofplus] We actually may encounter this evaluation order: Code[$posofplus=(2)] rulemult1[()] $posofplus=() Code[$posofplus=(2)] ruleplus0[$posofplus] Similar problems may occur if rulemult1[()] is executed but the subsequent $posofplus=() is delayed until after evaluation of P. Conclusions Attributes mostly solved and implemented. One issue remains: shared attributes in parallel parsers Mechanism to automatically update shared termpointers? Extracting path (example solution) from parser seems easy Questions & Discussion ?