src/Tools/Compute_Oracle/am_compiler.ML
author haftmann
Sat, 15 Sep 2007 19:27:35 +0200
changeset 24584 01e83ffa6c54
parent 23663 84b5c89b8b49
child 25217 3224db6415ae
permissions -rw-r--r--
fixed title
haftmann@24584
     1
(*  Title:      Tools/Compute_Oracle/am_compiler.ML
wenzelm@23174
     2
    ID:         $Id$
wenzelm@23174
     3
    Author:     Steven Obua
wenzelm@23174
     4
*)
wenzelm@23174
     5
wenzelm@23174
     6
signature COMPILING_AM = 
wenzelm@23174
     7
sig
wenzelm@23174
     8
  include ABSTRACT_MACHINE
wenzelm@23174
     9
obua@23663
    10
  val set_compiled_rewriter : (term -> term) -> unit
wenzelm@23174
    11
  val list_nth : 'a list * int -> 'a
wenzelm@23174
    12
  val list_map : ('a -> 'b) -> 'a list -> 'b list
wenzelm@23174
    13
end
wenzelm@23174
    14
wenzelm@23174
    15
structure AM_Compiler : COMPILING_AM = struct
wenzelm@23174
    16
wenzelm@23174
    17
val list_nth = List.nth;
wenzelm@23174
    18
val list_map = map;
wenzelm@23174
    19
obua@23663
    20
open AbstractMachine;
wenzelm@23174
    21
obua@23663
    22
val compiled_rewriter = ref (NONE:(term -> term)Option.option)
wenzelm@23174
    23
wenzelm@23174
    24
fun set_compiled_rewriter r = (compiled_rewriter := SOME r)
wenzelm@23174
    25
wenzelm@23174
    26
type program = (term -> term)
wenzelm@23174
    27
wenzelm@23174
    28
wenzelm@23174
    29
(*Returns true iff at most 0 .. (free-1) occur unbound. therefore
wenzelm@23174
    30
  check_freevars 0 t iff t is closed*)
wenzelm@23174
    31
fun check_freevars free (Var x) = x < free
wenzelm@23174
    32
  | check_freevars free (Const c) = true
wenzelm@23174
    33
  | check_freevars free (App (u, v)) = check_freevars free u andalso check_freevars free v
wenzelm@23174
    34
  | check_freevars free (Abs m) = check_freevars (free+1) m
wenzelm@23174
    35
wenzelm@23174
    36
fun count_patternvars PVar = 1
wenzelm@23174
    37
  | count_patternvars (PConst (_, ps)) =
wenzelm@23174
    38
      List.foldl (fn (p, count) => (count_patternvars p)+count) 0 ps
wenzelm@23174
    39
wenzelm@23174
    40
fun print_rule (p, t) = 
wenzelm@23174
    41
    let	
wenzelm@23174
    42
	fun str x = Int.toString x		    
wenzelm@23174
    43
	fun print_pattern n PVar = (n+1, "x"^(str n))
wenzelm@23174
    44
	  | print_pattern n (PConst (c, [])) = (n, "c"^(str c))
wenzelm@23174
    45
	  | print_pattern n (PConst (c, args)) = 
wenzelm@23174
    46
	    let
wenzelm@23174
    47
		val h = print_pattern n (PConst (c,[]))
wenzelm@23174
    48
	    in
wenzelm@23174
    49
		print_pattern_list h args
wenzelm@23174
    50
	    end
wenzelm@23174
    51
	and print_pattern_list r [] = r
wenzelm@23174
    52
	  | print_pattern_list (n, p) (t::ts) = 
wenzelm@23174
    53
	    let
wenzelm@23174
    54
		val (n, t) = print_pattern n t
wenzelm@23174
    55
	    in
wenzelm@23174
    56
		print_pattern_list (n, "App ("^p^", "^t^")") ts
wenzelm@23174
    57
	    end
wenzelm@23174
    58
wenzelm@23174
    59
	val (n, pattern) = print_pattern 0 p
wenzelm@23174
    60
	val pattern =
