···1717let strip: t => (t, array<t>)
1818let app: (t, array<t>) => t
1919let mkvars: int => array<t>
2020+let mapTerms: (t, t => t) => t
2021// exposed for testing purposes
2122exception UnifyFail(string)
2223let substAdd: (subst, schematic, t) => subst
+1-3
src/HOTermJView.resi
···11-include Signatures.JUDGMENT_VIEW
22- with module Term := HOTerm
33- and module Judgment := TermAsJudgment.HOTermJ
11+include Signatures.JUDGMENT_VIEW with module Term := HOTerm and module Judgment := HOTerm
+13-17
src/HOTermMethod.res
···22open Method
3344module MakeRewriteHOTerm = (
55- Judgment: JUDGMENT with module Term := HOTerm and type subst = HOTerm.subst and type t = HOTerm.t,
55+ Judgment: JUDGMENT with module Term := HOTerm and type t = HOTerm.t,
66 Config: {
77 let keyword: string
88 let reversed: bool
···43434444 type t<'a> = {
4545 equalityName: string,
4646- instantiation: array<Judgment.substCodom>,
4646+ instantiation: array<Term.t>,
4747 subgoal: 'a,
4848 }
4949···5757 }
5858 }
59596060- let substitute = (it: t<'a>, subst: Judgment.subst) => {
6060+ let substitute = (it: t<'a>, subst: Term.subst) => {
6161 {
6262 equalityName: it.equalityName,
6363- instantiation: it.instantiation->Array.map(t => t->Judgment.substituteSubstCodom(subst)),
6363+ instantiation: it.instantiation->Array.map(t => t->Judgment.substitute(subst)),
6464 subgoal: it.subgoal,
6565 }
6666 }
···7272 ~subprinter: ('a, ~scope: array<HOTerm.meta>, ~indentation: int=?) => string,
7373 ) => {
7474 let ind = String.repeat(" ", indentation)
7575- let args = it.instantiation->Array.map(t => Judgment.prettyPrintSubstCodom(t, ~scope))
7575+ let args = it.instantiation->Array.map(t => Term.prettyPrint(t, ~scope))
7676 let argsStr = if Array.length(args) > 0 {
7777 " " ++ Array.join(args, " ")
7878 } else {
···9898 let instantiation = []
9999 let it = ref(Error(""))
100100 while {
101101- it := Judgment.parseSubstCodom(cur.contents, ~scope, ~gen)
101101+ it := Term.parse(cur.contents, ~scope, ~gen)
102102 it.contents->Result.isOk
103103 } {
104104 let (val, rest) = it.contents->Result.getExn
···157157 }
158158159159 let apply = (ctx: Context.t, j: Judgment.t, gen: HOTerm.gen, f: Rule.t => 'a) => {
160160- let ret: Dict.t<(t<'a>, Judgment.subst)> = Dict.make()
160160+ let ret: Dict.t<(t<'a>, Term.subst)> = Dict.make()
161161162162 ctx
163163 ->Context.facts
···246246}
247247248248module Rewrite = (
249249- Judgment: JUDGMENT with module Term := HOTerm and type subst = HOTerm.subst and type t = HOTerm.t,
249249+ Judgment: JUDGMENT with module Term := HOTerm and type t = HOTerm.t,
250250) => MakeRewriteHOTerm(
251251 Judgment,
252252 {
···256256)
257257258258module RewriteReverse = (
259259- Judgment: JUDGMENT with module Term := HOTerm and type subst = HOTerm.subst and type t = HOTerm.t,
259259+ Judgment: JUDGMENT with module Term := HOTerm and type t = HOTerm.t,
260260) => MakeRewriteHOTerm(
261261 Judgment,
262262 {
···265265 },
266266)
267267268268-module ConstructorNeq = (
269269- Judgment: JUDGMENT with module Term := HOTerm and type subst = HOTerm.subst and type t = HOTerm.t,
270270-) => {
268268+module ConstructorNeq = (Judgment: JUDGMENT with module Term := HOTerm and type t = HOTerm.t) => {
271269 module Term = HOTerm
272270 module Rule = Rule.Make(HOTerm, Judgment)
273271 module Context = Context(HOTerm, Judgment)
···321319322320 let map = (it: t<'a>, _f: 'a => 'b): t<'b> => it
323321324324- let substitute = (it: t<'a>, _subst: Judgment.subst) => it
322322+ let substitute = (it: t<'a>, _subst: Term.subst) => it
325323326324 let prettyPrint = (_it: t<'a>, ~scope as _, ~indentation=0, ~subprinter as _) =>
327325 String.repeat(" ", indentation)->String.concat("constructor_neq")
···353351 }
354352}
355353356356-module ConstructorInj = (
357357- Judgment: JUDGMENT with module Term := HOTerm and type subst = HOTerm.subst and type t = HOTerm.t,
358358-) => {
354354+module ConstructorInj = (Judgment: JUDGMENT with module Term := HOTerm and type t = HOTerm.t) => {
359355 module Rule = Rule.Make(HOTerm, Judgment)
360356 module Context = Context(HOTerm, Judgment)
361357···370366371367 let map = (it: t<'a>, _f: 'a => 'b): t<'b> => it
372368373373- let substitute = (it: t<'a>, _subst: Judgment.subst) => it
369369+ let substitute = (it: t<'a>, _subst: HOTerm.subst) => it
374370375371 let prettyPrint = (it: t<'a>, ~scope as _, ~indentation=0, ~subprinter as _) =>
376372 String.repeat(" ", indentation)->String.concat(
+3-4
src/InductiveSet.res
···11open Signatures
22open Component
33-open Util
4354// InductiveSet is specific to HOTerm to allow pattern matching on term structure
65module Make = (
···5756 let generateInductionRule = (group: predicateGroup, allGroups: array<predicateGroup>): Rule.t => {
5857 let {name: str, arity: i} = group
5958 let numFormers = Array.length(allGroups)
6060- let groupIndex = mustFindIndex(allGroups, g => g.name == str && g.arity == i)
5959+ let groupIndex = Util.mustFindIndex(allGroups, g => g.name == str && g.arity == i)
61606261 let findFormerIndex = (name, arity) =>
6363- mustFindIndex(allGroups, g => g.name == name && g.arity == arity)
6262+ Util.mustFindIndex(allGroups, g => g.name == name && g.arity == arity)
64636564 let generateInductiveHypothesis = (premise: Rule.t, offset: int): option<Rule.t> => {
6665 let (head, args) = HOTerm.strip(premise.conclusion)
···8988 let (conclusionHead, conclusionArgs) = HOTerm.strip(constructorRule.conclusion)
9089 let typeIndex = switch conclusionHead {
9190 | Symbol({name}) => findFormerIndex(name, Array.length(conclusionArgs))
9292- | _ => throw(Unreachable("Constructor conclusion must have a Symbol head"))
9191+ | _ => throw(Util.Unreachable("Constructor conclusion must have a Symbol head"))
9392 }
94939594 {
···11-type rec t =
22- | Symbol({name: string})
33- | Compound({subexps: array<t>})
44- | Var({idx: int})
55- | Schematic({schematic: int, allowed: array<int>})
66- | Ghost
77-88-include Signatures.TERM
99- with type t := t
1010- and type meta = string
1111- and type schematic = int
1212- and type subst = Map.t<int, t>
+435
src/SExpFunc.res
···11+module type ATOM = {
22+ type t
33+ type subst = Map.t<int, t>
44+ let unify: (t, t, ~gen: ref<int>=?) => Seq.t<subst>
55+ let prettyPrint: (t, ~scope: array<string>) => string
66+ let parse: (string, ~scope: array<string>, ~gen: ref<int>=?) => result<(t, string), string>
77+ let substitute: (t, subst) => t
88+ let upshift: (t, int, ~from: int=?) => t
99+ // used for when trying to substitute a variable of the wrong type
1010+ let lowerVar: int => option<t>
1111+ let lowerSchematic: (int, array<int>) => option<t>
1212+ let substDeBruijn: (t, Map.t<int, t>, ~from: int=?, ~to: int) => t
1313+ let concrete: t => bool
1414+}
1515+1616+module IntCmp = Belt.Id.MakeComparable({
1717+ type t = int
1818+ let cmp = Pervasives.compare
1919+})
2020+2121+module Make = (Atom: ATOM): {
2222+ type rec t =
2323+ | Atom(Atom.t)
2424+ | Compound({subexps: array<t>})
2525+ | Var({idx: int})
2626+ | Schematic({schematic: int, allowed: array<int>})
2727+2828+ include Signatures.TERM
2929+ with type t := t
3030+ and type meta = string
3131+ and type schematic = int
3232+ and type subst = Map.t<int, t>
3333+ let mapTerms: (t, t => t) => t
3434+} => {
3535+ type rec t =
3636+ | Atom(Atom.t)
3737+ | Compound({subexps: array<t>})
3838+ | Var({idx: int})
3939+ | Schematic({schematic: int, allowed: array<int>})
4040+ module Atom = Atom
4141+ type meta = string
4242+ type schematic = int
4343+ type subst = Map.t<schematic, t>
4444+ let substEqual = Util.mapEqual
4545+ let mapSubst = Util.mapMapValues
4646+ let makeSubst = () => {
4747+ Map.make()
4848+ }
4949+ let equivalent = (a: t, b: t) => {
5050+ a == b
5151+ }
5252+ let reduce = (term: t) => term
5353+ let rec schematicsIn: t => Belt.Set.t<int, IntCmp.identity> = (it: t) =>
5454+ switch it {
5555+ | Schematic({schematic, _}) => Belt.Set.make(~id=module(IntCmp))->Belt.Set.add(schematic)
5656+ | Compound({subexps}) =>
5757+ subexps->Array.reduce(Belt.Set.make(~id=module(IntCmp)), (s, x) =>
5858+ Belt.Set.union(s, schematicsIn(x))
5959+ )
6060+ | _ => Belt.Set.make(~id=module(IntCmp))
6161+ }
6262+ let rec freeVarsIn: t => Belt.Set.t<int, IntCmp.identity> = (it: t) =>
6363+ switch it {
6464+ | Var({idx}) => Belt.Set.make(~id=module(IntCmp))->Belt.Set.add(idx)
6565+ | Compound({subexps}) =>
6666+ subexps->Array.reduce(Belt.Set.make(~id=module(IntCmp)), (s, x) =>
6767+ Belt.Set.union(s, freeVarsIn(x))
6868+ )
6969+ | _ => Belt.Set.make(~id=module(IntCmp))
7070+ }
7171+ let rec substitute = (term: t, subst: subst) =>
7272+ switch term {
7373+ | Compound({subexps}) => Compound({subexps: Array.map(subexps, x => substitute(x, subst))})
7474+ | Schematic({schematic, _}) =>
7575+ switch Map.get(subst, schematic) {
7676+ | None => term
7777+ | Some(found) => found
7878+ }
7979+ | Atom(name) => {
8080+ let symbolSubs =
8181+ subst
8282+ ->Map.entries
8383+ ->Iterator.toArray
8484+ ->Array.filterMap(((name, v)) =>
8585+ switch v {
8686+ | Atom(v) => Some((name, v))
8787+ | _ => None
8888+ }
8989+ )
9090+ ->Map.fromArray
9191+ Atom(name->Atom.substitute(symbolSubs))
9292+ }
9393+ | _ => term
9494+ }
9595+9696+ let combineSubst = (s: subst, t: subst) => {
9797+ let nu = Map.make()
9898+ Map.entries(s)->Iterator.forEach(opt =>
9999+ switch opt {
100100+ | None => ()
101101+ | Some((key, term)) => nu->Map.set(key, term->substitute(t))
102102+ }
103103+ )
104104+ Map.entries(t)->Iterator.forEach(opt =>
105105+ switch opt {
106106+ | None => ()
107107+ | Some((key, term)) => nu->Map.set(key, term->substitute(s))
108108+ }
109109+ )
110110+ nu
111111+ }
112112+ let emptySubst: subst = Map.make()
113113+ let singletonSubst: (int, t) => subst = (schematic, term) => {
114114+ let s = Map.make()
115115+ s->Map.set(schematic, term)
116116+ s
117117+ }
118118+ let rec unifyTerm = (a: t, b: t): Seq.t<subst> =>
119119+ switch (a, b) {
120120+ | (Atom(na), Atom(nb)) =>
121121+ Atom.unify(na, nb)->Seq.map(subst => subst->Util.mapMapValues(v => Atom(v)))
122122+ | (Compound({subexps: xa}), Compound({subexps: xb})) if Array.length(xa) == Array.length(xb) =>
123123+ unifyArray(Belt.Array.zip(xa, xb))
124124+ | (Var({idx: ia}), Var({idx: ib})) if ia == ib => Seq.once(emptySubst)
125125+ | (Schematic({schematic: sa, _}), Schematic({schematic: sb, _})) if sa == sb =>
126126+ Seq.once(emptySubst)
127127+ | (Schematic({schematic, allowed}), t)
128128+ if !Belt.Set.has(schematicsIn(t), schematic) &&
129129+ Belt.Set.subset(freeVarsIn(t), Belt.Set.fromArray(allowed, ~id=module(IntCmp))) =>
130130+ Seq.once(singletonSubst(schematic, t))
131131+ | (t, Schematic({schematic, allowed}))
132132+ if !Belt.Set.has(schematicsIn(t), schematic) &&
133133+ Belt.Set.subset(freeVarsIn(t), Belt.Set.fromArray(allowed, ~id=module(IntCmp))) =>
134134+ Seq.once(singletonSubst(schematic, t))
135135+ | (_, _) => Seq.empty
136136+ }
137137+ and unifyArray = (a: array<(t, t)>): Seq.t<subst> => {
138138+ if Array.length(a) == 0 {
139139+ Seq.once(emptySubst)
140140+ } else {
141141+ let (x, y) = a[0]->Option.getUnsafe
142142+ unifyTerm(x, y)->Seq.flatMap(s1 =>
143143+ a
144144+ ->Array.sliceToEnd(~start=1)
145145+ ->Array.map(((t1, t2)) => (substitute(t1, s1), substitute(t2, s1)))
146146+ ->unifyArray
147147+ ->Seq.map(s2 => combineSubst(s1, s2))
148148+ )
149149+ }
150150+ }
151151+ let unify = (a: t, b: t, ~gen as _=?) => unifyTerm(a, b)
152152+153153+ let rec lower = (term: t): option<Atom.t> =>
154154+ switch term {
155155+ | Atom(s) => Some(s)
156156+ | Var({idx}) => Atom.lowerVar(idx)
157157+ | Schematic({schematic, allowed}) => Atom.lowerSchematic(schematic, allowed)
158158+ | Compound({subexps: [e1]}) => lower(e1)
159159+ | _ => None
160160+ }
161161+ let rec substDeBruijn = (term: t, substs: array<t>, ~from: int=0) =>
162162+ switch term {
163163+ | Atom(s) => {
164164+ let symbolSubsts =
165165+ substs
166166+ ->Array.mapWithIndex((t, i) => lower(t)->Option.map(a => (i, a)))
167167+ ->Array.keepSome
168168+ ->Map.fromArray
169169+170170+ Atom(Atom.substDeBruijn(s, symbolSubsts, ~from, ~to=Array.length(substs)))
171171+ }
172172+173173+ | Compound({subexps}) =>
174174+ Compound({subexps: Array.map(subexps, x => substDeBruijn(x, substs, ~from))})
175175+ | Var({idx: var}) =>
176176+ if var < from {
177177+ term
178178+ } else if var - from < Array.length(substs) && var - from >= 0 {
179179+ Option.getUnsafe(substs[var - from])
180180+ } else {
181181+ Var({idx: var - Array.length(substs)})
182182+ }
183183+ | Schematic({schematic, allowed}) =>
184184+ Schematic({
185185+ schematic,
186186+ allowed: Array.filterMap(allowed, i =>
187187+ if i < from + Array.length(substs) {
188188+ None
189189+ } else {
190190+ Some(i - (from + Array.length(substs)))
191191+ }
192192+ ),
193193+ })
194194+ }
195195+ let rec upshift = (term: t, amount: int, ~from: int=0) =>
196196+ switch term {
197197+ | Atom(s) => Atom(s->Atom.upshift(amount, ~from))
198198+ | Compound({subexps}) => Compound({subexps: Array.map(subexps, x => upshift(x, amount, ~from))})
199199+ | Var({idx}) =>
200200+ Var({
201201+ idx: if idx >= from {
202202+ idx + amount
203203+ } else {
204204+ idx
205205+ },
206206+ })
207207+ | Schematic({schematic, allowed}) =>
208208+ Schematic({
209209+ schematic,
210210+ allowed: Array.map(allowed, i =>
211211+ if i >= from {
212212+ i + amount
213213+ } else {
214214+ i
215215+ }
216216+ ),
217217+ })
218218+ }
219219+ let place = (x: int, ~scope: array<string>) => Schematic({
220220+ schematic: x,
221221+ allowed: Array.fromInitializer(~length=Array.length(scope), i => i),
222222+ })
223223+ let mergeSubsts = Util.mapUnion
224224+225225+ type gen = ref<int>
226226+ let seen = (g: gen, s: int) => {
227227+ if s >= g.contents {
228228+ g := s + 1
229229+ }
230230+ }
231231+ let fresh = (g: gen, ~replacing as _=?) => {
232232+ let v = g.contents
233233+ g := g.contents + 1
234234+ v
235235+ }
236236+ let prettyPrintVar = (idx: int, scope: array<string>) => {
237237+ switch scope[idx] {
238238+ | Some(n) if Array.indexOf(scope, n) == idx => n
239239+ | _ => "\\"->String.concat(String.make(idx))
240240+ }
241241+ }
242242+ let makeGen = () => {
243243+ ref(0)
244244+ }
245245+ let rec prettyPrint = (it: t, ~scope: array<string>) =>
246246+ switch it {
247247+ | Atom(name) => Atom.prettyPrint(name, ~scope)
248248+ | Var({idx}) => prettyPrintVar(idx, scope)
249249+ | Schematic({schematic, allowed}) =>
250250+ "?"
251251+ ->String.concat(String.make(schematic))
252252+ ->String.concat("(")
253253+ ->String.concat(Array.join(allowed->Array.map(idx => prettyPrintVar(idx, scope)), " "))
254254+ ->String.concat(")")
255255+ | Compound({subexps}) =>
256256+ "("
257257+ ->String.concat(Array.join(subexps->Array.map(e => prettyPrint(e, ~scope)), " "))
258258+ ->String.concat(")")
259259+ }
260260+261261+ let prettyPrintSubst = (sub, ~scope) =>
262262+ Util.prettyPrintMap(sub, ~showV=t => prettyPrint(t, ~scope))
263263+ let symbolRegexpString = `^([^\\s()\\[\\]]+)`
264264+ let varRegexpString = "^\\\\([0-9]+)$"
265265+ let schematicRegexpString = "^\\?([0-9]+)$"
266266+ type lexeme = LParen | RParen | VarT(int) | AtomT(Atom.t) | SchematicT(int)
267267+ let nameRES = "^([^\\s.\\[\\]()]+)\\."
268268+ let prettyPrintMeta = (str: string) => {
269269+ String.concat(str, ".")
270270+ }
271271+ let parseMeta = (str: string) => {
272272+ let re = RegExp.fromStringWithFlags(nameRES, ~flags="y")
273273+ switch re->RegExp.exec(str->String.trim) {
274274+ | None => Error("not a meta name")
275275+ | Some(res) =>
276276+ switch RegExp.Result.matches(res) {
277277+ | [n] => Ok(n, String.sliceToEnd(str->String.trim, ~start=RegExp.lastIndex(re)))
278278+ | _ => Error("impossible happened")
279279+ }
280280+ }
281281+ }
282282+ let parse = (str: string, ~scope: array<string>, ~gen=?) => {
283283+ let cur = ref(String.make(str))
284284+ let lex: unit => option<lexeme> = () => {
285285+ let str = String.trim(cur.contents)
286286+ cur := str
287287+ let checkVariable = (candidate: string) => {
288288+ let varRegexp = RegExp.fromString(varRegexpString)
289289+ switch Array.indexOf(scope, candidate) {
290290+ | -1 =>
291291+ switch varRegexp->RegExp.exec(candidate) {
292292+ | Some(res') =>
293293+ switch RegExp.Result.matches(res') {
294294+ | [idx] => Some(idx->Int.fromString->Option.getUnsafe)
295295+ | _ => None
296296+ }
297297+ | None => None
298298+ }
299299+ | idx => Some(idx)
300300+ }
301301+ }
302302+ if String.get(str, 0) == Some("(") {
303303+ cur := String.sliceToEnd(str, ~start=1)
304304+ Some(LParen)
305305+ } else if String.get(str, 0) == Some(")") {
306306+ cur := String.sliceToEnd(str, ~start=1)
307307+ Some(RParen)
308308+ } else {
309309+ let symbolRegexp = RegExp.fromStringWithFlags(symbolRegexpString, ~flags="y")
310310+ switch symbolRegexp->RegExp.exec(str) {
311311+ | None => None
312312+ | Some(res) =>
313313+ switch RegExp.Result.matches(res) {
314314+ | [symb] => {
315315+ let specialSymb = tok => {
316316+ cur := String.sliceToEnd(str, ~start=RegExp.lastIndex(symbolRegexp))
317317+ Some(tok)
318318+ }
319319+ let regularSymb = () => {
320320+ // FIX: not ideal to throw away symbol error message
321321+ Console.log(("current", cur.contents))
322322+ Atom.parse(cur.contents, ~scope)
323323+ ->Util.Result.ok
324324+ ->Option.map(((s, rest)) => {
325325+ cur := rest
326326+ Console.log(("parsed", s, cur.contents))
327327+ AtomT(s)
328328+ })
329329+ }
330330+ switch checkVariable(symb) {
331331+ | Some(idx) => specialSymb(VarT(idx))
332332+ | None => {
333333+ let schematicRegexp = RegExp.fromString(schematicRegexpString)
334334+ switch schematicRegexp->RegExp.exec(symb) {
335335+ | None => regularSymb()
336336+ | Some(res') =>
337337+ switch RegExp.Result.matches(res') {
338338+ | [s] => specialSymb(SchematicT(s->Int.fromString->Option.getUnsafe))
339339+ | _ => regularSymb()
340340+ }
341341+ }
342342+ }
343343+ }
344344+ }
345345+ | _ => None
346346+ }
347347+ }
348348+ }
349349+ }
350350+351351+ let peek = () => {
352352+ // a bit slow, better would be to keep a backlog of lexed tokens..
353353+ let str = String.make(cur.contents)
354354+ let tok = lex()
355355+ cur := str
356356+ tok
357357+ }
358358+ exception ParseError(string)
359359+ let rec parseExp = () => {
360360+ let tok = peek()
361361+ switch tok {
362362+ | Some(AtomT(s)) => {
363363+ let _ = lex()
364364+ Some(Atom(s))
365365+ }
366366+ | Some(VarT(idx)) => {
367367+ let _ = lex()
368368+ Some(Var({idx: idx}))
369369+ }
370370+ | Some(SchematicT(num)) => {
371371+ let _ = lex()
372372+ switch lex() {
373373+ | Some(LParen) => {
374374+ let it = ref(None)
375375+ let bits = []
376376+ let getVar = (t: option<lexeme>) =>
377377+ switch t {
378378+ | Some(VarT(idx)) => Some(idx)
379379+ | _ => None
380380+ }
381381+ while {
382382+ it := lex()
383383+ it.contents->getVar->Option.isSome
384384+ } {
385385+ Array.push(bits, it.contents->getVar->Option.getUnsafe)
386386+ }
387387+ switch it.contents {
388388+ | Some(RParen) =>
389389+ switch gen {
390390+ | Some(g) => {
391391+ seen(g, num)
392392+ Some(Schematic({schematic: num, allowed: bits}))
393393+ }
394394+ | None => throw(ParseError("Schematics not allowed here"))
395395+ }
396396+ | _ => throw(ParseError("Expected closing parenthesis"))
397397+ }
398398+ }
399399+ | _ => throw(ParseError("Expected opening parenthesis"))
400400+ }
401401+ }
402402+ | Some(LParen) => {
403403+ let _ = lex()
404404+ let bits = []
405405+ let it = ref(None)
406406+ while {
407407+ it := parseExp()
408408+ it.contents->Option.isSome
409409+ } {
410410+ Array.push(bits, it.contents->Option.getUnsafe)
411411+ }
412412+ switch lex() {
413413+ | Some(RParen) => Some(Compound({subexps: bits}))
414414+ | _ => throw(ParseError("Expected closing parenthesis"))
415415+ }
416416+ }
417417+ | _ => None
418418+ }
419419+ }
420420+ switch parseExp() {
421421+ | exception ParseError(s) => Error(s)
422422+ | None => Error("No expression to parse")
423423+ | Some(e) => Ok((e, cur.contents))
424424+ }
425425+ }
426426+427427+ let rec concrete = t =>
428428+ switch t {
429429+ | Schematic(_) => true
430430+ | Atom(s) => Atom.concrete(s)
431431+ | Compound({subexps}) => subexps->Array.every(concrete)
432432+ | _ => false
433433+ }
434434+ let mapTerms = (t, f) => f(t)
435435+}
···2424 let parseMeta: string => result<(meta, string), string>
2525 let prettyPrint: (t, ~scope: array<meta>) => string
2626 let prettyPrintMeta: meta => string
2727- let ghostTerm: t
2727+ // will unifying t with a term give meaningful substitutions?
2828+ let concrete: t => bool
2829}
29303031module type JUDGMENT = {
3132 module Term: TERM
3233 type t
3333- type subst
3434- type substCodom
3535- type schematic = Term.schematic
3636- type meta = Term.meta
3737- let mapSubst: (subst, substCodom => substCodom) => subst
3838- let mergeSubsts: (subst, subst) => subst
3939- let substitute: (t, subst) => t
4040- let substituteSubstCodom: (substCodom, subst) => substCodom
3434+ let substitute: (t, Term.subst) => t
4135 let equivalent: (t, t) => bool
4242- let unify: (t, t, ~gen: Term.gen=?) => Seq.t<subst>
4343- let substDeBruijn: (t, array<substCodom>, ~from: int=?) => t
3636+ let unify: (t, t, ~gen: Term.gen=?) => Seq.t<Term.subst>
3737+ let substDeBruijn: (t, array<Term.t>, ~from: int=?) => t
4438 let reduce: t => t
4539 let upshift: (t, int, ~from: int=?) => t
4646- let upshiftSubstCodom: (substCodom, int, ~from: int=?) => substCodom
4747- let placeSubstCodom: (schematic, ~scope: array<meta>) => substCodom
4840 // Map a function over all terms in the judgment
4941 let mapTerms: (t, Term.t => Term.t) => t
5042 let parse: (string, ~scope: array<Term.meta>, ~gen: Term.gen=?) => result<(t, string), string>
5151- let parseSubstCodom: (
5252- string,
5353- ~scope: array<Term.meta>,
5454- ~gen: Term.gen=?,
5555- ) => result<(substCodom, string), string>
5643 let prettyPrint: (t, ~scope: array<Term.meta>) => string
5757- let prettyPrintSubstCodom: (substCodom, ~scope: array<Term.meta>) => string
5858- let ghostJudgment: t
4444+ let concrete: t => bool
5945}
60466147module type TERM_VIEW = {
···11+type rec piece =
22+ | String(string)
33+ | Var({idx: int})
44+ | Schematic({schematic: int, allowed: array<int>})
55+type t = array<piece>
66+77+module Atom: SExpFunc.ATOM with type t = t
88+module AtomView: SExpViewFunc.ATOM_VIEW with module Atom := Atom
···11+type t = StringS(StringA.Atom.t) | ConstS(string)
22+module Atom: SExpFunc.ATOM with type t = t
33+module AtomView: SExpViewFunc.ATOM_VIEW with module Atom := Atom
···11-type rec piece =
22- | String(string)
33- | Var({idx: int})
44- | Schematic({schematic: int, allowed: array<int>})
55- | Ghost
66-type t = array<piece>
77-type subst = Map.t<int, t>
88-99-include Signatures.TERM
1010- with type t := t
1111- and type meta = string
1212- and type schematic = int
1313- and type subst := subst
1414-1515-let fromSExp: SExp.t => t
1616-let toSExp: t => SExp.t
···11-include Signatures.TERM_VIEW with module Term := StringTerm
+29
src/Symbolic.res
···11+type t = string
22+module Atom = {
33+ type t = string
44+ type subst = Map.t<int, string>
55+ let unify = (a, b, ~gen as _=?) =>
66+ if a == b {
77+ Seq.once(Map.make())
88+ } else {
99+ Seq.empty
1010+ }
1111+ let prettyPrint = (name, ~scope as _: array<string>) => name
1212+ let symbolRegex = /^([^\s()\[\]]+)/
1313+ let parse = (string, ~scope as _: array<string>, ~gen as _=?) =>
1414+ switch Util.execRe(symbolRegex, string) {
1515+ | Some(([res], l)) => Ok((res, string->String.substringToEnd(~start=l)))
1616+ | _ => Error("constant symbol parse error")
1717+ }
1818+ let substitute = (name, _) => name
1919+ let lowerVar = _ => None
2020+ let lowerSchematic = (_, _) => None
2121+ let substDeBruijn = (name, _, ~from as _=?, ~to as _) => name
2222+ let concrete = _ => false
2323+ let upshift = (t, _, ~from as _=?) => t
2424+}
2525+2626+module AtomView = {
2727+ type props = {name: string, scope: array<string>}
2828+ let make = (props: props) => React.string(props.name)
2929+}
+3
src/Symbolic.resi
···11+type t = string
22+module Atom: SExpFunc.ATOM with type t = t
33+module AtomView: SExpViewFunc.ATOM_VIEW with module Atom := Atom
-18
src/TermAsJudgment.res
···11-open Signatures
22-33-module Make = (Term: TERM): (
44- JUDGMENT with module Term := Term and type t = Term.t and type subst = Term.subst
55-) => {
66- include Term
77- type substCodom = Term.t
88- let prettyPrintSubstCodom = Term.prettyPrint
99- let parseSubstCodom = Term.parse
1010- let placeSubstCodom = Term.place
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
1515-}
1616-1717-module SExpJ = Make(SExp)
1818-module HOTermJ = Make(HOTerm)
+12
src/TermViewAsJudgmentView.res
···11+module Make = (
22+ Term: Signatures.TERM,
33+ Judgment: Signatures.JUDGMENT with module Term := Term and type t = Term.t,
44+ TermView: Signatures.TERM_VIEW with module Term := Term,
55+): (Signatures.JUDGMENT_VIEW with module Term := Term and module Judgment := Judgment) => {
66+ module TermView = TermView
77+ type props = {
88+ judgment: Judgment.t,
99+ scope: array<Term.meta>,
1010+ }
1111+ let make = ({judgment, scope}) => TermView.make({term: judgment, scope})
1212+}
+13
src/Util.res
···117117 | i => i
118118 }
119119}
120120+121121+module Result = {
122122+ let ok = (r: result<'a, 'b>): option<'a> =>
123123+ switch r {
124124+ | Ok(a) => Some(a)
125125+ | Error(_) => None
126126+ }
127127+ let or = (r1: result<'a, 'b>, r2: unit => result<'a, 'b>): result<'a, 'b> =>
128128+ switch r1 {
129129+ | Ok(_) => r1
130130+ | Error(_) => r2()
131131+ }
132132+}