···1111 let upshiftSubstCodom = Term.upshift
1212 let substituteSubstCodom = Term.substitute
1313 let mapTerms = (t: Term.t, f: Term.t => Term.t): Term.t => f(t)
1414+ let ghostJudgment = Term.ghostTerm
1415}
15161617module SExpJ = Make(SExp)
+8-7
tests/HOTermTest.res
···145145})
146146147147zoraBlock("unify test", t => {
148148+ let testUnifyFail = Util.testUnifyFailString
148149 t->block("symbols", t => {
149150 let x = "x"
150151 let y = "y"
151152 t->testUnify(x, x)
152152- t->Util.testUnifyFail(y, x)
153153- t->Util.testUnifyFail(x, y)
153153+ t->testUnifyFail(y, x)
154154+ t->testUnifyFail(x, y)
154155 })
155156 t->block("applications", t => {
156157 let ab = "(a b)"
157158 let cd = "(c d)"
158159 t->testUnify(ab, ab)
159160 t->testUnify(cd, cd)
160160- t->Util.testUnifyFail(ab, cd)
161161- t->Util.testUnifyFail(cd, ab)
161161+ t->testUnifyFail(ab, cd)
162162+ t->testUnifyFail(cd, ab)
162163 })
163164 t->block("flex-rigid", t => {
164165 let x = "?0"
···278279 let a = "(x. ?0 x)"
279280 let b = "(x. f (?0 x))"
280281 // ?0 occurs in the rigid term on the right → should not unify
281281- t->Util.testUnifyFail(a, b)
282282+ t->testUnifyFail(a, b)
282283 })
283284 t->block("no capture", t => {
284285 let a = "(x. ?0)"
285286 let b = "(x. x)"
286287 // Should fail: it cannot capture the bound variable.
287287- t->Util.testUnifyFail(a, b)
288288+ t->testUnifyFail(a, b)
288289 })
289290 t->block("eta", t => {
290291 t->testUnify(
···340341 let a = "(Nat (S ?6))"
341342 let b = "(Nat (S (S \\0)))"
342343 let c = "(Nat (S (?6 \\0)))"
343343- t->Util.testUnifyFail(a, b)
344344+ t->testUnifyFail(a, b)
344345 t->testUnify(c, b, ~subst=emptySubst->substAdd(6, t->Util.parse("(x. S \\0)")))
345346 })
346347 t->block("tests from induction examples", _t => {
+14-8
tests/SExpTest.res
···5050 let comp2 = parse("(x a y)")
5151 let schema1 = parse("?1()")
5252 let schemaComp = parse("(?1() a ?2())")
5353- t->block("var eq", t => t->Util.testUnify(x, x, [Map.make()]))
5454- t->block("var neq", t => t->Util.testUnify(x, y, []))
5555- t->block("comp eq", t => t->Util.testUnify(comp1, comp1, [Map.make()]))
5656- t->block("comp neq", t => t->Util.testUnify(comp1, comp2, []))
5757- t->block("schema var", t => t->Util.testUnify(schema1, x, [Map.fromArray([(1, x)])]))
5858- t->block("schema comp", t => t->Util.testUnify(schema1, comp2, [Map.fromArray([(1, comp2)])]))
5353+ t->block("var eq", t => t->Util.testUnify(x, x, ~expect=[Map.make()]))
5454+ t->block("var neq", t => t->Util.testUnify(x, y, ~expect=[]))
5555+ t->block("comp eq", t => t->Util.testUnify(comp1, comp1, ~expect=[Map.make()]))
5656+ t->block("comp neq", t => t->Util.testUnify(comp1, comp2, ~expect=[]))
5757+ t->block("schema var", t => t->Util.testUnify(schema1, x, ~expect=[Map.fromArray([(1, x)])]))
5858+ t->block("schema comp", t =>
5959+ t->Util.testUnify(schema1, comp2, ~expect=[Map.fromArray([(1, comp2)])])
6060+ )
5961 t->block("comp-schema comp eq", t => {
6060- t->Util.testUnify(schemaComp, comp2, [Map.fromArray([(1, x), (2, y)])])
6262+ t->Util.testUnify(schemaComp, comp2, ~expect=[Map.fromArray([(1, x), (2, y)])])
6163 })
6264 t->block("comp-schema comp neq", t => {
6363- t->Util.testUnify(schemaComp, comp1, [])
6565+ t->Util.testUnify(schemaComp, comp1, ~expect=[])
6666+ })
6767+ t->block("ghost", t => {
6868+ t->Util.testUnifyFail(x, SExp.ghostTerm)
6969+ t->Util.testUnify(schema1, SExp.ghostTerm)
6470 })
6571})
+32-19
tests/StringTermTest.res
···4545 let b = parse(`"b"`)
4646 let x = parse(`"?1()"`)
4747 let y = parse(`"?2()"`)
4848+ t->block("ghost", t => {
4949+ t->Util.testUnifyFail(a, StringTerm.ghostTerm)
5050+ t->Util.testUnify(x, StringTerm.ghostTerm)
5151+ t->Util.testUnify([x, y, x]->Array.flat, StringTerm.ghostTerm)
5252+ })
4853 t->block("schematics on at most one side", t => {
4949- t->Util.testUnify(a, a, [Map.make()])
5050- t->Util.testUnify(x, a, [Map.fromArray([(1, a)])])
5151- t->Util.testUnify(a, x, [Map.fromArray([(1, a)])])
5454+ t->Util.testUnify(a, a, ~expect=[Map.make()])
5555+ t->Util.testUnify(x, a, ~expect=[Map.fromArray([(1, a)])])
5656+ t->Util.testUnify(a, x, ~expect=[Map.fromArray([(1, a)])])
52575358 let xy = parse(`"?1() ?2()"`)
5459 let ab = parse(`"a b"`)
5555- t->Util.testUnify(x, ab, [Map.fromArray([(1, ab)])])
6060+ t->Util.testUnify(x, ab, ~expect=[Map.fromArray([(1, ab)])])
5661 t->Util.testUnify(
5762 xy,
5863 ab,
5959- [
6464+ ~expect=[
6065 Map.fromArray([(1, []), (2, ab)]),
6166 Map.fromArray([(1, a), (2, b)]),
6267 Map.fromArray([(1, ab), (2, [])]),
6368 ],
6469 )
65706666- t->Util.testUnify(parse(`"?1() b ?2()"`), ab, [Map.fromArray([(1, a), (2, [])])])
7171+ t->Util.testUnify(parse(`"?1() b ?2()"`), ab, ~expect=[Map.fromArray([(1, a), (2, [])])])
6772 t->Util.testUnify(
6873 parse(`"?1() ?2() b"`),
6974 ab,
7070- [Map.fromArray([(1, []), (2, a)]), Map.fromArray([(1, a), (2, [])])],
7575+ ~expect=[Map.fromArray([(1, []), (2, a)]), Map.fromArray([(1, a), (2, [])])],
7176 )
7277 t->Util.testUnify(
7378 parse(`"a ?1() ?2()"`),
7479 ab,
7575- [Map.fromArray([(1, []), (2, b)]), Map.fromArray([(1, b), (2, [])])],
8080+ ~expect=[Map.fromArray([(1, []), (2, b)]), Map.fromArray([(1, b), (2, [])])],
7681 )
77827883 let xax = parse(`"?1() a ?1()"`)
7979- t->Util.testUnify(xax, parse(`"a"`), [Map.fromArray([(1, [])])])
8080- t->Util.testUnify(xax, parse(`"a a a"`), [Map.fromArray([(1, a)])])
8181- t->Util.testUnify(xax, parse(`"a b a a b"`), [Map.fromArray([(1, parse(`"a b"`))])])
8484+ t->Util.testUnify(xax, parse(`"a"`), ~expect=[Map.fromArray([(1, [])])])
8585+ t->Util.testUnify(xax, parse(`"a a a"`), ~expect=[Map.fromArray([(1, a)])])
8686+ t->Util.testUnify(xax, parse(`"a b a a b"`), ~expect=[Map.fromArray([(1, parse(`"a b"`))])])
8287 })
83888489 t->block("schematics appearing at most twice", t => {
8585- t->Util.testUnify(x, x, [Map.fromArray([(1, [])])])
8686- t->Util.testUnify(x, y, [Map.fromArray([(1, []), (2, [])])])
9090+ t->Util.testUnify(x, x, ~expect=[Map.fromArray([(1, [])])])
9191+ t->Util.testUnify(x, y, ~expect=[Map.fromArray([(1, []), (2, [])])])
87928888- t->Util.testUnify(a, parse(`"?1() a"`), [Map.fromArray([(1, [])])])
9393+ t->Util.testUnify(a, parse(`"?1() a"`), ~expect=[Map.fromArray([(1, [])])])
8994 t->Util.testUnify(
9095 parse(`"?1() a"`),
9196 parse(`"a ?1()"`),
9292- [
9797+ ~expect=[
9398 Map.fromArray([(1, [])]),
9499 Map.fromArray([(1, parse(`"a"`))]),
95100 Map.fromArray([(1, parse(`"a a"`))]),
···97102 Map.fromArray([(1, parse(`"a a a a"`))]),
98103 ],
99104 )
100100- t->Util.testUnify(parse(`"a ?1()"`), parse(`"?2() b`), [Map.fromArray([(1, b), (2, a)])])
101101- t->Util.testUnify(parse(`"a ?1() a"`), parse(`"?2() b a"`), [Map.fromArray([(1, b), (2, a)])])
105105+ t->Util.testUnify(
106106+ parse(`"a ?1()"`),
107107+ parse(`"?2() b`),
108108+ ~expect=[Map.fromArray([(1, b), (2, a)])],
109109+ )
110110+ t->Util.testUnify(
111111+ parse(`"a ?1() a"`),
112112+ parse(`"?2() b a"`),
113113+ ~expect=[Map.fromArray([(1, b), (2, a)])],
114114+ )
102115 t->Util.testUnify(
103116 parse(`"b ?1() a"`),
104117 parse(`"?2() a ?1()"`),
105105- [Map.fromArray([(1, a), (2, b)]), Map.fromArray([(1, []), (2, b)])],
118118+ ~expect=[Map.fromArray([(1, a), (2, b)]), Map.fromArray([(1, []), (2, b)])],
106119 )
107120 t->Util.testUnify(
108121 parse(`"a b ?1() c ?2()"`),
109122 parse(`"?2() c ?1() b a"`),
110110- [Map.fromArray([(1, a), (2, parse(`"a b a"`))])],
123123+ ~expect=[Map.fromArray([(1, a), (2, parse(`"a b a"`))])],
111124 )
112125 })
113126})
+32-18
tests/TestUtil.res
···9898 ss->Array.map(t => Term.prettyPrintSubst(t, ~scope=[]))->Util.showArray
9999 }
100100101101- let testUnify = (t: Zora.t, t1: Term.t, t2: Term.t, expect: array<Term.subst>, ~msg=?) => {
102102- let expect = Seq.fromArray(expect)
101101+ let testUnify = (
102102+ t: Zora.t,
103103+ t1: Term.t,
104104+ t2: Term.t,
105105+ ~expect: option<array<Term.subst>>=?,
106106+ ~msg=?,
107107+ ) => {
103108 let res = Term.unify(t1, t2)->Seq.take(10)
104104- // Console.log(
105105- // `t1: ${Term.prettyPrint(t1, ~scope=[])} t2:${Term.prettyPrint(t2, ~scope=[])}\nsubsts: ${res
106106- // ->Seq.map(t => Term.prettyPrintSubst(t, ~scope=[]))
107107- // ->Seq.join(",")}\n`,
108108- // )
109109- let noMatches =
110110- expect
111111- ->Seq.filter(sub1 => Seq.find(res, sub2 => Term.substEqual(sub1, sub2))->Option.isNone)
112112- ->Seq.map(t => Term.prettyPrintSubst(t, ~scope=[]))
113113- ->Seq.toArray
114114- let msg = msg->Option.getOr("each substitution in `expect` should have a match in solutions")
115115- t->equal(noMatches, [], ~msg)
109109+ switch expect {
110110+ | Some(expect) => {
111111+ let expect = Seq.fromArray(expect)
112112+ let noMatches =
113113+ expect
114114+ ->Seq.filter(sub1 => Seq.find(res, sub2 => Term.substEqual(sub1, sub2))->Option.isNone)
115115+ ->Seq.map(t => Term.prettyPrintSubst(t, ~scope=[]))
116116+ ->Seq.toArray
117117+ let msg =
118118+ msg->Option.getOr("each substitution in `expect` should have a match in solutions")
119119+ t->equal(noMatches, [], ~msg)
120120+ }
121121+ | None => {
122122+ let msg = msg->Option.getOr("expect non-nil substitution sequence")
123123+ t->ok(res->Seq.head->Option.isSome, ~msg)
124124+ }
125125+ }
116126 }
117127118118- let testUnifyFail = (t: Zora.t, at: string, bt: string, ~msg=?) => {
119119- let gen = Term.makeGen()
120120- let (a, _) = Term.parse(at, ~scope=[], ~gen)->Result.getExn
121121- let (b, _) = Term.parse(bt, ~scope=[], ~gen)->Result.getExn
128128+ let testUnifyFail = (t: Zora.t, a: Term.t, b: Term.t, ~msg=?) => {
122129 let res = Term.unify(a, b)
123130 if res->Seq.length != 0 {
124131 t->fail(~msg="unification succeeded: " ++ stringifyExn(a) ++ " and " ++ stringifyExn(b))
125132 } else {
126133 t->ok(true, ~msg=msg->Option.getOr("unification failed"))
127134 }
135135+ }
136136+137137+ let testUnifyFailString = (t: Zora.t, at: string, bt: string, ~msg=?) => {
138138+ let gen = Term.makeGen()
139139+ let (a, _) = Term.parse(at, ~scope=[], ~gen)->Result.getExn
140140+ let (b, _) = Term.parse(bt, ~scope=[], ~gen)->Result.getExn
141141+ testUnifyFail(t, a, b, ~msg?)
128142 }
129143}