wenzelm@23174
    61
            if exists_string Symbol.is_ascii_blank pattern then "(" ^ pattern ^")"
wenzelm@23174
    62
            else pattern
wenzelm@23174
    63
	
wenzelm@23174
    64
	fun print_term d (Var x) = (*if x < d then "Var "^(str x) else "x"^(str (n-(x-d)-1))*)
wenzelm@23174
    65
              "Var " ^ str x
wenzelm@23174
    66
	  | print_term d (Const c) = "c" ^ str c
wenzelm@23174
    67
	  | print_term d (App (a,b)) = "App (" ^ print_term d a ^ ", " ^ print_term d b ^ ")"
wenzelm@23174
    68
	  | print_term d (Abs c) = "Abs (" ^ print_term (d + 1) c ^ ")"
wenzelm@23174
    69
wenzelm@23174
    70
	fun listvars n = if n = 0 then "x0" else "x"^(str n)^", "^(listvars (n-1))
wenzelm@23174
    71
wenzelm@23174
    72
	val term = print_term 0 t
wenzelm@23174
    73
	val term =
wenzelm@23174
    74
            if n > 0 then "Closure (["^(listvars (n-1))^"], "^term^")"
wenzelm@23174
    75
            else "Closure ([], "^term^")"
wenzelm@23174
    76
			   
wenzelm@23174
    77
    in
obua@23663
    78
	"  | weak_reduce (false, stack, "^pattern^") = Continue (false, stack, "^term^")"
wenzelm@23174
    79
    end
wenzelm@23174
    80
wenzelm@23174
    81
fun constants_of PVar = []
wenzelm@23174
    82
  | constants_of (PConst (c, ps)) = c :: maps constants_of ps
wenzelm@23174
    83
wenzelm@23174
    84
fun constants_of_term (Var _) = []
wenzelm@23174
    85
  | constants_of_term (Abs m) = constants_of_term m
wenzelm@23174
    86
  | constants_of_term (App (a,b)) = (constants_of_term a)@(constants_of_term b)
wenzelm@23174
    87
  | constants_of_term (Const c) = [c]
wenzelm@23174
    88
    
wenzelm@23174
    89
fun load_rules sname name prog = 
wenzelm@23174
    90
    let
wenzelm@23174
    91
	val buffer = ref ""
wenzelm@23174
    92
	fun write s = (buffer := (!buffer)^s)
wenzelm@23174
    93
	fun writeln s = (write s; write "\n")
wenzelm@23174
    94
	fun writelist [] = ()
wenzelm@23174
    95
	  | writelist (s::ss) = (writeln s; writelist ss)
wenzelm@23174
    96
	fun str i = Int.toString i
wenzelm@23174
    97
	val _ = writelist [
wenzelm@23174
    98
		"structure "^name^" = struct",
wenzelm@23174
    99
		"",
obua@23663
   100
		"datatype term = Dummy | App of term * term | Abs of term | Var of int | Const of int | Closure of term list * term"]
wenzelm@23174
   101
	val constants = distinct (op =) (maps (fn (p, r) => ((constants_of p)@(constants_of_term r))) prog)
wenzelm@23174
   102
	val _ = map (fn x => write (" | c"^(str x))) constants
wenzelm@23174
   103
	val _ = writelist [
wenzelm@23174
   104
		"",
wenzelm@23174
   105
		"datatype stack = SEmpty | SAppL of term * stack | SAppR of term * stack | SAbs of stack",
obua@23663
   106
		"",
obua@23663
   107
		"type state = bool * stack * term",
obua@23663
   108
		"",
obua@23663
   109
		"datatype loopstate = Continue of state | Stop of stack * term",
obua@23663
   110
		"",
obua@23663
   111
		"fun proj_C (Continue s) = s",
obua@23663
   112
		"  | proj_C _ = raise Match",
obua@23663
   113
		"",
obua@23663
   114
		"fun proj_S (Stop s) = s",
obua@23663
   115
		"  | proj_S _ = raise Match",
obua@23663
   116
		"",
obua@23663
   117
		"fun cont (Continue _) = true",
obua@23663
   118
		"  | cont _ = false",
obua@23663
   119
		"",
obua@23663
   120
		"fun do_reduction reduce p =",
obua@23663
   121
		"    let",
obua@23663
   122
		"       val s = ref (Continue p)",
obua@23663
   123
		"       val _ = while cont (!s) do (s := reduce (proj_C (!s)))",
obua@23663
   124
		"   in",
obua@23663
   125
		"       proj_S (!s)",
obua@23663
   126
		"   end",
wenzelm@23174
   127
		""]
