src/Pure/Syntax/ast.ML
author wenzelm
Sat, 07 Dec 2024 23:50:18 +0100
changeset 81558 b57996a0688c
parent 81241 3b49bf00c8e4
permissions -rw-r--r--
clarified term positions and markup: syntax = true means this is via concrete syntax; clarified text color rendering;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
     1
(*  Title:      Pure/Syntax/ast.ML
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
     2
    Author:     Markus Wenzel, TU Muenchen
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
     3
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
     4
Abstract syntax trees, translation rules, matching and normalization of asts.
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
     5
*)
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
     6
42224
578a51fae383 discontinued special treatment of structure Ast: no pervasive content, no inclusion in structure Syntax;
wenzelm
parents: 42048
diff changeset
     7
signature AST =
16609
c787112bba1f removed obsolete (un)fold_ast2;
wenzelm
parents: 15973
diff changeset
     8
sig
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
     9
  datatype ast =
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    10
    Constant of string |
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    11
    Variable of string |
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    12
    Appl of ast list
42224
578a51fae383 discontinued special treatment of structure Ast: no pervasive content, no inclusion in structure Syntax;
wenzelm
parents: 42048
diff changeset
    13
  val mk_appl: ast -> ast list -> ast
81210
8635ed5e4613 tuned signature;
wenzelm
parents: 81208
diff changeset
    14
  val constrain: ast -> ast -> ast
258
e540b7d4ecb1 minor internal changes;
wenzelm
parents: 235
diff changeset
    15
  exception AST of string * ast list
80881
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    16
  val ast_ord: ast ord
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    17
  structure Table: TABLE
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    18
  structure Set: SET
81153
ee8c3375cd39 clarified signature;
wenzelm
parents: 81152
diff changeset
    19
  val pretty_var: string -> Pretty.T
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    20
  val pretty_ast: ast -> Pretty.T
258
e540b7d4ecb1 minor internal changes;
wenzelm
parents: 235
diff changeset
    21
  val pretty_rule: ast * ast -> Pretty.T
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
    22
  val strip_positions: ast -> ast
81152
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
    23
  val rule_index: ast * ast -> string
42224
578a51fae383 discontinued special treatment of structure Ast: no pervasive content, no inclusion in structure Syntax;
wenzelm
parents: 42048
diff changeset
    24
  val rule_error: ast * ast -> string option
10913
57eb8c1d6f88 export fold_ast etc.;
wenzelm
parents: 9372
diff changeset
    25
  val fold_ast: string -> ast list -> ast
57eb8c1d6f88 export fold_ast etc.;
wenzelm
parents: 9372
diff changeset
    26
  val fold_ast_p: string -> ast list * ast -> ast
57eb8c1d6f88 export fold_ast etc.;
wenzelm
parents: 9372
diff changeset
    27
  val unfold_ast: string -> ast -> ast list
57eb8c1d6f88 export fold_ast etc.;
wenzelm
parents: 9372
diff changeset
    28
  val unfold_ast_p: string -> ast -> ast list * ast
42277
7503beeffd8d tuned signature;
wenzelm
parents: 42264
diff changeset
    29
  val trace: bool Config.T
43347
f18cf88453d6 tuned name (cf. blast_stats);
wenzelm
parents: 42277
diff changeset
    30
  val stats: bool Config.T
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
    31
  val normalize: Proof.context -> {permissive_constraints: bool} ->
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
    32
    (string -> (ast * ast) list) -> ast -> ast
16609
c787112bba1f removed obsolete (un)fold_ast2;
wenzelm
parents: 15973
diff changeset
    33
end;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    34
42224
578a51fae383 discontinued special treatment of structure Ast: no pervasive content, no inclusion in structure Syntax;
wenzelm
parents: 42048
diff changeset
    35
structure Ast: AST =
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    36
struct
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    37
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    38
(** abstract syntax trees **)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    39
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    40
(*asts come in two flavours:
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    41
   - ordinary asts representing terms and typs: Variables are (often) treated
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    42
     like Constants;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    43
   - patterns used as lhs and rhs in rules: Variables are placeholders for
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    44
     proper asts*)
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    45
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    46
datatype ast =
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    47
  Constant of string |    (*"not", "_abs", "fun"*)
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    48
  Variable of string |    (*x, ?x, 'a, ?'a*)
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    49
  Appl of ast list;       (*(f x y z), ("fun" 'a 'b), ("_abs" x t)*)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    50
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    51
(*the list of subasts of an Appl node has to contain at least 2 elements, i.e.
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    52
  there are no empty asts or nullary applications; use mk_appl for convenience*)
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    53
fun mk_appl f [] = f
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    54
  | mk_appl f args = Appl (f :: args);
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    55
81210
8635ed5e4613 tuned signature;
wenzelm
parents: 81208
diff changeset
    56
