Skip to content

Commit

Permalink
Interpreted tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
corywalker committed Jul 10, 2017
1 parent 2587567 commit 7650047
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 14 deletions.
79 changes: 79 additions & 0 deletions expreduce/builtin.go
Expand Up @@ -35,6 +35,85 @@ type Definition struct {
Default string
}

func ToTestInstructions(tc *Expression) []TestInstruction {
instructions := []TestInstruction{}
for _, tiEx := range tc.Parts[1:] {
if st, isSt := HeadAssertion(tiEx, "ESameTest"); isSt {
if len(st.Parts) != 3 {
log.Fatalf("Invalid test case: %v\n", tiEx)
continue
}
instructions = append(instructions, &SameTestEx{
st.Parts[1], st.Parts[2]})
continue
}
if comment, isComment := HeadAssertion(tiEx, "EComment"); isComment {
if len(comment.Parts) != 2 {
log.Fatalf("Invalid test case: %v\n", tiEx)
continue
}
comStr, comIsStr := comment.Parts[1].(*String)
if !comIsStr {
log.Fatalf("Invalid test case: %v\n", tiEx)
continue
}
instructions = append(instructions, &TestComment{
comStr.Val})
continue
}
log.Fatalf("Invalid test case: %v\n", tiEx)
}
return instructions
}

func (def *Definition) AnnotateWithDynamicTests(es *EvalState) {
tests, testsDef := es.GetSymDef("Tests`" + def.Name)
if !testsDef {
return
}
testsList, testsIsList := HeadAssertion(tests, "List")
if !testsIsList {
return
}
for _, testCol := range testsList.Parts[1:] {
testColExpr, testColIsExpr := testCol.(*Expression)
if !testColIsExpr {
continue
}
headSym, headIsSym := testColExpr.Parts[0].(*Symbol)
if !headIsSym {
continue
}
if (headSym.Name == "ESimpleExamples") {
def.SimpleExamples = append(
def.SimpleExamples,
ToTestInstructions(testColExpr)...)
} else if (headSym.Name == "EFurtherExamples") {
def.FurtherExamples = append(
def.FurtherExamples,
ToTestInstructions(testColExpr)...)
} else if (headSym.Name == "ETests") {
def.Tests = append(
def.Tests,
ToTestInstructions(testColExpr)...)
} else if (headSym.Name == "EKnownFailures") {
def.KnownFailures = append(
def.KnownFailures,
ToTestInstructions(testColExpr)...)
} else if (headSym.Name == "EKnownDangerous") {
def.KnownDangerous = append(
def.KnownDangerous,
ToTestInstructions(testColExpr)...)
} else {
log.Fatalf("Invalid test collection: %v\n", testColExpr)
}
}
}

func (def *Definition) AnnotateWithDynamic(es *EvalState) {
def.AnnotateWithDynamicTests(es)
}

