(* Title: Pure/term_xml.ML Author: Makarius XML data representation of lambda terms. *) signature TERM_XML_OPS = sig type 'a T type 'a P val indexname: indexname P val sort: sort T val typ: typ T val term_raw: term T val typ_body: typ T val term: Consts.T -> term T end signature TERM_XML = sig structure Encode: TERM_XML_OPS structure Decode: TERM_XML_OPS end; structure Term_XML: TERM_XML = struct structure Encode = struct open XML.Encode; fun indexname (a, b) = if b = 0 then [a] else [a, int_atom b]; val sort = list string; fun typ T = T |> variant [fn Type (a, b) => ([a], list typ b), fn TFree (a, b) => ([a], sort b), fn TVar (a, b) => (indexname a, sort b)]; fun term_raw t = t |> variant [fn Const (a, b) => ([a], typ b), fn Free (a, b) => ([a], typ b), fn Var (a, b) => (indexname a, typ b), fn Bound a => ([], int a), fn Abs (a, b, c) => ([a], pair typ term_raw (b, c)), fn op $ a => ([], pair term_raw term_raw a)]; fun typ_body T = if T = dummyT then [] else typ T; fun term consts t = t |> variant [fn Const (a, b) => ([a], list typ (Consts.typargs consts (a, b))), fn Free (a, b) => ([a], typ_body b), fn Var (a, b) => (indexname a, typ_body b), fn Bound a => ([], int a), fn Abs (a, b, c) => ([a], pair typ (term consts) (b, c)), fn op $ a => ([], pair (term consts) (term consts) a)]; end; structure Decode = struct open XML.Decode; fun indexname [a] = (a, 0) | indexname [a, b] = (a, int_atom b); val sort = list string; fun typ body = body |> variant [fn ([a], b) => Type (a, list typ b), fn ([a], b) => TFree (a, sort b), fn (a, b) => TVar (indexname a, sort b)]; fun term_raw body = body |> variant [fn ([a], b) => Const (a, typ b), fn ([a], b) => Free (a, typ b), fn (a, b) => Var (indexname a, typ b), fn ([], a) => Bound (int a), fn ([a], b) => let val (c, d) = pair typ term_raw b in Abs (a, c, d) end, fn ([], a) => op $ (pair term_raw term_raw a)]; fun typ_body [] = dummyT | typ_body body = typ body; fun term consts body = body |> variant [fn ([a], b) => Const (a, Consts.instance consts (a, list typ b)), fn ([a], b) => Free (a, typ_body b), fn (a, b) => Var (indexname a, typ_body b), fn ([], a) => Bound (int a), fn ([a], b) => let val (c, d) = pair typ (term consts) b in Abs (a, c, d) end, fn ([], a) => op $ (pair (term consts) (term consts) a)]; end; end;