-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlabmap.ml
143 lines (119 loc) · 4.33 KB
/
labmap.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
open Tuple
open Sourcepos
open Option
open Listutils
open Name
open Formula
open Com
open Knot
(* This file is part of Arsenic, a proofchecker for New Lace logic.
Copyright (c) 2015 Richard Bornat.
Licensed under the MIT license (sic): see LICENCE.txt or
https://opensource.org/licenses/MIT
*)
type scloc =
| DoUntilPos of sourcepos
| WhilePos of sourcepos
| IfPos of sourcepos
| IfArmPos of bool
| ControlPos
let string_of_scloc = function
| DoUntilPos spos -> "DoUntilPos " ^ string_of_sourcepos spos
| WhilePos spos -> "WhilePos " ^ string_of_sourcepos spos
| IfPos spos -> "IfPos " ^ string_of_sourcepos spos
| IfArmPos b -> "IfArmPos " ^ string_of_bool b
| ControlPos -> "ControlPos"
type componentid =
| CidSimplecom of simplecom triplet
| CidControl of condition
| CidInit of label * formula
| CidFinal of label * formula
| CidThreadPost of knot
let string_of_componentid = function
| CidSimplecom ct -> string_of_triplet string_of_simplecom ct
| CidControl c -> string_of_condition c
| CidInit (lab,f)
| CidFinal (lab,f) -> Printf.sprintf "{%s:%s}"
(string_of_label lab)
(string_of_formula f)
| CidThreadPost k -> string_of_knot k
module LabMap = Name.LabelMap
type parentid = int * scloc
let string_of_parentid = Tuple.bracketed_string_of_pair string_of_int string_of_scloc
let string_of_parentids = bracketed_string_of_list string_of_parentid
type labelid = sourcepos * componentid * parentid list
let string_of_labelid =
Tuple.bracketed_string_of_triple
string_of_sourcepos
string_of_componentid
string_of_parentids
type labmap = labelid LabMap.t
let string_of_labmap = LabMap.to_string string_of_labelid
let bad s lab labmap =
raise (Invalid_argument (Printf.sprintf "Not_found LabMap.%s %s %s"
s
(Name.string_of_label lab)
(string_of_labmap labmap)
)
)
let is_control lab labmap =
try match sndof3 (LabMap.find lab labmap) with
| CidControl _ -> true
| _ -> false
with Not_found -> bad "is_control" lab labmap
let get_parents lab labmap =
try thrdof3 (LabMap.find lab labmap)
with Not_found -> bad "get_parents" lab labmap
let get_cid lab labmap =
try sndof3 (LabMap.find lab labmap)
with Not_found -> bad "get_cid" lab labmap
let strictly_encloses outer inner =
match outer, inner with
| _ , [] -> false
| [] , _ -> true
| pid::_, _ -> outer<>inner && List.mem pid inner
let encloses outer inner =
outer=inner || strictly_encloses outer inner
let rec tightest_loop parents =
match parents with
| [] -> []
| (_, ControlPos ) :: parents
| (_, IfPos _) :: parents
| (_, IfArmPos _) :: parents -> tightest_loop parents
| (_, DoUntilPos _) :: _
| (_, WhilePos _) :: _ -> parents
let rec common_ancestors bparents cparents =
let bparents = tightest_loop bparents in
let cparents = tightest_loop cparents in
match bparents, cparents with
| [] , _
| _ , [] -> []
| (bn, _ as bp)::bparents', (cn, _ as cp)::cparents' ->
if bn<cn then common_ancestors bparents cparents' else
if cn<bn then common_ancestors bparents' cparents else
if bp=cp then bparents else
common_ancestors bparents' cparents'
(* find the loosest loop (if there is one) that is outside innerps, but
inside the common ancestor of outerps and innerps.
*)
let weakest_inner_loop outerps innerps =
let outerps = common_ancestors outerps innerps in
let rec wil ips =
if outerps=ips then None
else
match ips with
| [] -> None
| (_, DoUntilPos _) :: ips'
| (_, WhilePos _) :: ips' -> wil ips' |~~ (fun _ -> Some ips)
| _ :: ips' -> wil ips'
in
wil innerps
let rec enclosing_if parents =
match parents with
| [] -> []
| (_, IfArmPos _) :: _
| (_, IfPos _) :: _ -> parents
| _ :: parents -> enclosing_if parents
let pidopt = function
| [] -> None
| pid::_ -> Some pid