src/Pure/IsaPlanner/upterm_lib.ML
changeset 15481 fc075ae929e4
child 16179 fa7e70be26b0
equal deleted inserted replaced
15480:cb3612cc41a3 15481:fc075ae929e4
       
     1 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) 
       
     2 (*  Title:      libs/upterm_lib.ML
       
     3     Author:     Lucas Dixon, University of Edinburgh
       
     4                 lucas.dixon@ed.ac.uk
       
     5     Created:    26 Jan 2004
       
     6 *)
       
     7 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *) 
       
     8 (*  DESCRIPTION:
       
     9 
       
    10     generic upterms for lambda calculus  
       
    11 
       
    12 *)   
       
    13 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *)
       
    14 
       
    15 
       
    16 signature UPTERM_LIB = 
       
    17 sig
       
    18        
       
    19 
       
    20   (* type for upterms defined in terms of a 't : a downterm type, and 
       
    21      'y : types for bound variable in the downterm type *)
       
    22   datatype ('t,'y) T =
       
    23            abs of string * 'y * (('t,'y) T)
       
    24          | appl of 't * (('t,'y) T)
       
    25          | appr of 't * (('t,'y) T)
       
    26          | root
       
    27 
       
    28   (* analysis *)
       
    29   val tyenv_of_upterm : ('t,'y) T -> (string * 'y) list
       
    30   val tyenv_of_upterm' : ('t,'y) T -> 'y list
       
    31   val addr_of_upterm : ('t,'y) T -> int list
       
    32   val upsize_of_upterm : ('t,'y) T -> int
       
    33   
       
    34   (* editing *)
       
    35   val map_to_upterm_parts : ('t -> 't2) * ('y -> 'y2)  -> 
       
    36 														('t,'y) T -> ('t2,'y2) T
       
    37 
       
    38   val expand_map_to_upterm_parts : ('t -> 't2 list) * ('y -> 'y2)  -> 
       
    39 																	 ('t,'y) T -> ('t2,'y2) T list
       
    40 
       
    41   val fold_upterm : ('a * 't -> 'a) -> (* left *)
       
    42                     ('a * 't -> 'a) ->  (* right *)
       
    43                     ('a * (string * 'y) -> 'a) -> (* abs *)
       
    44                     ('a * ('t,'y) T) -> 'a (* everything *)
       
    45 
       
    46   (* apply one term to another *)
       
    47   val apply : ('t,'y) T -> ('t,'y) T -> ('t,'y) T
       
    48 
       
    49 end;
       
    50 
       
    51 
       
    52 
       
    53 (* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- *)
       
    54 structure UpTermLib : UPTERM_LIB =
       
    55 struct 
       
    56 
       
    57   (* type for upterms defined in terms of a 't : a downterm type, and 
       
    58      'y : types for bound variable in the downterm type *)
       
    59   datatype ('t,'y) T =
       
    60            abs of string * 'y * ('t,'y) T
       
    61          | appl of 't * ('t,'y) T
       
    62          | appr of 't * ('t,'y) T
       
    63          | root;
       
    64 
       
    65   (* get the bound variable names and types for the current foucs *)
       
    66   fun tyenv_of_upterm (appl(l,m)) = tyenv_of_upterm m
       
    67     | tyenv_of_upterm (appr(r,m)) = tyenv_of_upterm m
       
    68     | tyenv_of_upterm (abs(s,ty,m)) = (s, ty) :: (tyenv_of_upterm m)
       
    69     | tyenv_of_upterm root = [];
       
    70 
       
    71   (* get the bound variable types for the current foucs *)
       
    72   fun tyenv_of_upterm' (appl(l,m)) = tyenv_of_upterm' m
       
    73     | tyenv_of_upterm' (appr(r,m)) = tyenv_of_upterm' m
       
    74     | tyenv_of_upterm' (abs(s,ty,m)) = ty :: (tyenv_of_upterm' m)
       
    75     | tyenv_of_upterm' root = [];
       
    76 
       
    77   (* an address construction for the upterm, ie if we were at the
       
    78      root, address describes how to get to this point. *)
       
    79   fun addr_of_upterm1 A root = A
       
    80     | addr_of_upterm1 A (appl (l,m)) = addr_of_upterm1 (1::A) m
       
    81     | addr_of_upterm1 A (appr (r,m)) = addr_of_upterm1 (2::A) m
       
    82     | addr_of_upterm1 A (abs (s,ty,m)) = addr_of_upterm1 (0::A) m;
       
    83 
       
    84   fun addr_of_upterm m = addr_of_upterm1 [] m;
       
    85 
       
    86   (* the size of the upterm, ie how far to get to root *)
       
    87   fun upsize_of_upterm root = 0
       
    88     | upsize_of_upterm (appl (l,m)) = (upsize_of_upterm m) + 1
       
    89     | upsize_of_upterm (appr (r,m)) = (upsize_of_upterm m) + 1
       
    90     | upsize_of_upterm (abs (s,ty,m)) = (upsize_of_upterm m) + 1;
       
    91 
       
    92   (* apply an upterm to to another upterm *)
       
    93   fun apply x root = x
       
    94     | apply x (appl (l,m)) = appl(l, apply x m)
       
    95     | apply x (appr (r,m)) = appr(r, apply x m)
       
    96     | apply x (abs (s,ty,m)) = abs(s, ty, apply x m);
       
    97 
       
    98   (* applies the term function to each term in each part of the upterm *)
       
    99   fun map_to_upterm_parts (tf,yf) root = root
       
   100 
       
   101     | map_to_upterm_parts (tf,yf) (abs(s,ty,m)) = 
       
   102       abs(s,yf ty,map_to_upterm_parts (tf,yf) m)
       
   103 
       
   104     | map_to_upterm_parts (tf,yf) (appr(t,m)) = 
       
   105       appr (tf t, map_to_upterm_parts (tf,yf) m)
       
   106 
       
   107     | map_to_upterm_parts (tf,yf) (appl(t,m)) = 
       
   108       appl (tf t, map_to_upterm_parts (tf,yf) m);
       
   109 
       
   110 
       
   111   (* applies the term function to each term in each part of the upterm *)
       
   112   fun expand_map_to_upterm_parts (tf,yf) root = [root]
       
   113     | expand_map_to_upterm_parts (tf,yf) (abs(s,ty,m)) = 
       
   114 			map (fn x => abs(s,yf ty, x)) 
       
   115 					(expand_map_to_upterm_parts (tf,yf) m)
       
   116     | expand_map_to_upterm_parts (tf,yf) (appr(t,m)) = 
       
   117       map appr (IsaPLib.all_pairs 
       
   118 									(tf t) (expand_map_to_upterm_parts (tf,yf) m))
       
   119     | expand_map_to_upterm_parts (tf,yf) (appl(t,m)) = 
       
   120       map appl (IsaPLib.all_pairs 
       
   121 									(tf t) (expand_map_to_upterm_parts (tf,yf) m));
       
   122 
       
   123   (* fold along each 't (down term) in the upterm *)
       
   124 	fun fold_upterm fl fr fa (d, u) = 
       
   125       let 
       
   126 	      fun fold_upterm' (d, root) = d
       
   127 		      | fold_upterm' (d, abs(s,ty,m)) = fold_upterm' (fa(d,(s,ty)), m)
       
   128 		      | fold_upterm' (d, appr(t,m)) = fold_upterm' (fr(d,t), m)
       
   129 		      | fold_upterm' (d, appl(t,m)) = fold_upterm' (fl(d,t), m)
       
   130       in fold_upterm' (d,u) end;
       
   131 
       
   132 end;