From 9edb06c5c141f4a214e44310fbb979c50e041422 Mon Sep 17 00:00:00 2001 From: Tim Vieira Date: Fri, 5 Jul 2013 19:03:31 -0400 Subject: [PATCH] use doctester --- src/Dyna/Backend/Python/dyna-doctest.py | 22 +++-- src/Dyna/Backend/Python/repl.py | 2 +- test/repl/aggregator-conflict | 9 -- ...ict.expect => aggregator-conflict.dynadoc} | 9 +- test/repl/colon-equals.doctest | 61 ++++++++++++ test/repl/{ => data}/english.gr | 0 test/repl/{ => data}/english.par | 0 test/repl/{ => data}/english.sen | 0 test/repl/late-aggregator-assignment | 15 --- ...ect => late-aggregator-assignment.dynadoc} | 18 ++-- test/repl/load.bash | 10 -- test/repl/load.dyna | 23 ----- test/repl/load.dynadoc | 63 ++++++++++++ test/{misc => repl}/retract-bc.dynadoc | 0 test/repl/retract-rule | 17 ---- test/repl/retract-rule.expect | 44 --------- test/repl/trace.dynadoc | 99 +++++++++++++++++++ 17 files changed, 255 insertions(+), 137 deletions(-) delete mode 100755 test/repl/aggregator-conflict rename test/repl/{aggregator-conflict.expect => aggregator-conflict.dynadoc} (88%) create mode 100644 test/repl/colon-equals.doctest rename test/repl/{ => data}/english.gr (100%) rename test/repl/{ => data}/english.par (100%) rename test/repl/{ => data}/english.sen (100%) delete mode 100755 test/repl/late-aggregator-assignment rename test/repl/{late-aggregator-assignment.expect => late-aggregator-assignment.dynadoc} (74%) delete mode 100755 test/repl/load.bash delete mode 100644 test/repl/load.dyna create mode 100644 test/repl/load.dynadoc rename test/{misc => repl}/retract-bc.dynadoc (100%) delete mode 100755 test/repl/retract-rule delete mode 100644 test/repl/retract-rule.expect create mode 100644 test/repl/trace.dynadoc diff --git a/src/Dyna/Backend/Python/dyna-doctest.py b/src/Dyna/Backend/Python/dyna-doctest.py index 0d7a16f..6522705 100755 --- a/src/Dyna/Backend/Python/dyna-doctest.py +++ b/src/Dyna/Backend/Python/dyna-doctest.py @@ -12,29 +12,37 @@ def extract(code): 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*': @@ -48,15 +56,15 @@ def run(code): 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 @@ -67,7 +75,7 @@ def run(code): print green % 'PASS!' print else: - print red % '%s errors' % len(errors) + print yellow % '>>>', red % '%s errors' % errors print sys.exit(1) diff --git a/src/Dyna/Backend/Python/repl.py b/src/Dyna/Backend/Python/repl.py index d3a3e09..ad65ae3 100644 --- a/src/Dyna/Backend/Python/repl.py +++ b/src/Dyna/Backend/Python/repl.py @@ -250,7 +250,7 @@ class REPL(cmd.Cmd, object): 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): diff --git a/test/repl/aggregator-conflict b/test/repl/aggregator-conflict deleted file mode 100755 index fb02378..0000000 --- a/test/repl/aggregator-conflict +++ /dev/null @@ -1,9 +0,0 @@ -#!/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 diff --git a/test/repl/aggregator-conflict.expect b/test/repl/aggregator-conflict.dynadoc similarity index 88% rename from test/repl/aggregator-conflict.expect rename to test/repl/aggregator-conflict.dynadoc index 1bc2e60..f5dd087 100644 --- a/test/repl/aggregator-conflict.expect +++ b/test/repl/aggregator-conflict.dynadoc @@ -1,9 +1,12 @@ -> > + +> a += 1. + Changes ======= a = 1. -> DynaCompilerError: +> a. +DynaCompilerError: Encountered error in input program: Conflicting aggregators; rule uses '|=' for a/0 but I had been lead to expect '+='. @@ -11,5 +14,3 @@ Everything was syntactically valid, but we could not see it through. new rule(s) were not added to program. - -> exit diff --git a/test/repl/colon-equals.doctest b/test/repl/colon-equals.doctest new file mode 100644 index 0000000..377fa4a --- /dev/null +++ b/test/repl/colon-equals.doctest @@ -0,0 +1,61 @@ +% 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. diff --git a/test/repl/english.gr b/test/repl/data/english.gr similarity index 100% rename from test/repl/english.gr rename to test/repl/data/english.gr diff --git a/test/repl/english.par b/test/repl/data/english.par similarity index 100% rename from test/repl/english.par rename to test/repl/data/english.par diff --git a/test/repl/english.sen b/test/repl/data/english.sen similarity index 100% rename from test/repl/english.sen rename to test/repl/data/english.sen diff --git a/test/repl/late-aggregator-assignment b/test/repl/late-aggregator-assignment deleted file mode 100755 index 415806f..0000000 --- a/test/repl/late-aggregator-assignment +++ /dev/null @@ -1,15 +0,0 @@ -#!/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 diff --git a/test/repl/late-aggregator-assignment.expect b/test/repl/late-aggregator-assignment.dynadoc similarity index 74% rename from test/repl/late-aggregator-assignment.expect rename to test/repl/late-aggregator-assignment.dynadoc index 6321d06..ad70e8f 100644 --- a/test/repl/late-aggregator-assignment.expect +++ b/test/repl/late-aggregator-assignment.dynadoc @@ -1,30 +1,34 @@ -> > > + +> 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 diff --git a/test/repl/load.bash b/test/repl/load.bash deleted file mode 100755 index b6021f4..0000000 --- a/test/repl/load.bash +++ /dev/null @@ -1,10 +0,0 @@ -#!/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()' \ - "$@" diff --git a/test/repl/load.dyna b/test/repl/load.dyna deleted file mode 100644 index 860a3dd..0000000 --- a/test/repl/load.dyna +++ /dev/null @@ -1,23 +0,0 @@ -% 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)). diff --git a/test/repl/load.dynadoc b/test/repl/load.dynadoc new file mode 100644 index 0000000..1036591 --- /dev/null +++ b/test/repl/load.dynadoc @@ -0,0 +1,63 @@ +> :- 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* diff --git a/test/misc/retract-bc.dynadoc b/test/repl/retract-bc.dynadoc similarity index 100% rename from test/misc/retract-bc.dynadoc rename to test/repl/retract-bc.dynadoc diff --git a/test/repl/retract-rule b/test/repl/retract-rule deleted file mode 100755 index 25e039a..0000000 --- a/test/repl/retract-rule +++ /dev/null @@ -1,17 +0,0 @@ -#!/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 diff --git a/test/repl/retract-rule.expect b/test/repl/retract-rule.expect deleted file mode 100644 index 2e477ba..0000000 --- a/test/repl/retract-rule.expect +++ /dev/null @@ -1,44 +0,0 @@ -> > -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 diff --git a/test/repl/trace.dynadoc b/test/repl/trace.dynadoc new file mode 100644 index 0000000..4444362 --- /dev/null +++ b/test/repl/trace.dynadoc @@ -0,0 +1,99 @@ +> 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) -- 2.50.1