src/Pure/Syntax/term_position.ML
author wenzelm
Wed, 22 Jan 2025 22:22:19 +0100
changeset 81954 6f2bcdfa9a19
parent 81558 b57996a0688c
permissions -rw-r--r--
misc tuning: more concise operations on prems (without change of exceptions); discontinue odd clone Drule.cprems_of (see also 991a3feaf270);
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     1
(*  Title:      Pure/Syntax/term_position.ML
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     3
81251
89ea66c2045b clarified position constraints: omit redundant information, e.g. for implicit object-logic judgment;
wenzelm
parents: 81232
diff changeset
     4
Reported positions within term syntax trees (non-empty list).
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     5
*)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     6
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     7
signature TERM_POSITION =
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
     8
sig
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
     9
  type T = {syntax: bool, pos: Position.T}
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    10
  val syntax: Position.T -> T
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    11
  val no_syntax: Position.T -> T
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    12
  val store_reports: Position.report_text list Unsynchronized.ref ->
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    13
    T list -> ('a -> Markup.T list) -> 'a -> unit
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    14
  val pretty: Position.T list -> Pretty.T
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    15
  val encode: T list -> string
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    16
  val encode_syntax: Position.T list -> string
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    17
  val encode_no_syntax: Position.T list -> string
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    18
  val detect: string -> bool
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    19
  val decode: string -> T list
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    20
  val detect_position: term -> bool
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    21
  val decode_position: term -> (T list * typ) option
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    22
  val decode_position1: term -> T option
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    23
  val detect_positionT: typ -> bool
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    24
  val decode_positionT: typ -> T list
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    25
  val decode_positionS: sort -> T list * sort
52175
626a757d3c2d uniform Term_Position.markers (cf. dbadb4d03cbc);
wenzelm
parents: 50201
diff changeset
    26
  val markers: string list
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    27
  val strip_positions: term -> term
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    28
end;
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    29
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    30
structure Term_Position: TERM_POSITION =
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    31
struct
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    32
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    33
(* type T *)
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    34
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    35
type T = {syntax: bool, pos: Position.T};
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    36
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    37
fun syntax pos : T = {syntax = true, pos = pos};
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    38
fun no_syntax pos : T = {syntax = false, pos = pos};
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    39
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    40
fun store_reports _ [] _ _ = ()
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    41
  | store_reports (r: Position.report_text list Unsynchronized.ref) ps markup x =
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    42
      let
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    43
        val ms = markup x;
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    44
        fun store {syntax, pos} =
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    45
          fold (fn m => cons ((pos, Markup.syntax_properties syntax m), "")) ms;
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    46
      in Unsynchronized.change r (fold store ps) end;
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    47
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    48
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    49
(* markup *)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    50
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    51
val position_dummy = "<position>";
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    52
val position_text = XML.Text position_dummy;
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    53
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    54
fun pretty ps = Pretty.marks_str (map Position.markup ps, position_dummy);
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    55
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    56
fun encode_pos {syntax, pos} =
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    57
  XML.Elem (Position.markup pos |> Markup.syntax_properties syntax, [position_text]);
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    58
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    59
fun decode_pos (XML.Elem ((name, props), [arg])) =
50201
c26369c9eda6 Isabelle-specific implementation of quasi-abstract markup elements -- back to module arrangement before d83797ef0d2d;
wenzelm
parents: 49685
diff changeset
    60
      if name = Markup.positionN andalso arg = position_text
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    61
      then SOME {syntax = Markup.has_syntax props, pos = Position.of_properties props}
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    62
      else NONE
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    63
  | decode_pos _ = NONE;
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    64
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    65
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    66
(* encode *)
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    67
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    68
val encode_none = YXML.string_of (encode_pos (no_syntax Position.none));
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    69
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    70
fun encode ps =
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    71
  (case filter (Position.is_reported o #pos) ps of
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    72
    [] => encode_none
81251
89ea66c2045b clarified position constraints: omit redundant information, e.g. for implicit object-logic judgment;
wenzelm
parents: 81232
diff changeset
    73
  | ps' => YXML.string_of_body (map encode_pos ps'));
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    74
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    75
val encode_syntax = encode o map syntax;
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    76
val encode_no_syntax = encode o map no_syntax;
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    77
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    78
val encode_prefix = YXML.XY ^ Markup.positionN;
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    79
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    80
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    81
(* decode *)
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    82
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    83
val detect = String.isPrefix encode_prefix;
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    84
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
    85
fun decode str =
81558
b57996a0688c clarified term positions and markup: syntax = true means this is via concrete syntax;
wenzelm
parents: 81251
diff changeset
    86
  if str = encode_none then [no_syntax Position.none]
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    87
  else if detect str then
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    88
    let
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    89
      val xml = YXML.parse_body str handle Fail msg => error msg;
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    90
      val ps = map decode_pos xml;
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    91
    in
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    92
      if not (null ps) andalso forall is_some ps then map the ps
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    93
      else if forall is_none ps then []
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    94
      else error ("Bad encoded positions: " ^ quote str)
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    95
    end
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
    96
  else [];
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    97
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    98
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
    99
(* positions within parse trees *)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   100
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   101
fun detect_position (Free (x, _)) = detect x
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   102
  | detect_position _ = false;
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   103
45445
41e641a870de pass term positions into check phase, where resulting types are reported accordingly, and eventually shown as tooltips;
wenzelm
parents: 42264
diff changeset
   104
fun decode_position (Free (x, _)) =
41e641a870de pass term positions into check phase, where resulting types are reported accordingly, and eventually shown as tooltips;
wenzelm
parents: 42264
diff changeset
   105
      (case decode x of
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   106
        [] => NONE
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   107
      | ps => SOME (ps, TFree (x, dummyS)))
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   108
  | decode_position _ = NONE;
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   109
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   110
fun decode_position1 (Free (x, _)) =
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   111
      (case decode x of
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   112
        [] => NONE
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   113
      | pos :: _ => SOME pos)
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   114
  | decode_position1 _ = NONE;
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   115
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   116
fun detect_positionT (TFree (x, _)) = detect x
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   117
  | detect_positionT _ = false;
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   118
45445
41e641a870de pass term positions into check phase, where resulting types are reported accordingly, and eventually shown as tooltips;
wenzelm
parents: 42264
diff changeset
   119
fun decode_positionT (TFree (x, _)) = decode x
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   120
  | decode_positionT _ = [];
45445
41e641a870de pass term positions into check phase, where resulting types are reported accordingly, and eventually shown as tooltips;
wenzelm
parents: 42264
diff changeset
   121
49685
4341e4d86872 allow position constraints to coexist with 0 or 1 sort constraints;
wenzelm
parents: 49674
diff changeset
   122
fun decode_positionS cs =
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   123
  let val (ps, sort) = List.partition detect cs
81218
94bace5078ba support multiple positions (non-empty list);
wenzelm
parents: 80875
diff changeset
   124
  in (maps decode ps, sort) end;
49674
dbadb4d03cbc report sort assignment of visible type variables;
wenzelm
parents: 45666
diff changeset
   125
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   126
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   127
(* strip_positions *)
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   128
52175
626a757d3c2d uniform Term_Position.markers (cf. dbadb4d03cbc);
wenzelm
parents: 50201
diff changeset
   129
val markers = ["_constrain", "_constrainAbs", "_ofsort"];
626a757d3c2d uniform Term_Position.markers (cf. dbadb4d03cbc);
wenzelm
parents: 50201
diff changeset
   130
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   131
fun strip_positions ((t as Const (c, _)) $ u $ v) =
81232
9867b5cf3f7a more concise representation of term positions;
wenzelm
parents: 81218
diff changeset
   132
      if member (op =) markers c andalso detect_position v
42264
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   133
      then strip_positions u
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   134
      else t $ strip_positions u $ strip_positions v
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   135
  | strip_positions (t $ u) = strip_positions t $ strip_positions u
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   136
  | strip_positions (Abs (x, T, t)) = Abs (x, T, strip_positions t)
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   137
  | strip_positions t = t;
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   138
b6c1b0c4c511 separate structure Term_Position;
wenzelm
parents:
diff changeset
   139
end;