fun constrain a b = Appl [Constant "_constrain", a, b];
8635ed5e4613 tuned signature;
wenzelm
parents: 81208
diff changeset
    57
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    58
(*exception for system errors involving asts*)
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    59
exception AST of string * ast list;
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    60
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
    61
80881
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    62
(* order *)
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    63
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    64
local
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    65
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    66
fun cons_nr (Constant _) = 0
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    67
  | cons_nr (Variable _) = 1
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    68
  | cons_nr (Appl _) = 2;
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    69
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    70
in
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    71
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    72
fun ast_ord asts =
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    73
  if pointer_eq asts then EQUAL
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    74
  else
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    75
    (case asts of
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    76
      (Constant a, Constant b) => fast_string_ord (a, b)
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    77
    | (Variable a, Variable b) => fast_string_ord (a, b)
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    78
    | (Appl a, Appl b) => list_ord ast_ord (a, b)
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    79
    | _ => int_ord (apply2 cons_nr asts));
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    80
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    81
end;
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    82
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    83
structure Table = Table(type key = ast val ord = ast_ord);
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    84
structure Set = Set(Table.Key);
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    85
94ea065a8881 more operations;
wenzelm
parents: 80809
diff changeset
    86
81152
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
    87
(* print asts in a LISP-like style *)
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    88
81153
ee8c3375cd39 clarified signature;
wenzelm
parents: 81152
diff changeset
    89
