| author | huffman | 
| Wed, 12 Oct 2005 03:02:18 +0200 | |
| changeset 17840 | 11bcd77cfa22 | 
| parent 17795 | 5b18c3343028 | 
| child 19475 | 8aa2b380614a | 
| permissions | -rw-r--r-- | 
| 15481 | 1 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | 
| 16179 | 2 | (* Title: Pure/IsaPlanner/focus_term_lib.ML | 
| 3 | ID: $Id$ | |
| 15481 | 4 | Author: Lucas Dixon, University of Edinburgh | 
| 5 | lucasd@dai.ed.ac.uk | |
| 6 | Date: 16 April 2003 | |
| 7 | *) | |
| 8 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 9 | (* DESCRIPTION: | |
| 10 | ||
| 11 | Generic Foucs terms (like Zippers), which allows modification and | |
| 12 | manipulation of term keeping track of how we got to the position | |
| 13 | in the term. We provide a signature for terms, ie any kind of | |
| 14 | lamda calculus with abs and application, and some notion of types | |
| 15 | and naming of abstracted vars. | |
| 16 | ||
| 17 | FIXME: at some point in the future make a library to work simply | |
| 18 | with polymorphic upterms - that way if I want to use them without | |
| 19 | the focus part, then I don't need to include all the focus stuff. | |
| 20 | ||
| 21 | *) | |
| 22 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 23 | ||
| 24 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 25 | ||
| 26 | (* to endoce and decode general terms into the type needed by focus | |
| 27 | term, this is an easy thing to write, but needs to be done for each | |
| 28 | type that is going to be used with focus terms. *) | |
| 29 | ||
| 30 | signature F_ENCODE_TERM_SIG = | |
| 31 | sig | |
| 32 | ||
| 33 | type term (* type of term to be encoded into TermT for focus term manip *) | |
| 34 | type TypeT (* type annotation for abstractions *) | |
| 35 | type LeafT (* type for other leaf types in term sturcture *) | |
| 36 | ||
| 37 | (* the type to be encoded into *) | |
| 17795 | 38 | datatype TermT = $ of TermT * TermT | 
| 15481 | 39 | | Abs of string * TypeT * TermT | 
| 40 | | lf of LeafT | |
| 41 | ||
| 42 | (* the encode and decode functions *) | |
| 43 | val fakebounds : string * TypeT -> term -> term | |
| 44 | val encode : term -> TermT | |
| 45 | val decode : TermT -> term | |
| 46 | ||
| 47 | end; | |
| 48 | ||
| 49 | ||
| 50 | ||
| 51 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 52 | signature FOCUS_TERM_SIG = | |
| 53 | sig | |
| 54 | structure MinTermS : F_ENCODE_TERM_SIG | |
| 55 | ||
| 56 | exception focus_term_exp of string; | |
| 57 | exception out_of_term_exception of string; | |
| 58 | ||
| 17795 | 59 | type Term (* = MinTermS.TermT *) | 
| 60 | type Type (* = MinTermS.TypeT *) | |
| 15481 | 61 | |
| 17795 | 62 | type UpTerm (* = (Term,Type) UpTermLib.T *) | 
| 15481 | 63 | |
| 64 | (* datatype | |
| 65 | UpTerm = | |
| 66 | abs of string * Type * UpTerm | |
| 67 | | appl of Term * UpTerm | |
| 68 | | appr of Term * UpTerm | |
| 69 | | root *) | |
| 70 | ||
| 71 | datatype FcTerm = focus of Term * UpTerm | |
| 72 | ||
| 73 | (* translating *) | |
| 74 | val fcterm_of_term : MinTermS.term -> FcTerm | |
| 75 | val term_of_fcterm : FcTerm -> MinTermS.term | |
| 76 | ||
| 77 | (* editing/constrution *) | |
| 78 | val enc_appl : (MinTermS.term * UpTerm) -> UpTerm | |
| 79 | val enc_appr : (MinTermS.term * UpTerm) -> UpTerm | |
| 80 | ||
| 81 | (* upterm creatioin *) | |
| 82 | val upterm_of : FcTerm -> UpTerm | |
| 83 | val add_upterm : UpTerm -> FcTerm -> FcTerm | |
| 84 | val mk_term_of_upterm : (MinTermS.term * UpTerm) -> MinTermS.term | |
| 85 | val mk_termf_of_upterm : UpTerm -> | |
| 86 | (((string * Type) list) * | |
| 87 | (MinTermS.term -> MinTermS.term)) | |
| 88 | val pure_mk_termf_of_upterm : (MinTermS.term, Type) UpTermLib.T -> | |
| 89 | (((string * Type) list) * | |
| 90 | (MinTermS.term -> MinTermS.term)) | |
| 91 | ||
| 92 | (* focusing, throws exceptions *) | |
| 93 | val focus_bot_left_leaf : FcTerm -> FcTerm | |
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 94 | val focus_bot_left_nonabs_leaf : FcTerm -> FcTerm | 
| 15481 | 95 | val focus_left : FcTerm -> FcTerm | 
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 96 | val focus_strict_left : FcTerm -> FcTerm | 
| 15481 | 97 | val focus_right : FcTerm -> FcTerm | 
| 98 | val focus_abs : FcTerm -> FcTerm | |
| 99 | val focus_fake_abs : FcTerm -> FcTerm | |
| 100 | val focus_to_top : FcTerm -> FcTerm | |
| 101 | val focus_up : FcTerm -> FcTerm | |
| 102 | val focus_up_right : FcTerm -> FcTerm | |
| 103 | val focus_up_right1 : FcTerm -> FcTerm | |
| 104 | ||
| 105 | (* optional focus changes *) | |
| 106 | val focus_up_abs : FcTerm -> FcTerm option | |
| 107 | val focus_up_appr : FcTerm -> FcTerm option | |
| 108 | val focus_up_appl : FcTerm -> FcTerm option | |
| 109 | val focus_up_abs_or_appr : FcTerm -> FcTerm option | |
| 110 | ||
| 111 | val tyenv_of_focus : FcTerm -> (string * Type) list | |
| 112 | val tyenv_of_focus' : FcTerm -> Type list | |
| 113 | ||
| 114 | (* set/get the focus term *) | |
| 115 | val set_focus_of_fcterm : FcTerm -> MinTermS.term -> FcTerm | |
| 116 | val focus_of_fcterm : FcTerm -> MinTermS.term | |
| 117 | ||
| 118 | (* leaf navigation *) | |
| 119 | val leaf_seq_of_fcterm : FcTerm -> FcTerm Seq.seq | |
| 120 | val next_leaf_fcterm : FcTerm -> FcTerm | |
| 121 | val next_leaf_of_fcterm_seq : FcTerm -> FcTerm Seq.seq | |
| 122 | ||
| 123 | (* analysis *) | |
| 124 | val upsize_of_fcterm : FcTerm -> int | |
| 125 | end; | |
| 126 | ||
| 127 | ||
| 128 | ||
| 129 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 130 | (* | |
| 131 | ||
| 132 | NOTE!!! I think this can be done in a purely functional way with a | |
| 133 | pair of a term (the focus) and a function, that when applied | |
| 134 | unfocuses one level... maybe think about this as it would be a very | |
| 135 | nice generic consrtuction, without the need for encoding/decoding | |
| 136 | strutcures. | |
| 137 | ||
| 138 | *) | |
| 139 | functor FocusTermFUN(structure EncodeTerm : F_ENCODE_TERM_SIG) | |
| 140 | : FOCUS_TERM_SIG = | |
| 141 | struct | |
| 142 | ||
| 143 | structure MinTermS = EncodeTerm; | |
| 144 | ||
| 145 | local open MinTermS open UpTermLib in | |
| 146 | ||
| 147 | type Term = MinTermS.TermT; | |
| 148 | type Type = MinTermS.TypeT; | |
| 149 | ||
| 150 | exception focus_term_exp of string; | |
| 151 | exception out_of_term_exception of string; | |
| 152 | ||
| 153 | infix 9 $ | |
| 154 | ||
| 155 | (* datatype to hold a term tree and the path to where you are in the term *) | |
| 156 | (* datatype UpTerm = root | |
| 157 | | appl of (Term * UpTerm) | |
| 158 | | appr of (Term * UpTerm) | |
| 159 | | abs of (string * Type * UpTerm); *) | |
| 160 | ||
| 161 | type UpTerm = (Term,Type) UpTermLib.T; | |
| 162 | ||
| 163 | fun enc_appl (t,u) = appl((MinTermS.encode t),u); | |
| 164 | fun enc_appr (t,u) = appr((MinTermS.encode t),u); | |
| 165 | ||
| 166 | datatype FcTerm = focus of (Term * UpTerm); | |
| 167 | ||
| 168 | (* the the term of the upterm *) | |
| 169 | fun mk_term_of_upt_aux (t, root) = MinTermS.decode t | |
| 170 | | mk_term_of_upt_aux (t, appl (l,m)) = mk_term_of_upt_aux(l$t, m) | |
| 171 | | mk_term_of_upt_aux (t, appr (r,m)) = mk_term_of_upt_aux(t$r, m) | |
| 172 | | mk_term_of_upt_aux (t, abs (s,ty,m)) = mk_term_of_upt_aux(Abs(s,ty,t),m); | |
| 173 | ||
| 174 | fun mk_term_of_upterm (t, ut) = mk_term_of_upt_aux (MinTermS.encode t, ut); | |
| 175 | ||
| 176 | (* a function version of the above, given an upterm it returns: | |
| 177 | a function on that given a term puts it in the context of the upterm, | |
| 178 | and a list of bound variables that are in the upterm, added as | |
| 179 | we go up - so in reverse order from that typiclaly used by top-down | |
| 180 | parsing of terms. *) | |
| 181 | fun mk_termf_of_upt_aux (f, bs, root) = | |
| 182 | (bs, fn t => MinTermS.decode (f t)) | |
| 183 | | mk_termf_of_upt_aux (f, bs, appl (l,m)) = | |
| 184 | mk_termf_of_upt_aux (fn t => l $ (f t), bs, m) | |
| 185 | | mk_termf_of_upt_aux (f, bs, appr (r,m)) = | |
| 186 | mk_termf_of_upt_aux (fn t => (f t) $ r, bs, m) | |
| 187 | | mk_termf_of_upt_aux (f, bs, abs (s,ty,m)) = | |
| 188 | mk_termf_of_upt_aux (fn t => Abs(s,ty,(f t)), (s,ty)::bs, m); | |
| 189 | ||
| 190 | fun mk_termf_of_upterm ut = mk_termf_of_upt_aux (MinTermS.encode, [], ut); | |
| 191 | ||
| 192 | ||
| 193 | fun upterm_of (focus(t, u)) = u; | |
| 194 | ||
| 195 | (* put a new upterm at the start of our current term *) | |
| 196 | fun add_upterm u2 (focus(t, u)) = focus(t, UpTermLib.apply u2 u); | |
| 197 | ||
| 198 | ||
| 199 | (* As above but work on the pure originial upterm type *) | |
| 200 | fun pure_mk_termf_of_upterm ut = | |
| 201 | mk_termf_of_upt_aux | |
| 202 | (encode, [], (map_to_upterm_parts (encode, I) ut)); | |
| 203 | ||
| 204 | fun fcterm_of_term t = focus(encode t, root); | |
| 205 | ||
| 206 | fun term_of_fcterm (focus (t, m)) = mk_term_of_upt_aux (t, m); | |
| 207 | ||
| 208 | (* fun term_of_fcterm (focus (t, root)) = mk_term_of_upt_aux (t, root) | |
| 209 | | term_of_fcterm _ = raise focus_term_exp "term_of_fcterm: something bad has happened here."; *) | |
| 210 | ||
| 211 | fun focus_of_fcterm (focus(t, _)) = MinTermS.decode t; | |
| 212 | ||
| 213 | (* replace the focus term with a new term... *) | |
| 214 | fun set_focus_of_fcterm (focus(_, m)) nt = focus(MinTermS.encode nt, m); | |
| 215 | ||
| 216 | fun focus_left (focus(a $ b, m)) = focus(a, appr(b, m)) | |
| 217 | | focus_left (focus(Abs(s,ty,t), m)) = focus_left (focus(t, abs(s,ty,m))) | |
| 218 | | focus_left (focus(l, m)) = raise out_of_term_exception "focus_left"; | |
| 219 | ||
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 220 | fun focus_strict_left (focus(a $ b, m)) = focus(a, appr(b, m)) | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 221 | | focus_strict_left (focus(l, m)) = raise out_of_term_exception "focus_left"; | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 222 | |
| 15481 | 223 | (* Note: ":" is standard for faked bound vars... see: EQStepTacTermTools *) | 
| 224 | fun focus_fake_abs (focus(Abs(s,ty,t), m)) = | |
| 225 | let val t' = MinTermS.encode (fakebounds (s,ty) (MinTermS.decode t)) | |
| 226 | in focus(t', abs(s,ty,m)) end | |
| 227 | | focus_fake_abs (focus(l, m)) = raise out_of_term_exception "focus_fake_abs"; | |
| 228 | ||
| 229 | fun focus_abs (focus(Abs(s,ty,t), m)) = focus(t, abs(s,ty,m)) | |
| 230 | | focus_abs (focus(l, m)) = raise out_of_term_exception "focus_abs"; | |
| 231 | ||
| 232 | ||
| 233 | fun focus_right (focus(a $ b, m)) = focus(b, appl(a, m)) | |
| 234 | | focus_right (focus(Abs(s,ty,t), m)) = focus_right (focus(t, abs(s,ty,m))) | |
| 235 | | focus_right (focus(l, m)) = raise out_of_term_exception "focus_right"; | |
| 236 | ||
| 237 | fun focus_up (focus(t, appl(l,m))) = focus(l$t, m) | |
| 238 | | focus_up (focus(t, appr(r,m))) = focus(t$r, m) | |
| 239 | | focus_up (focus(t, abs(s,ty,m))) = focus_up (focus(Abs(s,ty,t), m)) | |
| 240 | | focus_up (focus(t, root)) = raise out_of_term_exception "focus_up"; | |
| 241 | ||
| 242 | fun focus_to_top t = | |
| 243 | focus_to_top (focus_up t) handle out_of_term_exception _ => t; | |
| 244 | ||
| 245 | (* focus up until you can move right, and then do so *) | |
| 246 | fun focus_up_right (focus(t, appl(l,m))) = | |
| 247 | focus_up_right (focus(l$t, m)) | |
| 248 | | focus_up_right (focus(t, appr(r,m))) = | |
| 249 | focus(r, appl(t,m)) | |
| 250 | | focus_up_right (focus(t, abs(s,ty,m))) = | |
| 251 | focus_up_right (focus(Abs(s,ty,t), m)) | |
| 252 | | focus_up_right (focus(t, root)) = | |
| 253 | raise out_of_term_exception "focus_up_right"; | |
| 254 | ||
| 255 | (* as above, but do not move up over a left application *) | |
| 256 | fun focus_up_right1 (focus(t, appl(l,m))) = | |
| 257 | raise out_of_term_exception "focus_up_right1" | |
| 258 | | focus_up_right1 (focus(t, appr(r,m))) = | |
| 259 | focus(r, appl(t,m)) | |
| 260 | | focus_up_right1 (focus(t, abs(s,ty,m))) = | |
| 261 | focus_up_right (focus(Abs(s,ty,t), m)) | |
| 262 | | focus_up_right1 (focus(t, root)) = | |
| 263 | raise out_of_term_exception "focus_up_right1"; | |
| 264 | ||
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 265 | (* move focus to the bottom left through abstractions *) | 
| 15481 | 266 | fun focus_bot_left_leaf (ft as focus(t, _)) = | 
| 267 | focus_bot_left_leaf (focus_left ft) | |
| 268 | handle out_of_term_exception _=> ft; | |
| 269 | ||
| 15814 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 270 | (* move focus to the bottom left, but not into abstractions *) | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 271 | fun focus_bot_left_nonabs_leaf (ft as focus(t, _)) = | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 272 | focus_bot_left_nonabs_leaf (focus_strict_left ft) | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 273 | handle out_of_term_exception _=> ft; | 
| 
d65f461c8672
lucas - fixed a big with renaming of bound variables. Other small changes.
 dixon parents: 
15632diff
changeset | 274 | |
| 15481 | 275 | (* focus tools for working directly with the focus representation *) | 
| 15531 | 276 | fun focus_up_appr (focus(t, appl(l,m))) = NONE | 
| 277 | | focus_up_appr (focus(t, appr(r,m))) = SOME (focus(t$r, m)) | |
| 278 | | focus_up_appr (focus(t, abs(s,ty,m))) = NONE | |
| 279 | | focus_up_appr (focus(t, root)) = NONE; | |
| 15481 | 280 | |
| 15531 | 281 | fun focus_up_appl (focus(t, appl(l,m))) = SOME (focus(l$t, m)) | 
| 282 | | focus_up_appl (focus(t, appr(r,m))) = NONE | |
| 283 | | focus_up_appl (focus(t, abs(s,ty,m))) = NONE | |
| 284 | | focus_up_appl (focus(t, root)) = NONE; | |
| 15481 | 285 | |
| 15531 | 286 | fun focus_up_abs (focus(t, appl(l,m))) = NONE | 
| 287 | | focus_up_abs (focus(t, appr(r,m))) = NONE | |
| 15481 | 288 | | focus_up_abs (focus(t, abs(s,ty,m))) = | 
| 15531 | 289 | SOME (focus_up (focus(Abs(s,ty,t), m))) | 
| 290 | | focus_up_abs (focus(t, root)) = NONE; | |
| 15481 | 291 | |
| 15531 | 292 | fun focus_up_abs_or_appr (focus(t, appl(l,m))) = NONE | 
| 293 | | focus_up_abs_or_appr (focus(t, appr(r,m))) = SOME (focus(t$r, m)) | |
| 15481 | 294 | | focus_up_abs_or_appr (focus(t, abs(s,ty,m))) = | 
| 17044 
94d38d9fac40
lucas - fixed bug in changing focus - when moving up and right, if an abs was encountered it would move up an extra time. I also removed the spurious pretty printing function that did nothing.
 dixon parents: 
16179diff
changeset | 295 | SOME (focus(Abs(s,ty,t), m)) | 
| 15531 | 296 | | focus_up_abs_or_appr (focus(t, root)) = NONE; | 
| 15481 | 297 | |
| 298 | ||
| 299 | fun tyenv_of_focus (focus(t, u)) = tyenv_of_upterm u; | |
| 300 | fun tyenv_of_focus' (focus(t, u)) = tyenv_of_upterm' u; | |
| 301 | ||
| 302 | (* return the Term.type of the focus term, computes bound vars type, | |
| 303 | does a quick check only. *) | |
| 304 | (* fun fastype_of_focus (focus(t, m)) = | |
| 305 | let | |
| 306 | fun boundtypes_of_upterm (abs(s,ty,m)) = | |
| 307 | ty::(boundtypes_of_upterm m) | |
| 308 | | boundtypes_of_upterm (appl(t,m)) = | |
| 309 | boundtypes_of_upterm m | |
| 310 | | boundtypes_of_upterm (appr(t,m)) = | |
| 311 | boundtypes_of_upterm m | |
| 312 | | boundtypes_of_upterm (root) = [] | |
| 313 | in | |
| 314 | fastype_of1 ((boundtypes_of_upterm m), t) | |
| 315 | end; *) | |
| 316 | ||
| 317 | (* gets the next left hand side term, or throws an exception *) | |
| 318 | fun next_leaf_fcterm ft = focus_bot_left_leaf (focus_up_right ft); | |
| 319 | ||
| 320 | fun next_leaf_of_fcterm_seq_aux t () = | |
| 321 | let val nextt = next_leaf_fcterm t | |
| 322 | in | |
| 15531 | 323 | SOME (nextt, Seq.make (next_leaf_of_fcterm_seq_aux nextt)) | 
| 324 | end handle out_of_term_exception _ => NONE; | |
| 15481 | 325 | |
| 326 | (* sequence of next upterms from start upterm... | |
| 327 | ie a sequence of all leafs after this one*) | |
| 328 | fun next_leaf_of_fcterm_seq in_t = | |
| 329 | Seq.make (next_leaf_of_fcterm_seq_aux in_t); | |
| 330 | ||
| 331 | (* returns a sequence of all leaf up terms from term, ie DFS on | |
| 332 | leafs of term, ie uses time O(n), n = sizeof term. *) | |
| 333 | fun leaf_seq_of_fcterm in_t = | |
| 334 | let | |
| 335 | val botleft = (focus_bot_left_leaf in_t) | |
| 336 | in | |
| 337 | Seq.cons (botleft, (Seq.make (next_leaf_of_fcterm_seq_aux botleft)) ) | |
| 338 | end; | |
| 339 | ||
| 340 | fun upsize_of_fcterm (focus(t, ut)) = upsize_of_upterm ut; | |
| 341 | ||
| 342 | end; (* local *) | |
| 343 | ||
| 344 | end; (* functor *) | |
| 345 | ||
| 346 | ||
| 347 | ||
| 348 | ||
| 349 | ||
| 350 | (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) | |
| 351 | (* focus term encoding sturcture for isabelle terms *) | |
| 352 | structure EncodeIsaFTerm : F_ENCODE_TERM_SIG = | |
| 353 | struct | |
| 354 | infix 9 $; | |
| 355 | ||
| 356 | type term = Term.term; | |
| 357 | ||
| 358 | type TypeT = Term.typ; | |
| 359 | ||
| 360 | datatype LeafT = lConst of string * Term.typ | |
| 361 | | lVar of ((string * int) * Term.typ) | |
| 362 | | lFree of (string * Term.typ) | |
| 363 | | lBound of int; | |
| 364 | ||
| 365 | datatype TermT = op $ of TermT * TermT | |
| 366 | | Abs of string * TypeT * TermT | |
| 367 | | lf of LeafT; | |
| 368 | ||
| 369 |   fun fakebounds (s, ty) t = subst_bound (Free(":" ^ s, ty), t);
 | |
| 370 | ||
| 371 | fun encode (Term.$(a,b)) = (encode a) $ (encode b) | |
| 372 | | encode (Term.Abs(s,ty,t)) = Abs(s,ty,(encode t)) | |
| 373 | | encode (Term.Const(s,ty)) = lf(lConst(s,ty)) | |
| 374 | | encode (Term.Var((s,i),ty)) = lf(lVar((s,i),ty)) | |
| 375 | | encode (Term.Free(s,ty)) = lf(lFree(s,ty)) | |
| 376 | | encode (Term.Bound i) = lf(lBound i); | |
| 377 | ||
| 378 | fun decode (a $ b) = Term.$(decode a, decode b) | |
| 379 | | decode (Abs(s,ty,t)) = (Term.Abs(s,ty,decode t)) | |
| 380 | | decode (lf(lConst(s,ty))) = Term.Const(s,ty) | |
| 381 | | decode (lf(lVar((s,i),ty))) = Term.Var((s,i),ty) | |
| 382 | | decode (lf(lFree(s,ty))) = (Term.Free(s,ty)) | |
| 383 | | decode (lf(lBound i)) = (Term.Bound i); | |
| 384 | ||
| 385 | end; | |
| 386 |