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 ?