src/Pure/Syntax/ast.ML
changeset 11733 9dd88f3aa8e0
parent 10913 57eb8c1d6f88
child 12262 11ff5f47df6e
equal deleted inserted replaced
11732:139aaced13f4 11733:9dd88f3aa8e0
   199 (*the normalizer works yoyo-like: top-down, bottom-up, top-down, ...*)
   199 (*the normalizer works yoyo-like: top-down, bottom-up, top-down, ...*)
   200 
   200 
   201 fun normalize trace stat get_rules pre_ast =
   201 fun normalize trace stat get_rules pre_ast =
   202   let
   202   let
   203     val passes = ref 0;
   203     val passes = ref 0;
   204     val lookups = ref 0;
       
   205     val failed_matches = ref 0;
   204     val failed_matches = ref 0;
   206     val changes = ref 0;
   205     val changes = ref 0;
   207 
   206 
   208     fun subst _ (ast as Constant _) = ast
   207     fun subst _ (ast as Constant _) = ast
   209       | subst env (Variable x) = the (Symtab.lookup (env, x))
   208       | subst env (Variable x) = the (Symtab.lookup (env, x))
   210       | subst env (Appl asts) = Appl (map (subst env) asts);
   209       | subst env (Appl asts) = Appl (map (subst env) asts);
   211 
   210 
   212     fun try_rules ast ((lhs, rhs) :: pats) =
   211     fun try_rules ((lhs, rhs) :: pats) ast =
   213           (case match ast lhs of
   212           (case match ast lhs of
   214             Some (env, args) =>
   213             Some (env, args) =>
   215               (inc changes; Some (mk_appl (subst env rhs) args))
   214               (inc changes; Some (mk_appl (subst env rhs) args))
   216           | None => (inc failed_matches; try_rules ast pats))
   215           | None => (inc failed_matches; try_rules pats ast))
   217       | try_rules _ [] = None;
   216       | try_rules [] _ = None;
   218 
   217     val try_headless_rules = try_rules (get_rules "");
   219     fun try ast a = (inc lookups; try_rules ast (get_rules a));
   218 
       
   219     fun try ast a =
       
   220       (case try_rules (get_rules a) ast of
       
   221         None => try_headless_rules ast
       
   222       | some => some);
   220 
   223 
   221     fun rewrite (ast as Constant a) = try ast a
   224     fun rewrite (ast as Constant a) = try ast a
   222       | rewrite (ast as Variable a) = try ast a
   225       | rewrite (ast as Variable a) = try ast a
   223       | rewrite (ast as Appl (Constant a :: _)) = try ast a
   226       | rewrite (ast as Appl (Constant a :: _)) = try ast a
   224       | rewrite (ast as Appl (Variable a :: _)) = try ast a
   227       | rewrite (ast as Appl (Variable a :: _)) = try ast a
   225       | rewrite ast = try ast "";
   228       | rewrite ast = try_headless_rules ast;
   226 
   229 
   227     fun rewrote old_ast new_ast =
   230     fun rewrote old_ast new_ast =
   228       if trace then
   231       if trace then
   229         writeln ("rewrote: " ^ str_of_ast old_ast ^ "  ->  " ^ str_of_ast new_ast)
   232         writeln ("rewrote: " ^ str_of_ast old_ast ^ "  ->  " ^ str_of_ast new_ast)
   230       else ();
   233       else ();
   260     val post_ast = normal pre_ast;
   263     val post_ast = normal pre_ast;
   261   in
   264   in
   262     if trace orelse stat then
   265     if trace orelse stat then
   263       writeln ("post: " ^ str_of_ast post_ast ^ "\nnormalize: " ^
   266       writeln ("post: " ^ str_of_ast post_ast ^ "\nnormalize: " ^
   264         string_of_int (! passes) ^ " passes, " ^
   267         string_of_int (! passes) ^ " passes, " ^
   265         string_of_int (! lookups) ^ " lookups, " ^
       
   266         string_of_int (! changes) ^ " changes, " ^
   268         string_of_int (! changes) ^ " changes, " ^
   267         string_of_int (! failed_matches) ^ " matches failed")
   269         string_of_int (! failed_matches) ^ " matches failed")
   268     else ();
   270     else ();
   269     post_ast
   271     post_ast
   270   end;
   272   end;