obua@23663
   128
wenzelm@23174
   129
	val _ = writelist [
obua@23663
   130
		"fun weak_reduce (false, stack, Closure (e, App (a, b))) = Continue (false, SAppL (Closure (e, b), stack), Closure (e, a))",
obua@23663
   131
		"  | weak_reduce (false, SAppL (b, stack), Closure (e, Abs m)) = Continue (false, stack, Closure (b::e, m))",
obua@23663
   132
		"  | weak_reduce (false, stack, c as Closure (e, Abs m)) = Continue (true, stack, c)",
obua@23663
   133
		"  | weak_reduce (false, stack, Closure (e, Var n)) = Continue (false, stack, case "^sname^".list_nth (e, n) of Dummy => Var n | r => r)",
obua@23663
   134
		"  | weak_reduce (false, stack, Closure (e, c)) = Continue (false, stack, c)"]
obua@23663
   135
	val _ = writelist (map print_rule prog)
obua@23663
   136
        val _ = writelist [
obua@23663
   137
		"  | weak_reduce (false, stack, clos) = Continue (true, stack, clos)",
obua@23663
   138
		"  | weak_reduce (true, SAppR (a, stack), b) = Continue (false, stack, App (a,b))",
obua@23663
   139
		"  | weak_reduce (true, s as (SAppL (b, stack)), a) = Continue (false, SAppR (a, stack), b)",
obua@23663
   140
		"  | weak_reduce (true, stack, c) = Stop (stack, c)",
wenzelm@23174
   141
		"",
obua@23663
   142
		"fun strong_reduce (false, stack, Closure (e, Abs m)) =",
wenzelm@23174
   143
		"    let",
obua@23663
   144
		"        val (stack', wnf) = do_reduction weak_reduce (false, SEmpty, Closure (Dummy::e, m))",
wenzelm@23174
   145
		"    in",
obua@23663
   146
		"        case stack' of",
obua@23663
   147
		"            SEmpty => Continue (false, SAbs stack, wnf)",
obua@23663
   148
		"          | _ => raise ("^sname^".Run \"internal error in strong: weak failed\")",
obua@23663
   149
		"    end",		
obua@23663
   150
		"  | strong_reduce (false, stack, clos as (App (u, v))) = Continue (false, SAppL (v, stack), u)",
obua@23663
   151
		"  | strong_reduce (false, stack, clos) = Continue (true, stack, clos)",
obua@23663
   152
		"  | strong_reduce (true, SAbs stack, m) = Continue (false, stack, Abs m)",
obua@23663
   153
		"  | strong_reduce (true, SAppL (b, stack), a) = Continue (false, SAppR (a, stack), b)",
obua@23663
   154
		"  | strong_reduce (true, SAppR (a, stack), b) = Continue (true, stack, App (a, b))",
obua@23663
   155
		"  | strong_reduce (true, stack, clos) = Stop (stack, clos)",
wenzelm@23174
   156
		""]
wenzelm@23174
   157
	
wenzelm@23174
   158
	val ic = "(case c of "^(implode (map (fn c => (str c)^" => c"^(str c)^" | ") constants))^" _ => Const c)"						  	
wenzelm@23174
   159
	val _ = writelist [
wenzelm@23174
   160
		"fun importTerm ("^sname^".Var x) = Var x",
wenzelm@23174
   161
		"  | importTerm ("^sname^".Const c) =  "^ic,
wenzelm@23174
   162
		"  | importTerm ("^sname^".App (a, b)) = App (importTerm a, importTerm b)",
wenzelm@23174
   163
		"  | importTerm ("^sname^".Abs m) = Abs (importTerm m)",
wenzelm@23174
   164
		""]
