author | wenzelm |
Wed, 22 Jan 2025 22:22:19 +0100 | |
changeset 81954 | 6f2bcdfa9a19 |
parent 81558 | b57996a0688c |
permissions | -rw-r--r-- |
42264 | 1 |
(* Title: Pure/Syntax/term_position.ML |
2 |
Author: Makarius |
|
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 | 5 |
*) |
6 |
||
7 |
signature TERM_POSITION = |
|
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 | 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 | 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 | 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 | 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 | 27 |
val strip_positions: term -> term |
28 |
end; |
|
29 |
||
30 |
structure Term_Position: TERM_POSITION = |
|
31 |
struct |
|
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 | 49 |
(* markup *) |
50 |
||
51 |
val position_dummy = "<position>"; |
|
52 |
val position_text = XML.Text position_dummy; |
|
53 |
||
81218 | 54 |
fun pretty ps = Pretty.marks_str (map Position.markup ps, position_dummy); |
42264 | 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 | 58 |
|
81218 | 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 | 62 |
else NONE |
81218 | 63 |
| decode_pos _ = NONE; |
64 |
||
81232 | 65 |
|
66 |
(* encode *) |
|
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 | 69 |
|
81218 | 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 | 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 | 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 | 78 |
val encode_prefix = YXML.XY ^ Markup.positionN; |
79 |
||
80 |
||
81 |
(* decode *) |
|
82 |
||
83 |
val detect = String.isPrefix encode_prefix; |
|
81218 | 84 |
|
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 | 87 |
else if detect str then |
88 |
let |
|
89 |
val xml = YXML.parse_body str handle Fail msg => error msg; |
|
90 |
val ps = map decode_pos xml; |
|
91 |
in |
|
92 |
if not (null ps) andalso forall is_some ps then map the ps |
|
93 |
else if forall is_none ps then [] |
|
94 |
else error ("Bad encoded positions: " ^ quote str) |
|
95 |
end |
|
96 |
else []; |
|
42264 | 97 |
|
98 |
||
99 |
(* positions within parse trees *) |
|
100 |
||
81232 | 101 |
fun detect_position (Free (x, _)) = detect x |
102 |
| detect_position _ = false; |
|
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 | 106 |
[] => NONE |
107 |
| ps => SOME (ps, TFree (x, dummyS))) |
|
42264 | 108 |
| decode_position _ = NONE; |
109 |
||
81218 | 110 |
fun decode_position1 (Free (x, _)) = |
111 |
(case decode x of |
|
112 |
[] => NONE |
|
113 |
| pos :: _ => SOME pos) |
|
114 |
| decode_position1 _ = NONE; |
|
115 |
||
81232 | 116 |
fun detect_positionT (TFree (x, _)) = detect x |
117 |
| detect_positionT _ = false; |
|
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 | 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 | 123 |
let val (ps, sort) = List.partition detect cs |
81218 | 124 |
in (maps decode ps, sort) end; |
49674
dbadb4d03cbc
report sort assignment of visible type variables;
wenzelm
parents:
45666
diff
changeset
|
125 |
|
81232 | 126 |
|
127 |
(* strip_positions *) |
|
42264 | 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 | 131 |
fun strip_positions ((t as Const (c, _)) $ u $ v) = |
81232 | 132 |
if member (op =) markers c andalso detect_position v |
42264 | 133 |
then strip_positions u |
134 |
else t $ strip_positions u $ strip_positions v |
|
135 |
| strip_positions (t $ u) = strip_positions t $ strip_positions u |
|
136 |
| strip_positions (Abs (x, T, t)) = Abs (x, T, strip_positions t) |
|
137 |
| strip_positions t = t; |
|
138 |
||
139 |
end; |