Skip to content

Commit 9b9637e

Browse files
committed
Initial drop of RGref implementation into a separate repository
0 parents  commit 9b9637e

15 files changed

+1408
-0
lines changed

BinaryTree.v

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
Require Import RGref.DSL.DSL.
2+
3+
(** * A Mutable Binary Tree *)
4+
5+
(** ** A Pure Tree of Non-Zero Naturals
6+
To further familiarize ourselves, we implement a pure-functional tree containing arbitrary non-zero nats. *)
7+
8+
Section PureTree.
9+
Inductive btree' : Set :=
10+
| lf' : btree'
11+
| nd' : forall (C:Set) (P:C->Prop) (a b:C) (pa:P a) (pb:P b), nat -> btree'.
12+
Inductive gtz' : btree' -> Prop :=
13+
| gtzlf : gtz' lf'
14+
| gtznd : forall (C:Set) (P:C->Prop) (a b:C) (pa:P a) (pb:P b) (n:nat),
15+
n > 0 -> gtz' (nd' C P a b pa pb n).
16+
Inductive PTCheck : btree' -> Prop :=
17+
| lf_check : PTCheck lf'
18+
| nd_check : forall (n:nat) (a b:btree') (pa:PTCheck a) (pb:PTCheck b) (gta:gtz' a) (gtb:gtz' b),
19+
PTCheck (nd' btree' gtz' a b gta gtb n).
20+
Definition btree := {t:btree'|PTCheck t}.
21+
Definition gtz (t:btree) := gtz' (proj1_sig t).
22+
Definition lf := exist _ lf' lf_check.
23+
Definition nd n (a b:btree) pa pb := exist _ (nd' btree' gtz' (proj1_sig a) (proj1_sig b) pa pb n)
24+
(nd_check n (proj1_sig a) (proj1_sig b) (proj2_sig a) (proj2_sig b) pa pb).
25+
26+
End PureTree.
27+
(*
28+
Axiom sref_axiom : forall (A:Type), Type.
29+
Inductive sref (A:Type) : Type :=
30+
| mksref : nat -> sref A.
31+
Axiom sref_read : forall {A}, sref A -> A.
32+
(*CoInductive natskel (C:Type) (P:hpred C) (R G:hrel C) : Set :=
33+
| leaf : natskel C P R G
34+
| node : nat -> ref{C|P}[R,G] -> natskel C P R G.*)
35+
Inductive natskel (C:Set) (P:C->Prop): Set :=
36+
| leaf : natskel C P
37+
| node : nat -> sref (natskel C P) -> natskel C P.
38+
39+
Fixpoint ll_of_len (n:nat) (P:forall {A}, nat->A->Prop): Set :=
40+
match n with
41+
| 0 => natskel unit (fun _ => True)
42+
| S n' => natskel (ll_of_len n' P) (P _ n')
43+
end.
44+
Check ll_of_len.
45+
Fixpoint sorted {A} (n:nat) : A -> Prop :=
46+
fun l =>
47+
match (n,l) with
48+
| (0,y) => True
49+
| (S n',leaf) => True
50+
| (S n',node val tl) => val > 0 /\ sorted (sref_read tl)
51+
end.
52+
53+
(*CoInductive cotype : Type -> Type :=
54+
| μ : forall (τ:Set), cotype (natskel τ) -> cotype τ.*)
55+
56+
Inductive sorted : forall {C P}, natskel C P -> Prop :=
57+
| sleaf : forall C P, sorted (leaf C P)
58+
| snode : forall C n (tl:natskel C (sorted C sorted), n > 0 -> sorted (sref_read tl) -> sorted (node _ _ n tl)
59+
.
60+
61+
62+
Fixpoint btree
63+
64+
Definition bound {C P R G}: hpred (natskel C P R G) :=
65+
fun node => fun h =>
66+
match node with
67+
| leaf => True
68+
| node n tl => n > 0
69+
end.
70+
*)

CounterModule.v

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
Require Import RGref.DSL.DSL.
2+
3+
(** * Counter Module : Abstract Data Types with Rely-Guarantee References *)
4+
5+
(** Rely-guarantee references work just fine with traditional encapsulation
6+
methods, such as ML-style modules. Let's define a module type for an
7+
abstract counter *)
8+
Module Type Counter.
9+
Parameter counter_val : Set.
10+
Parameter increasing_counter : hrel counter_val.
11+
Definition counter := ref{counter_val|any}[increasing_counter,increasing_counter].
12+
Parameter read : counter -> nat.
13+
Parameter increment : forall { Γ }, counter -> rgref Γ unit Γ.
14+
Parameter create_counter : forall { Γ }, unit -> rgref Γ counter Γ.
15+
End Counter.
16+
(** These are all the same operations described in the MonotonicCounter example.
17+
In fact, we'll hijack those definitions to define our counter module
18+
instantiation. *)
19+
Module SomeCounter : Counter.
20+
Require Import MonotonicCounter.
21+
Definition counter_val := nat.
22+
Definition increasing_counter := increasing.
23+
Definition counter := monotonic_counter.
24+
Definition read := read_counter.
25+
Definition increment := @inc_monotonic.
26+
Definition create_counter := @mkCounter.
27+
End SomeCounter.
28+
29+
(** Now we can experiment with opening the module we just defined. *)
30+
Import SomeCounter.
31+
(** The type counter_val is opaque. But notice that we exposed the
32+
fact that the counter type is a reference. *)
33+
Print counter.
34+
Print counter_val.
35+
36+
(** We can write an expression to dereference the reference, but
37+
because increasing_counter is abstract, we cannot even prove
38+
the reflexivity requirement to allow the read, let alone
39+
reason about relation folding.
40+
<<
41+
Program Definition get_counter_val (c:counter) := deref _ _ c.
42+
>>
43+
*)
44+
45+
(** But we can still use it as a standard ADT. In general, any subcomponent
46+
of the reference exposed can be encapsulated or not, though the more
47+
details of relations or predicates that are exposed, the more likely
48+
it is that extra lemmas will need to be exported from the module in order
49+
for it to be useful. *)
50+
Example test_some_counter { Γ } (_:unit) : rgref Γ unit Γ :=
51+
x <- create_counter tt;
52+
_ <- increment x;
53+
increment x.

0 commit comments

Comments
 (0)