wenzelm@23174
   165
obua@23663
   166
	fun ec c = "  | exportTerm c"^(str c)^" = "^sname^".Const "^(str c)
wenzelm@23174
   167
	val _ = writelist [
obua@23663
   168
		"fun exportTerm (Var x) = "^sname^".Var x",
obua@23663
   169
		"  | exportTerm (Const c) = "^sname^".Const c",
obua@23663
   170
		"  | exportTerm (App (a,b)) = "^sname^".App (exportTerm a, exportTerm b)",
obua@23663
   171
		"  | exportTerm (Abs m) = "^sname^".Abs (exportTerm m)",
obua@23663
   172
		"  | exportTerm (Closure (closlist, clos)) = raise ("^sname^".Run \"internal error, cannot export Closure\")",
obua@23663
   173
		"  | exportTerm Dummy = raise ("^sname^".Run \"internal error, cannot export Dummy\")"]
wenzelm@23174
   174
	val _ = writelist (map ec constants)
wenzelm@23174
   175
		
wenzelm@23174
   176
	val _ = writelist [
wenzelm@23174
   177
		"",
wenzelm@23174
   178
		"fun rewrite t = ",
wenzelm@23174
   179
		"    let",
obua@23663
   180
		"      val (stack, wnf) = do_reduction weak_reduce (false, SEmpty, Closure ([], importTerm t))",
wenzelm@23174
   181
		"    in",
wenzelm@23174
   182
		"      case stack of ",
obua@23663
   183
		"           SEmpty => (case do_reduction strong_reduce (false, SEmpty, wnf) of",
wenzelm@23174
   184
		"                          (SEmpty, snf) => exportTerm snf",
wenzelm@23174
   185
		"                        | _ => raise ("^sname^".Run \"internal error in rewrite: strong failed\"))",
wenzelm@23174
   186
		"         | _ => (raise ("^sname^".Run \"internal error in rewrite: weak failed\"))",
wenzelm@23174
   187
		"    end",
wenzelm@23174
   188
		"",
wenzelm@23174
   189
		"val _ = "^sname^".set_compiled_rewriter rewrite",
wenzelm@23174
   190
		"",
wenzelm@23174
   191
		"end;"]
wenzelm@23174
   192
wenzelm@23174
   193
    in
wenzelm@23174
   194
	compiled_rewriter := NONE;	
wenzelm@23174
   195
	use_text "" Output.ml_output false (!buffer);
wenzelm@23174
   196
	case !compiled_rewriter of 
wenzelm@23174
   197
	    NONE => raise (Compile "cannot communicate with compiled function")
obua@23663
   198
	  | SOME r => (compiled_rewriter := NONE; r)
wenzelm@23174
   199
    end	
wenzelm@23174
   200
wenzelm@23174
   201
fun compile eqs = 
wenzelm@23174
   202
    let
obua@23663
   203
	val _ = if exists (fn (a,b,c) => not (null a)) eqs then raise Compile ("cannot deal with guards") else ()
obua@23663
   204
	val eqs = map (fn (a,b,c) => (b,c)) eqs
obua@23663
   205
	fun check (p, r) = if check_freevars (count_patternvars p) r then () else raise Compile ("unbound variables in rule") 
wenzelm@23174
   206
	val _ = map (fn (p, r) => 
obua@23663
   207
                  (check (p, r); 
obua@23663
   208
                   case p of PVar => raise (Compile "pattern is just a variable") | _ => ())) eqs
wenzelm@23174
   209
    in
wenzelm@23174
   210
	load_rules "AM_Compiler" "AM_compiled_code" eqs
wenzelm@23174
   211
    end	
wenzelm@23174
   212
wenzelm@23174
   213
fun run prog t = (prog t)
obua@23663
   214
obua@23663
   215
fun discard p = ()
wenzelm@23174
   216
			 	  
wenzelm@23174
   217
end
wenzelm@23174
   218