type NamedDefSet struct {
Name string
Defs []Definition
Expand Down
4 changes: 4 additions & 0 deletions expreduce/builtin_arithmetic.go
Expand Up @@ -603,5 +603,9 @@ func getArithmeticDefinitions() (defs []Definition) {
&SameTest{"1440", "Product[a + b, {a, 1, 2}, {b, 1, 3}]"},
},
})
defs = append(defs, Definition{
Name: "Abs",
Usage: "`Abs[expr]` calculates the absolute value of `expr`.",
})
return
}
12 changes: 12 additions & 0 deletions expreduce/builtin_power.go
Expand Up @@ -418,5 +418,17 @@ func GetPowerDefinitions() (defs []Definition) {
&SameTest{"{-(2800301/67344500),1-2 x+x^3}", "FactorTermsList[(-2800301/538756 + (2800301*x)/269378 - (2800301*x^3)/538756)/125]"},
},
})
/*defs = append(defs, Definition{
Name: "PolynomialGCD",
Usage: "`PolynomialGCD[a, b]` calculates the polynomial GCD of `a` and `b`.",
SimpleExamples: []TestInstruction{
&SameTest{"2+3 x+x^2", "PolynomialGCD[8 + 22*x + 21*x^2 + 8*x^3 + x^4, 6 + 11*x + 6*x^2 + x^3]"},
&SameTest{"2+x^2", "PolynomialGCD[-4 + x^4, 4 + 4*x^2 + x^4]"},
&SameTest{"1-2 x+x^3", "PolynomialGCD[5 - 12*x + 4*x^2 + 5*x^3 - x^4 - 2*x^5 + x^7, 3 - 6*x - 7*x^2 + 17*x^3 + x^4 - 9*x^5 + x^7]"},
&SameTest{"1+x", "PolynomialGCD[6 + 7*x + x^2, -6 - 5*x + x^2]"},
&SameTest{"1", "PolynomialGCD[3 + 6*x + 2*x^2, 1 + 2*x]"},
&SameTest{"3+x", "PolynomialGCD[6 - 28*x - 19*x^2 + 3*x^3 + 2*x^4, -18 - 9*x + 2*x^2 + x^3]"},
},
})*/
return
}
7 changes: 7 additions & 0 deletions expreduce/builtin_system.go
Expand Up @@ -627,5 +627,12 @@ func GetSystemDefinitions() (defs []Definition) {
&SameTest{"{t$9,2,10}", "$ModuleNumber=8;t$3=test;Module[{t,j:=2},{t,j,$ModuleNumber}]"},
},
})
defs = append(defs, Definition{
Name: "ESameTest",
OmitDocumentation: true,
ExpreduceSpecific: true,
Bootstrap: true,
Attributes: []string{"HoldAll"},
})
return
}
3 changes: 2 additions & 1 deletion expreduce/cas_test.go
Expand Up @@ -32,11 +32,12 @@ func TestIncludedModules(t *testing.T) {
}
fmt.Printf("Testing module %s\n", defSet.Name)
for _, def := range defSet.Defs {
es := NewEvalState()
def.AnnotateWithDynamic(es)
td := TestDesc{
module: defSet.Name,
def: def,
}
es := NewEvalState()
if *deftimings {
es.DebugOn(logging.ERROR)
}
Expand Down
4 changes: 2 additions & 2 deletions expreduce/evalstate.go
Expand Up @@ -70,7 +70,7 @@ func (this *EvalState) Load(def Definition) {

func InitCAS(es *EvalState) {
// System initialization
data := MustAsset("resources/init.er")
data := MustAsset("resources/init.m")
EvalInterp(string(data), es)
EvalInterp(fmt.Sprintf("$Path = {\"%s\"}", "."), es)
}
Expand Down Expand Up @@ -98,7 +98,7 @@ func (es *EvalState) Init(loadAllDefs bool) {
es.Load(def)
}
}
data, err := Asset(fmt.Sprintf("resources/%v.er", defSet.Name))
data, err := Asset(fmt.Sprintf("resources/%v.m", defSet.Name))
if err == nil {
EvalInterp(string(data), es)
}
Expand Down
17 changes: 17 additions & 0 deletions expreduce/resources/arithmetic.m
@@ -0,0 +1,17 @@
Abs[a_?NumberQ] := If[a<0,-a,a];
Abs[-a_] := Abs[a];
Attributes[Abs] = {Listable, NumericFunction, Protected, ReadProtected};
Tests`Abs = {
ESimpleExamples[
ESameTest[5.2, Abs[-5.2]],
ESameTest[5, Abs[5]],
EComment["Absolute values of unspecified inputs will be left unevaluated:"],
ESameTest[Abs[a], Abs[a]],
EComment["But sometimes simplifications can occur:"],
ESameTest[Abs[Sin[x]], Abs[-Sin[x]]]
], ETests[
ESameTest[0, Abs[0]],
ESameTest[Abs[x^a], Abs[-x^a]],
ESameTest[Abs[x^(a + b)], Abs[-x^(a + b)]]
]
};
File renamed without changes.
File renamed without changes.
@@ -1,5 +1,3 @@
Abs[a_?NumberQ] := If[a<0,-a,a];

(* Eventually we should not need the rest___ term. GCD is Flat. *)
GCD[Rational[a_, b_], Rational[c_, d_], rest___] :=
GCD[GCD[a*d, c*b]/(b*d), rest];
Expand Down
32 changes: 32 additions & 0 deletions expreduce/resources/power.er → expreduce/resources/power.m
Expand Up @@ -91,3 +91,35 @@
{c, toFactor/c // Expand}
];
Attributes[FactorTermsList] = {Protected};

(*PolySubresultantGCD[inA_, inB_, inX_] :=
Module[{u = inA, v = inB, x = inX, h, delta, beta, newU, newV, i},
Print[u];
Print[v];
Print[x];
h = 1;
i = 1;
While[v =!= 0 && i < 20,
delta = Exponent[u, x] - Exponent[v, x];
Print[delta];
beta = (-1)^(delta + 1)*Exponent[u, x]*h^delta;
Print[beta];
h = h*(Exponent[v, x]/h)^delta;
Print[h];
newU = v;
newV = PolynomialRemainder[u, v, x]/beta;
Print[newV];
u = newU;
v = newV;
i = i + 1;
];
If[Exponent[u, x] == 0, 1, u]
];*)
(* doesn't work with rational functions yet. *)

(* Looks like prefactored inputs remain factored. *)
(*PolynomialGCD[inA_, inB_] :=
FactorTermsList[
PolySubresultantGCD[inA, inB, Variables[inA][[1]]]][[2]];
Attributes[PolynomialGCD] = {Listable, Protected};*)
File renamed without changes.
27 changes: 19 additions & 8 deletions expreduce/testing.go
Expand Up @@ -67,9 +67,20 @@ func (this *TestComment) Run(t *testing.T, es *EvalState, td TestDesc) bool {
return true
}

func CasTestInner(es *EvalState, out string, in string, test bool, desc string) (succ bool, s string) {
inTree := EvalInterp(in, es).Eval(es)
outTree := EvalInterp(out, es).Eval(es)
type SameTestEx struct {
Out Ex
In Ex
}

func (this *SameTestEx) Run(t *testing.T, es *EvalState, td TestDesc) bool {
succ, s := CasTestInner(es, this.Out, this.In, this.In.String(), true, td.desc)
assert.True(t, succ, s)
return succ
}

func CasTestInner(es *EvalState, out Ex, in Ex, inStr string, test bool, desc string) (succ bool, s string) {
inTree := in.Eval(es).Eval(es)
outTree := out.Eval(es).Eval(es)
theTestTree := NewExpression([]Ex{
&Symbol{"SameQ"},
NewExpression([]Ex{&Symbol{"Hold"}, inTree}),
Expand All @@ -89,7 +100,7 @@ func CasTestInner(es *EvalState, out string, in string, test bool, desc string)
buffer.WriteString(outTree.String())
buffer.WriteString(")")
buffer.WriteString("\n\tInput was: ")
buffer.WriteString(in)
buffer.WriteString(inStr)
if len(desc) != 0 {
buffer.WriteString("\n\tDesc: ")
buffer.WriteString(desc)
Expand All @@ -102,25 +113,25 @@ func CasTestInner(es *EvalState, out string, in string, test bool, desc string)
}

func CasAssertSame(t *testing.T, es *EvalState, out string, in string) bool {
succ, s := CasTestInner(es, out, in, true, "")
succ, s := CasTestInner(es, Interp(out), Interp(in), in, true, "")
assert.True(t, succ, s)
return succ
}

func CasAssertDiff(t *testing.T, es *EvalState, out string, in string) bool {
succ, s := CasTestInner(es, out, in, false, "")
succ, s := CasTestInner(es, Interp(out), Interp(in), in, false, "")
assert.True(t, succ, s)
return succ
}

func CasAssertDescSame(t *testing.T, es *EvalState, out string, in string, desc string) bool {
succ, s := CasTestInner(es, out, in, true, desc)
succ, s := CasTestInner(es, Interp(out), Interp(in), in, true, desc)
assert.True(t, succ, s)
return succ
}

func CasAssertDescDiff(t *testing.T, es *EvalState, out string, in string, desc string) bool {
succ, s := CasTestInner(es, out, in, false, desc)
succ, s := CasTestInner(es, Interp(out), Interp(in), in, false, desc)
assert.True(t, succ, s)
return succ
}
2 changes: 1 addition & 1 deletion expreduce/testing_test.go
Expand Up @@ -12,7 +12,7 @@ func TestTesting(t *testing.T) {
es := NewEvalState()

CasAssertSame(t, es, " 1 ", " 1")
succ, s := CasTestInner(es, " 1. ", "1 ", true, "")
succ, s := CasTestInner(es, Interp(" 1. "), Interp("1 "), " 1. ", true, "")
assert.False(t, succ, s)
CasAssertSame(t, es, "5.5", "1+1.5+3")
CasAssertDiff(t, es, "5.6", "1+1.5+3")
Expand Down

0 comments on commit 7650047

Please sign in to comment.