for block in re.compile('^> ', re.MULTILINE).split(code):
cmd = []
expect = []
+
+ reading = True
+
for i, line in enumerate(block.split('\n')):
- if line.startswith('|') or i == 0:
+ if (line.startswith('|') or i == 0) and reading:
if line.startswith('|'):
line = line[1:]
cmd.append(line)
else:
+ reading = False
expect.append(line)
yield '\n'.join(cmd).strip(), '\n'.join(expect).strip()
def clean(x):
- return re.sub('\033\[\d+m', '', strip_comments(x)).strip()
+ # remove whitespace at end of line
+ # remove ansi color codes
+ return re.compile('(\s*)$', re.MULTILINE).sub('', re.sub('\033\[\d+m', '', strip_comments(x)).strip())
def run(code):
interp = Interpreter()
repl = REPL(interp)
- errors = []
+ errors = 0
for cmd, expect in extract(code):
+
if not clean(cmd):
print
continue
+
print yellow % '> %s' % cmd
if clean(cmd) == '*resume*':
sys.stdout = sys.__stdout__
got = clean(x.getvalue())
- expect = clean(got)
+ expect = clean(expect)
- if clean(expect) == '*ignore*':
+ if expect == '*ignore*':
continue
if expect != got:
print green % expect
print red % got
- errors.append([cmd, expect, got])
+ errors += 1
else:
print
print got
print green % 'PASS!'
print
else:
- print red % '%s errors' % len(errors)
+ print yellow % '>>>', red % '%s errors' % errors
print
sys.exit(1)
return
print
for term, result in sorted((subst(q, result), result) for result in results):
- print term, '=', _repr(result['$val'])
+ print '%s = %s.' % (term, _repr(result['$val']))
print
def default(self, line, show_changed=True):
+++ /dev/null
-#!/usr/bin/env bash
-
-echo -e "
-a += 1.
-a." |./dyna > $0.out
-
-diff <(sed -e 's/[ -][^ -]*\.dyna/ /g' $0.expect) \
- <(sed -e 's/[ -][^ -]*\.dyna/ /g' $0.out) \
- && echo pass
-> >
+
+> a += 1.
+
Changes
=======
a = 1.
-> DynaCompilerError:
+> a.
+DynaCompilerError:
Encountered error in input program:
Conflicting aggregators; rule <repl>
uses '|=' for a/0 but I had been lead to expect '+='.
see it through.
new rule(s) were not added to program.
-
-> exit
--- /dev/null
+% This program should leave b in an error state, but currently leaves it at 2
+% for some reason:
+
+> a(1) := 1. a(2) := 2. b := 0. b := a(X).
+
+Changes
+=======
+a(1) = 1.
+a(2) = 2.
+b = $error.
+
+> sol
+
+Solution
+========
+b = $error.
+
+a/1
+===
+a(1) = 1.
+a(2) = 2.
+
+
+Errors
+======
+Error(s) aggregating b/0:
+ AggregatorError:
+ `b`: `:=` got conflicting values [1, 2] for rule index 3
+
+
+% It should be an error because the last rule to contribute any aggregands to b
+% (namely rule 4) contributes multiple aggregands, and there's no way to choose
+% among them.
+
+% Until recently, I would have said that the following should also leave b in an
+% error state. But now possibly we should allow b to be 2 in this case for
+% consistency with the new version of = that we're trying on #23. Thoughts?
+
+> retract_rule 3
+
+Changes
+=======
+b = 0.
+
+> a(1) := 2. a(2) := 2. b := 0. b := a(X).
+
+Changes
+=======
+a(1) = 2.
+b = 2.
+
+> sol
+
+Solution
+========
+b = 2.
+
+a/1
+===
+a(1) = 2.
+a(2) = 2.
+++ /dev/null
-#!/usr/bin/env bash
-
-# Some items learn their aggregator late in life.
-
-echo -e "
-a += b * c.
-rules
-b := 2.
-rules
-c := 3.
-rules" |./dyna > $0.out
-
-diff <(sed -e 's/[ -][^ -]*\/\.dyna/ /g' $0.expect) \
- <(sed -e 's/[ -][^ -]*\/\.dyna/ /g' $0.out) \
- && echo pass
-> > >
+
+> a += b * c.
+> rules
+
Rules
=====
0: a += b * c.
->
+> b := 2.
+
Changes
=======
b = 2.
->
+> rules
+
Rules
=====
0: a += b * c.
1: b := 2.
->
+> c := 3.
Changes
=======
a = 6.
c = 3.
->
+> rules
+
Rules
=====
0: a += b * c.
1: b := 2.
2: c := 3.
-
-> exit
+++ /dev/null
-#!/usr/bin/env bash
-
-# The example shows off some of the REPL's data loading commands.
-
-./dyna test/repl/load.dyna \
- --load 'rules_tsv = tsv("test/repl/english.gr")' \
- 'token = matrix("test/repl/english.sen", astype=str)' \
- 'tree = sexpr("test/repl/english.par")' \
- --post 'dump_solution()' \
- "$@"
+++ /dev/null
-% accompanies load.bash
-
-:- dispos &cons(&,&).
-:- dispos &nil.
-
-% binary rules
-rewrite(X, Y, Z) :=
- rules_tsv(Linenum, Cost, X, R),
- [Y, Z] is split(R, "\\s+"),
- float(Cost).
-
-% load unary rules
-rewrite(X, Y) :=
- rules_tsv(Linenum, Cost, X, R),
- [Y] is split(R, "\\s+"),
- float(Cost).
-
-phrase(S,X,I,K) += phrase(S,Y,I,K) + rewrite(X,Y).
-phrase(S,X,I,K) += phrase(S,Y,I,J) + phrase(S,Z,J,K) + rewrite(X,Y,Z).
-phrase(S,W,I,I+1) += W is token(S,I), 0.
-
-sentence_length(S) max= token(S,I), I+1.
-goal(S) += phrase(S, "ROOT", 0, sentence_length(S)).
--- /dev/null
+> :- dispos &cons(&,&).
+| :- dispos &nil.
+|
+| % binary rules
+| rewrite(X, Y, Z) :=
+| rules_tsv(Linenum, Cost, X, R),
+| [Y, Z] is split(R, "\\s+"),
+| float(Cost).
+|
+| % load unary rules
+| rewrite(X, Y) :=
+| rules_tsv(Linenum, Cost, X, R),
+| [Y] is split(R, "\\s+"),
+| float(Cost).
+|
+| phrase(S,X,I,K) += phrase(S,Y,I,K) + rewrite(X,Y).
+| phrase(S,X,I,K) += phrase(S,Y,I,J) + phrase(S,Z,J,K) + rewrite(X,Y,Z).
+| phrase(S,W,I,I+1) += W is token(S,I), 0.
+|
+| sentence_length(S) max= token(S,I), I+1.
+| goal(S) += phrase(S, "ROOT", 0, sentence_length(S)).
+
+
+> load rules_tsv = tsv("test/repl/data/english.gr")
+ *ignore*
+> load token = matrix("test/repl/data/english.sen", astype=str)
+ *ignore*
+> load tree = sexpr("test/repl/data/english.par")
+ *ignore*
+> post dump_solution()
+
+ *ignore*
+
+> vquery goal(X)
+
+16.990000000000002 where {X=14}
+20.97 where {X=7}
+22.97 where {X=0}
+22.97 where {X=1}
+22.97 where {X=2}
+28.169999999999995 where {X=16}
+34.89 where {X=4}
+36.89 where {X=3}
+38.84 where {X=17}
+42.06 where {X=13}
+42.57 where {X=8}
+42.57 where {X=9}
+43.85 where {X=19}
+45.269999999999996 where {X=10}
+53.7 where {X=20}
+87.37 where {X=6}
+91.37 where {X=5}
+137.65 where {X=12}
+
+> query tree(0)
+
+tree(0) = ['ROOT', ['S', ['NP', 'George'], ['VP', ['V', ['V', 'love'], '-s'], ['NP', 'Laura']]], '.'].
+
+> query sentence_length(10)
+
+sentence_length(10) = 9.
+
+> *resume*
+++ /dev/null
-#!/usr/bin/env bash
-
-echo -e "
-a += 1.
-b += 1.
-a += 1.
-rules
-sol
-retract_rule 0
-retract_rule 1
-sol" |./dyna > $0.out
-
-diff $0.expect $0.out && echo pass
-
-# TODO: add test to make sure that rule retraction will clear errors.
-
-#$ echo -e "retract_rule 0\n retract_rule 3\nretract_rule 6\nrules\nchart" | ./dyna examples/errors.dyna -i
+++ /dev/null
-> >
-Changes
-=======
-a = 1.
-
->
-Changes
-=======
-b = 1.
-
->
-Changes
-=======
-a = 2.
-
->
-Rules
-=====
- 0: a += 1.
- 1: b += 1.
- 2: a += 1.
-
->
-Solution
-========
-a = 2.
-b = 1.
-
->
-Changes
-=======
-a = 1.
-
->
-Changes
-=======
-b = null.
-
->
-Solution
-========
-a = 1.
-
-> exit
--- /dev/null
+> a += 1.
+| a += a / 2.
+
+Changes
+=======
+a = 2.0.
+
+> trace a
+
+a = 2.0
+|
+├─ += 1
+│
+│ a += 1.
+│
+└─ += 1.0
+
+ a += (a=2.0 / 2)=1.0.
+ |
+ └─ a = 2.0
+ |
+ └─ continue as before (cyclic structure, will continue forever)
+
+
+> :- backchain f/1.
+| f(X) := f(X-1) + f(X-2) for X > 1.
+| f(1) := 1.
+| f(0) := 1.
+| b := f(3).
+
+Changes
+=======
+b = 3.
+
+> trace b
+
+b = 3
+|
+└─ := 3
+
+ b := f(3)=3.
+ |
+ └─ f(3) = 3
+ |
+ └─ := 3
+
+ f(X=3) := (f((X=3 - 1)=2)=2 + f((X=3 - 2)=1)=1)=3,
+ for ((X=3 > 1)=true) = (&true=true).
+ |
+ ├─ f(1) = 1
+ │ |
+ │ └─ := 1
+ │
+ │ f(1) := 1.
+ │
+ └─ f(2) = 2
+ |
+ └─ := 2
+
+ f(X=2) := (f((X=2 - 1)=1)=1 + f((X=2 - 2)=0)=1)=2,
+ for ((X=2 > 1)=true) = (&true=true).
+ |
+ ├─ f(0) = 1
+ │ |
+ │ └─ := 1
+ │
+ │ f(0) := 1.
+ │
+ └─ f(1) = 1
+ |
+ └─ continue as before (shared structure)
+
+> :- backchain foo/1.
+| :- backchain bar/2.
+| foo(X) = X+1.
+| bar(A,B) += foo(A)*B.
+| bar(A,B) += A*foo(B).
+
+> trace bar(10,10)
+
+bar(10,10) = 220
+|
+├─ += 110
+│
+│ bar(A=10, B=10) += (foo(A=10)=11 * B=10)=110.
+│ |
+│ └─ foo(10) = 11
+│ |
+│ └─ = 11
+│
+│ foo(X=10) = (X=10 + 1)=11.
+│
+└─ += 110
+
+ bar(A=10, B=10) += (A=10 * foo(B=10)=11)=110.
+ |
+ └─ foo(10) = 11
+ |
+ └─ continue as before (shared structure)