···11module ConstSymbol: SExpFunc.SYMBOL = {
22 type t = string
33- let match = (nameA, nameB) => nameA == nameB
33+ type subst = Map.t<int, string>
44+ let unify = (a, b) =>
55+ if a == b {
66+ Seq.once(Map.make())
77+ } else {
88+ Seq.empty
99+ }
410 let prettyPrint = (name, ~scope as _: array<string>) => name
511 let parse = (string, ~scope as _: array<string>) => Ok((string, ""))
612}
+20-27
src/SExpFunc.res
···11module type SYMBOL = {
22 type t
33- let match: (t, t) => bool
33+ type subst = Map.t<int, t>
44+ let unify: (t, t) => Seq.t<subst>
45 let prettyPrint: (t, ~scope: array<string>) => string
56 let parse: (string, ~scope: array<string>) => result<(t, string), string>
67}
···9495 s->Map.set(schematic, term)
9596 s
9697 }
9797- let rec unifyTerm = (a: t, b: t) =>
9898+ let rec unifyTerm = (a: t, b: t): Seq.t<subst> =>
9899 switch (a, b) {
9999- | (Symbol(na), Symbol(nb)) if na->Symbol.match(nb) => Some(emptySubst)
100100- | (Var({idx: ia}), Var({idx: ib})) if ia == ib => Some(emptySubst)
101101- | (Schematic({schematic: sa, _}), Schematic({schematic: sb, _})) if sa == sb => Some(emptySubst)
100100+ | (Symbol(na), Symbol(nb)) =>
101101+ Symbol.unify(na, nb)->Seq.map(subst => subst->Util.mapMapValues(v => Symbol(v)))
102102 | (Compound({subexps: xa}), Compound({subexps: xb})) if Array.length(xa) == Array.length(xb) =>
103103 unifyArray(Belt.Array.zip(xa, xb))
104104+ | (Var({idx: ia}), Var({idx: ib})) if ia == ib => Seq.once(emptySubst)
105105+ | (Schematic({schematic: sa, _}), Schematic({schematic: sb, _})) if sa == sb =>
106106+ Seq.once(emptySubst)
104107 | (Schematic({schematic, allowed}), t)
105108 if !Belt.Set.has(schematicsIn(t), schematic) &&
106109 Belt.Set.subset(freeVarsIn(t), Belt.Set.fromArray(allowed, ~id=module(IntCmp))) =>
107107- Some(singletonSubst(schematic, t))
110110+ Seq.once(singletonSubst(schematic, t))
108111 | (t, Schematic({schematic, allowed}))
109112 if !Belt.Set.has(schematicsIn(t), schematic) &&
110113 Belt.Set.subset(freeVarsIn(t), Belt.Set.fromArray(allowed, ~id=module(IntCmp))) =>
111111- Some(singletonSubst(schematic, t))
112112- | (_, _) => None
114114+ Seq.once(singletonSubst(schematic, t))
115115+ | (_, _) => Seq.empty
113116 }
114114- and unifyArray = (a: array<(t, t)>) => {
117117+ and unifyArray = (a: array<(t, t)>): Seq.t<subst> => {
115118 if Array.length(a) == 0 {
116116- Some(emptySubst)
119119+ Seq.once(emptySubst)
117120 } else {
118121 let (x, y) = a[0]->Option.getUnsafe
119119- switch unifyTerm(x, y) {
120120- | None => None
121121- | Some(s1) =>
122122- switch a
122122+ unifyTerm(x, y)->Seq.flatMap(s1 =>
123123+ a
123124 ->Array.sliceToEnd(~start=1)
124125 ->Array.map(((t1, t2)) => (substitute(t1, s1), substitute(t2, s1)))
125125- ->unifyArray {
126126- | None => None
127127- | Some(s2) => Some(combineSubst(s1, s2))
128128- }
129129- }
126126+ ->unifyArray
127127+ ->Seq.map(s2 => combineSubst(s1, s2))
128128+ )
130129 }
131130 }
132132- let unify = (a: t, b: t, ~gen as _=?) => {
133133- Seq.fromArray(
134134- switch unifyTerm(a, b) {
135135- | None => []
136136- | Some(s) => [s]
137137- },
138138- )
139139- }
131131+ let unify = (a: t, b: t, ~gen as _=?) => unifyTerm(a, b)
132132+140133 let rec substDeBruijn = (term: t, substs: array<t>, ~from: int=0) =>
141134 switch term {
142135 | Symbol(_) => term