Skip to content

Commit 47176a3

Browse files
committed
Why3 proof update: is witness to make spec more clear, rename Qualified in line with Rust code
1 parent b2cda4c commit 47176a3

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

proofs/sudoers.mlw

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,25 @@ use array.Array
77
use option.Option
88
use ref.Ref
99
use int.Int
10+
use witness.Witness
1011

1112
(* loose models for the types in sudoers::Ast *)
1213
type metavar 'a = All | Only 'a
13-
type qualified 'a = Yes 'a | No 'a
14+
type qualified 'a = Allow 'a | Forbid 'a
1415
type spec 'tag 'a = { inner: qualified (metavar 'a); info: 'tag }
1516

1617
predicate contains (pred: 'a -> bool) (a: array 'a)
1718
= exists i. 0 <= i < length a /\ pred a[i]
1819

1920
function who (item: spec 'tag 'a): metavar 'a
2021
= match item.inner with
21-
| Yes x -> x
22-
| No x -> x
22+
| Allow x -> x
23+
| Forbid x -> x
2324
end
2425

2526
function condition (item: spec 'tag 'a): option 'tag
2627
= match item with
27-
| { inner = Yes _; info = tag } -> Some tag
28+
| { inner = Allow _; info = tag } -> Some tag
2829
| _ -> None
2930
end
3031

@@ -37,14 +38,17 @@ function matched_by (pred: 'a -> bool) (item: spec 'tag 'a): bool
3738
let function bool_then (b: bool) (x: 'a): option 'a
3839
= if b then Some x else None
3940

40-
predicate final_match (pred: 'a -> bool) (a: array 'a) (f: 'a -> 'b) (x: 'b)
41-
= exists i. 0 <= i < length a /\ pred a[i] /\ f a[i] = x /\ forall k. i < k < length a -> not pred a[k]
41+
predicate is_final_match (pred: 'a -> bool) (a: array 'a) (i: int)
42+
= 0 <= i < length a /\ pred a[i] /\ forall k. i < k < length a -> not pred a[k]
43+
44+
function final_match (pred: 'a -> bool) (items: array 'a): 'a
45+
= items[witness (is_final_match pred items)]
4246

4347
(* Why3 model of the sudoers::find_item function *)
4448
let find_item (items: array (spec 'tag 'a)) (pred: 'a -> bool): option 'tag
4549
returns {
46-
| Some tag -> final_match (matched_by pred) items condition (Some tag)
47-
| None -> not contains (matched_by pred) items \/ final_match (matched_by pred) items condition None
50+
| Some tag -> contains (matched_by pred) items && condition (final_match (matched_by pred) items) = Some tag
51+
| None -> contains (matched_by pred) items -> condition (final_match (matched_by pred) items) = None
4852
}
4953

5054
= let result = ref None in
@@ -54,13 +58,13 @@ let find_item (items: array (spec 'tag 'a)) (pred: 'a -> bool): option 'tag
5458
exists j. 0 <= j < i /\ matched_by pred items[j] /\ Some tag = condition items[j] /\
5559
forall k. j < k < i -> not matched_by pred items[k] }
5660
let (judgement, who) = match items[i].inner with
57-
| No x -> (false, x)
58-
| Yes x -> (true, x)
61+
| Forbid x -> (false, x)
62+
| Allow x -> (true, x)
5963
end in
6064
let info = items[i].info in
6165
match who with
6266
| All -> result := judgement.bool_then(info)
63-
| Only id -> if pred id then result := judgement.bool_then(info);
67+
| Only id -> if pred id then result := judgement.bool_then(info)
6468
end;
6569
done;
6670

0 commit comments

Comments
 (0)