fun pretty_var x =
ee8c3375cd39 clarified signature;
wenzelm
parents: 81152
diff changeset
    90
  (case Term_Position.decode x of
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 81210
diff changeset
    91
    [] => Pretty.str x
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81241
diff changeset
    92
  | ps => Term_Position.pretty (map #pos ps));
81153
ee8c3375cd39 clarified signature;
wenzelm
parents: 81152
diff changeset
    93
14599
c3177fffd31a Replaced quote by Pretty.quote.
berghofe
parents: 12785
diff changeset
    94
fun pretty_ast (Constant a) = Pretty.quote (Pretty.str a)
81153
ee8c3375cd39 clarified signature;
wenzelm
parents: 81152
diff changeset
    95
  | pretty_ast (Variable x) = pretty_var x
38328
36afb56ec49e tuned whitespace;
wenzelm
parents: 33957
diff changeset
    96
  | pretty_ast (Appl asts) = Pretty.enclose "(" ")" (Pretty.breaks (map pretty_ast asts));
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    97
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
    98
fun pretty_rule (lhs, rhs) =
67519
6905b156a030 tuned output;
wenzelm
parents: 64556
diff changeset
    99
  Pretty.block [pretty_ast lhs, Pretty.str " \<leadsto>", Pretty.brk 1, pretty_ast rhs];
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
   100
80809
4a64fc4d1cde clarified signature: type ML_Pretty.pretty coincides with PolyML.pretty;
wenzelm
parents: 74232
diff changeset
   101
val _ = ML_system_pp (fn _ => fn _ => Pretty.to_ML o pretty_ast);
62663
bea354f6ff21 clarified modules;
wenzelm
parents: 56438
diff changeset
   102
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
   103
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   104
(* strip_positions *)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   105
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   106
fun strip_positions (Appl ((t as Constant c) :: u :: (v as Variable x) :: asts)) =
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   107
      if member (op =) Term_Position.markers c andalso Term_Position.detect x
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   108
      then mk_appl (strip_positions u) (map strip_positions asts)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   109
      else Appl (map strip_positions (t :: u :: v :: asts))
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   110
  | strip_positions (Appl asts) = Appl (map strip_positions asts)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   111
  | strip_positions ast = ast;
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   112
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents: 42224
diff changeset
   113
81152
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
   114
(* translation rules *)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   115
81152
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
   116
fun rule_index (Constant a, _: ast) = a
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
   117
  | rule_index (Appl (Constant a :: _), _) = a
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
   118
  | rule_index _ = "";
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   119
32784
1a5dde5079ac eliminated redundant bindings;
wenzelm
parents: 32738
diff changeset
   120
fun rule_error (lhs, rhs) =
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   121
  let
19486
wenzelm
parents: 19473
diff changeset
   122
    fun add_vars (Constant _) = I
wenzelm
parents: 19473
diff changeset
   123
      | add_vars (Variable x) = cons x
wenzelm
parents: 19473
diff changeset
   124
      | add_vars (Appl asts) = fold add_vars asts;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   125
19486
wenzelm
parents: 19473
diff changeset
   126
    val lvars = add_vars lhs [];
wenzelm
parents: 19473
diff changeset
   127
    val rvars = add_vars rhs [];
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   128
  in
19486
wenzelm
parents: 19473
diff changeset
   129
    if has_duplicates (op =) lvars then SOME "duplicate vars in lhs"
33038
8f9594c31de4 dropped redundant gen_ prefix
haftmann
parents: 33037
diff changeset
   130
    else if not (subset (op =) (rvars, lvars)) then SOME "rhs contains extra variables"
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15421
diff changeset
   131
    else NONE
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   132
  end;
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   133
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   134
81152
ece9fe9bf440 clarified signature;
wenzelm
parents: 81151
diff changeset
   135
(* ast translation utilities *)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   136
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   137
fun fold_ast _ [] = raise Match
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   138
  | fold_ast _ [y] = y
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   139
  | fold_ast c (x :: xs) = Appl [Constant c, x, fold_ast c xs];
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   140
19473
wenzelm
parents: 17412
diff changeset
   141
fun fold_ast_p c = uncurry (fold_rev (fn x => fn xs => Appl [Constant c, x, xs]));
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   142
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   143
81166
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   144
fun unfold_ast c (y as Appl [Appl [Constant "_constrain", Constant c', _], x, xs]) =
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   145
      if c = c' then x :: unfold_ast c xs else [y]
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   146
  | unfold_ast c (y as Appl [Constant c', x, xs]) =
16609
c787112bba1f removed obsolete (un)fold_ast2;
wenzelm
parents: 15973
diff changeset
   147
      if c = c' then x :: unfold_ast c xs else [y]
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   148
  | unfold_ast _ y = [y];
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   149
81166
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   150
fun unfold_ast_p c (y as Appl [Appl [Constant "_constrain", Constant c', _], x, xs]) =
81207
wenzelm
parents: 81171
diff changeset
   151
      if c = c' then unfold_ast_p c xs |>> cons x else ([], y)
81166
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   152
  | unfold_ast_p c (y as Appl [Constant c', x, xs]) =
81207
wenzelm
parents: 81171
diff changeset
   153
      if c = c' then unfold_ast_p c xs |>> cons x else ([], y)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   154
  | unfold_ast_p _ y = ([], y);
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   155
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   156
16609
c787112bba1f removed obsolete (un)fold_ast2;
wenzelm
parents: 15973
diff changeset
   157
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   158
(** normalization of asts **)
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   159
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   160
(* match *)
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   161
81156
wenzelm
parents: 81153
diff changeset
   162
local
wenzelm
parents: 81153
diff changeset
   163
wenzelm
parents: 81153
diff changeset
   164
exception NO_MATCH;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   165
81234
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   166
fun const_match0 (Constant a) b = a = b
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   167
  | const_match0 (Variable a) b = a = b
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   168
  | const_match0 _ _ = false;
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   169
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   170
fun const_match true (Appl [Constant "_constrain", ast, _]) b = const_match0 ast b
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   171
  | const_match false (Appl [Constant "_constrain", ast, Variable x]) b =
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   172
      Term_Position.detect x andalso const_match0 ast b
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   173
  | const_match _ a b = const_match0 a b;
81166
26ecbac09941 allow type constraints for const_syntax;
wenzelm
parents: 81156
diff changeset
   174
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   175
fun match1 p ast (Constant b) env = if const_match p ast b then env else raise NO_MATCH
81234
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   176
  | match1 _ ast (Variable x) env = Symtab.update (x, ast) env
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   177
  | match1 p (Appl asts) (Appl pats) env = match2 p asts pats env
81234
ae0ccabd0aab more liberal ast matching, notably for case-translations in HOLCF that operate on logical consts rather than syntax consts;
wenzelm
parents: 81232
diff changeset
   178
  | match1 _ _ _ _ = raise NO_MATCH
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   179
and match2 p (ast :: asts) (pat :: pats) env = match1 p ast pat env |> match2 p asts pats
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   180
  | match2 _ [] [] env = env
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   181
  | match2 _ _ _ _ = raise NO_MATCH;
81156
wenzelm
parents: 81153
diff changeset
   182
wenzelm
parents: 81153
diff changeset
   183
in
wenzelm
parents: 81153
diff changeset
   184
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   185
fun match p ast pat =
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   186
  let
1127
42ec82147d83 changed macro expander such that patterns also match prefixes of appls;
wenzelm
parents: 922
diff changeset
   187
    val (head, args) =
81156
wenzelm
parents: 81153
diff changeset
   188
      (case (ast, pat) of
1127
42ec82147d83 changed macro expander such that patterns also match prefixes of appls;
wenzelm
parents: 922
diff changeset
   189
        (Appl asts, Appl pats) =>
42ec82147d83 changed macro expander such that patterns also match prefixes of appls;
wenzelm
parents: 922
diff changeset
   190
          let val a = length asts and p = length pats in
33957
e9afca2118d4 normalized uncurry take/drop
haftmann
parents: 33955
diff changeset
   191
            if a > p then (Appl (take p asts), drop p asts)
81156
wenzelm
parents: 81153
diff changeset
   192
            else (ast, [])
1127
42ec82147d83 changed macro expander such that patterns also match prefixes of appls;
wenzelm
parents: 922
diff changeset
   193
          end
81156
wenzelm
parents: 81153
diff changeset
   194
      | _ => (ast, []));
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   195
  in SOME (Symtab.build (match1 p head pat), args) handle NO_MATCH => NONE end;
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   196
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   197
end;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   198
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   199
18
c9ec452ff08f lots of internal cleaning and tuning;
wenzelm
parents: 0
diff changeset
   200
(* normalize *)
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   201
69575
f77cc54f6d47 clarified signature: more types;
wenzelm
parents: 67519
diff changeset
   202
val trace = Config.declare_bool ("syntax_ast_trace", \<^here>) (K false);
f77cc54f6d47 clarified signature: more types;
wenzelm
parents: 67519
diff changeset
   203
val stats = Config.declare_bool ("syntax_ast_stats", \<^here>) (K false);
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   204
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   205
local
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   206
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   207
fun subst _ (ast as Constant _) = ast
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   208
  | subst env (Variable x) = the (Symtab.lookup env x)
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   209
  | subst env (Appl asts) = Appl (map (subst env) asts);
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   210
81171
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   211
fun head_name (Constant a) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   212
  | head_name (Variable a) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   213
  | head_name (Appl [Constant "_constrain", Constant a, _]) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   214
  | head_name (Appl (Appl [Constant "_constrain", Constant a, _] :: _)) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   215
  | head_name (Appl (Constant a :: _)) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   216
  | head_name (Appl (Variable a :: _)) = a
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   217
  | head_name _ = "";
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   218
42048
afd11ca8e018 support for encoded positions (for id_position, longid_position) as pseudo type-constraints -- still inactive;
wenzelm
parents: 41377
diff changeset
   219
fun message head body =
afd11ca8e018 support for encoded positions (for id_position, longid_position) as pseudo type-constraints -- still inactive;
wenzelm
parents: 41377
diff changeset
   220
  Pretty.string_of (Pretty.block [Pretty.str head, Pretty.brk 1, body]);
afd11ca8e018 support for encoded positions (for id_position, longid_position) as pseudo type-constraints -- still inactive;
wenzelm
parents: 41377
diff changeset
   221
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   222
fun tracing_if false _ = ()
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   223
  | tracing_if true msg = tracing (msg ());
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   224
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   225
in
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   226
41377
390c53904220 configuration option "syntax_ast_trace" and "syntax_ast_stat";
wenzelm
parents: 38328
diff changeset
   227
(*the normalizer works yoyo-like: top-down, bottom-up, top-down, ...*)
81208
893b056542e7 more accurate treatment of constraints: restrict permissive mode to output;
wenzelm
parents: 81207
diff changeset
   228
fun normalize ctxt {permissive_constraints = p} get_rules pre_ast =
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   229
  let
42277
7503beeffd8d tuned signature;
wenzelm
parents: 42264
diff changeset
   230
    val trace = Config.get ctxt trace;
43347
f18cf88453d6 tuned name (cf. blast_stats);
wenzelm
parents: 42277
diff changeset
   231
    val stats = Config.get ctxt stats;
41377
390c53904220 configuration option "syntax_ast_trace" and "syntax_ast_stat";
wenzelm
parents: 38328
diff changeset
   232
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   233
    val matches_failed = Unsynchronized.ref 0;
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   234
    val changes = Unsynchronized.ref 0;
32738
15bb09ca0378 explicit indication of Unsynchronized.ref;
wenzelm
parents: 30628
diff changeset
   235
    val passes = Unsynchronized.ref 0;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   236
81241
wenzelm
parents: 81240
diff changeset
   237
    fun test_changes () =
wenzelm
parents: 81240
diff changeset
   238
      let val old_changes = ! changes
wenzelm
parents: 81240
diff changeset
   239
      in fn () => old_changes <> ! changes end;
wenzelm
parents: 81240
diff changeset
   240
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   241
    fun rewrite1 ast (lhs, rhs) =
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   242
      (case match p ast lhs of
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   243
        NONE => (Unsynchronized.inc matches_failed; NONE)
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   244
      | SOME (env, args) => (Unsynchronized.inc changes; SOME (mk_appl (subst env rhs) args)));
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   245
81171
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   246
    fun rewrite2 a ast =
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   247
      (case get_first (rewrite1 ast) (get_rules a) of
81171
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   248
        NONE => if a = "" then NONE else rewrite2 "" ast
98fd5375de00 minor performance tuning;
wenzelm
parents: 81166
diff changeset
   249
      | some => some);
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   250
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   251
    fun rewrote rule = tracing_if trace (fn () => message "rewrote:" (pretty_rule rule));
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   252
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   253
    fun norm1 ast =
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   254
      (case rewrite2 (head_name ast) ast of
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   255
        SOME ast' => (rewrote (ast, ast'); norm1 ast')
15531
08c8dad8e399 Deleted Library.option type.
skalberg
parents: 15421
diff changeset
   256
      | NONE => ast);
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   257
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   258
    fun norm2 ast =
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   259
      (case norm1 ast of
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   260
        Appl subs =>
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   261
          let
81241
wenzelm
parents: 81240
diff changeset
   262
            val changed = test_changes ();
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   263
            val ast' = Appl (map norm2 subs);
81241
wenzelm
parents: 81240
diff changeset
   264
          in if changed () then norm1 ast' else ast' end
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   265
      | atomic => atomic);
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   266
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   267
    fun norm ast =
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   268
      let
81241
wenzelm
parents: 81240
diff changeset
   269
        val changed = test_changes ();
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   270
        val ast' = norm2 ast;
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   271
        val _ = Unsynchronized.inc passes;
81241
wenzelm
parents: 81240
diff changeset
   272
      in if changed () then norm ast' else ast' end;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   273
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   274
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   275
    val _ = tracing_if trace (fn () => message "pre:" (pretty_ast pre_ast));
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   276
    val post_ast = norm pre_ast;
21962
279b129498b6 removed conditional combinator;
wenzelm
parents: 19486
diff changeset
   277
    val _ =
81240
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   278
      tracing_if (trace orelse stats) (fn () =>
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   279
        message "post:" (pretty_ast post_ast) ^ "\nnormalize: " ^
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   280
        string_of_int (! passes) ^ " passes, " ^
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   281
        string_of_int (! changes) ^ " changes, " ^
47b95e6af3c8 misc tuning and clarification;
wenzelm
parents: 81234
diff changeset
   282
        string_of_int (! matches_failed) ^ " matches failed");
21962
279b129498b6 removed conditional combinator;
wenzelm
parents: 19486
diff changeset
   283
  in post_ast end;
0
a5a9c433f639 Initial revision
clasohm
parents:
diff changeset
   284
1506
192c48376d25 Elimination of fully-functorial style.
paulson
parents: 1127
diff changeset
   285
end;
81151
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   286
0d728eadad86 misc tuning and clarification;
wenzelm
parents: 80881
diff changeset
   287
end;