···11include Signatures.JUDGMENT_VIEW
22- with module Term := StringTerm
22+ with module Term := StringTermJudgment.StringSExp
33 and module Judgment := StringTermJudgment
+2-147
src/StringTermJudgment.res
···4343 | ConstS(s) => SExp.ConstSymbol.constSymbol(s)
4444 }
4545}
4646-module StringSExp = SExpFunc.Make(StringSymbol)
4747-let constSymbol = (s: string): StringSExp.t => StringSExp.Symbol(ConstS(SExp.pSymbol(s)))
4848-4949-let toSExp = (t: StringTerm.t): StringSExp.t => {
5050- let convertPiece = (p: StringTerm.piece): StringSExp.t =>
5151- switch p {
5252- | StringTerm.String(s) => {
5353- let (s, _) = StringSymbol.parse(s, ~scope=[])->Result.getExn
5454- StringSExp.Symbol(s)
5555- }
5656- | StringTerm.Var({idx}) => StringSExp.Var({idx: idx})
5757- | StringTerm.Schematic({schematic, allowed}) => StringSExp.Schematic({schematic, allowed})
5858- | StringTerm.Ghost => StringSExp.ghostTerm
5959- }
6060- switch Array.length(t) {
6161- | 1 => convertPiece(t[0]->Option.getExn)
6262- | _ => StringSExp.Compound({subexps: Array.map(t, convertPiece)})
6363- }
6464-}
65466666-let rec fromSExp = (t: StringSExp.t): StringTerm.t =>
6767- switch t {
6868- | StringSExp.Symbol(name) => [StringTerm.String(StringSymbol.prettyPrint(name, ~scope=[]))]
6969- | StringSExp.Schematic({schematic, allowed}) => [StringTerm.Schematic({schematic, allowed})]
7070- | StringSExp.Var({idx}) => [StringTerm.Var({idx: idx})]
7171- | StringSExp.Compound({subexps}) => subexps->Array.flatMap(fromSExp)
7272- | StringSExp.Ghost => [StringTerm.Ghost]
7373- }
7474-7575-type t = (StringTerm.t, StringSExp.t)
7676-type substCodom = StringV(StringTerm.t) | SExpV(StringSExp.t)
7777-type subst = Map.t<int, substCodom>
7878-type schematic = int
7979-type meta = string
8080-8181-let mapSubst = Util.mapMapValues
8282-let mergeSubsts: (subst, subst) => subst = Util.mapUnion
8383-let splitSub: subst => (StringTerm.subst, StringSExp.subst) = s => {
8484- let stringSub = Map.make()
8585- let judgeSub = Map.make()
8686- s->Map.forEachWithKey((v, k) => {
8787- switch v {
8888- | StringV(t) => {
8989- stringSub->Map.set(k, t)
9090- judgeSub->Map.set(k, t->toSExp)
9191- }
9292- | SExpV(t) => {
9393- stringSub->Map.set(k, t->fromSExp)
9494- judgeSub->Map.set(k, t)
9595- }
9696- }
9797- })
9898- (stringSub, judgeSub)
9999-}
100100-let substitute = ((term, judge): t, sub) => {
101101- let (stringSub, judgeSub) = splitSub(sub)
102102- (StringTerm.substitute(term, stringSub), StringSExp.substitute(judge, judgeSub))
103103-}
104104-105105-let substituteSubstCodom = (s: substCodom, subst: subst) => {
106106- let (stringSub, judgeSub) = splitSub(subst)
107107- switch s {
108108- | StringV(t) => StringV(StringTerm.substitute(t, stringSub))
109109- | SExpV(t) => SExpV(StringSExp.substitute(t, judgeSub))
110110- }
111111-}
112112-let equivalent = ((t1, j1): t, (t2, j2): t) =>
113113- StringTerm.equivalent(t1, t2) && StringSExp.equivalent(j1, j2)
114114-let reduce = t => t
115115-let unify = ((t1, j1): t, (t2, j2): t, ~gen as _=?) => {
116116- // cartesian prod of possible unifications
117117- let judgeSubs = StringSExp.unify(j1, j2)->Seq.map(s => s->Util.mapMapValues(t => SExpV(t)))
118118- let stringSubs = StringTerm.unify(t1, t2)->Seq.map(s => s->Util.mapMapValues(t => StringV(t)))
119119- judgeSubs->Seq.flatMap(judgeSub =>
120120- // NOTE: silent failure mode here where substitution exists for a given schematic on both string
121121- // SExp side. for now, bias string sub. in future, maybe consider this not a valid judgement to begin with.
122122- stringSubs->Seq.map(stringSub => Util.mapUnion(stringSub, judgeSub))
123123- )
124124-}
125125-let substDeBruijn = ((t, j): t, scope: array<substCodom>, ~from: int=0) => {
126126- // NOTE: implicit type coercion here. if we unify and expect a string but get an sexp,
127127- // perform naive flattening of compound to substitute. likewise in opposite direction.
128128- let stringScope = scope->Array.map(v =>
129129- switch v {
130130- | StringV(t) => t
131131- | SExpV(t) => fromSExp(t)
132132- }
133133- )
134134- let judgeScope = scope->Array.map(v =>
135135- switch v {
136136- | SExpV(t) => t
137137- | StringV(t) => toSExp(t)
138138- }
139139- )
140140- (StringTerm.substDeBruijn(t, stringScope, ~from), StringSExp.substDeBruijn(j, judgeScope, ~from))
141141-}
142142-let upshift = ((t, j): t, amount: int, ~from: int=0) => (
143143- StringTerm.upshift(t, amount, ~from),
144144- StringSExp.upshift(j, amount, ~from),
145145-)
146146-147147-let upshiftSubstCodom = (v: substCodom, amount: int, ~from: int=0) =>
148148- switch v {
149149- | StringV(t) => StringV(StringTerm.upshift(t, amount, ~from))
150150- | SExpV(j) => SExpV(StringSExp.upshift(j, amount, ~from))
151151- }
152152-153153-let mapTerms = ((t, j): t, f: StringTerm.t => StringTerm.t): t => {
154154- // Apply the function to both the string term and the sexp (converted to/from string term)
155155- let newT = f(t)
156156- // FIX: is this necessary? is mapTerms even used?
157157- let newJ = j->fromSExp->f->toSExp
158158- (newT, newJ)
159159-}
160160-161161-let parse = (str: string, ~scope: array<string>, ~gen: option<ref<int>>=?) => {
162162- StringTerm.parse(str, ~scope, ~gen?)->Result.flatMap(((t, str)) =>
163163- StringSExp.parse(str, ~scope)->Result.map(((j, str)) => ((t, j), str))
164164- )
165165-}
166166-167167-// HACK: this does work due to the hacky string-sexp conversion we have inplace with substitutions,
168168-// but a different solution would be preferable
169169-let placeSubstCodom = (x: int, ~scope: array<string>) => StringV(StringTerm.place(x, ~scope))
170170-171171-let parseSubstCodom = (str: string, ~scope: array<StringTerm.meta>, ~gen=?) => {
172172- switch StringTerm.parse(str, ~scope, ~gen?) {
173173- | Ok(t, str) => Ok(StringV(t), str)
174174- | Error(stringE) =>
175175- switch StringSExp.parse(str, ~scope) {
176176- | Ok(t, str) => Ok(SExpV(t), str)
177177- | Error(sExpE) =>
178178- Error(
179179- `string or sexp expected.\nstring parsing failed with error: ${stringE}\nsexp parsing failed with error: ${sExpE}`,
180180- )
181181- }
182182- }
183183-}
184184-185185-let prettyPrint = ((t, j): t, ~scope: array<StringTerm.meta>) =>
186186- `${StringTerm.prettyPrint(t, ~scope)} ${StringSExp.prettyPrint(j, ~scope)}`
187187-let prettyPrintSubstCodom = (v: substCodom, ~scope: array<StringTerm.meta>) =>
188188- switch v {
189189- | StringV(t) => StringTerm.prettyPrint(t, ~scope)
190190- | SExpV(t) => StringSExp.prettyPrint(t, ~scope)
191191- }
192192-193193-let ghostJudgment = (StringTerm.ghostTerm, StringSExp.ghostTerm)
4747+module StringSExp = SExpFunc.Make(StringSymbol)
4848+include TermAsJudgment.Make(StringSExp)
+2-4
src/StringTermJudgment.resi
···22module StringSymbol: SExpFunc.SYMBOL with type t = stringSymbol
3344module StringSExp: module type of SExpFunc.Make(StringSymbol)
55-66-type t = (StringTerm.t, StringSExp.t)
77-let constSymbol: string => StringSExp.t
55+type t = StringSExp.t
8699-include Signatures.JUDGMENT with module Term := StringTerm and type t := t
77+include Signatures.JUDGMENT with module Term := StringSExp and type t := t