Skip to content

Commit 02784cf

Browse files
committed
totally rework fields, move to typeclasses per field rather than fin and Coq's pattern matching.
Not sure how well the typeclass resolution will work with cleaner syntax.
1 parent 04b095a commit 02784cf

File tree

1 file changed

+41
-66
lines changed

1 file changed

+41
-66
lines changed

RGref/DSL/Fields.v

Lines changed: 41 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,27 @@ Require Import RGref.DSL.DSL.
22
Require Import Coq.Vectors.Fin.
33
Require Import Coq.Arith.Arith.
44

5-
Definition fin := t. (* Why on earth is this named t in the stdlib??? *)
5+
(* Field Typing is a tagging mechanism, that fields of T are indexed by F *)
6+
Class FieldTyping (T : Set) (F : Set) : Set := {}.
67

7-
Definition FieldTypes (n : nat) := fin n -> Set.
8-
9-
Class FieldAccess (T : Set) {n : nat} (ft : FieldTypes n) : Set := {
10-
fieldOf : forall (obj : T) (x : fin n), ft x ;
11-
fieldUpdate : forall (obj : T) (x : fin n) (v : ft x), T
8+
Class FieldType (T : Set) (F : Set) `{FieldTyping T F} (f:F) (FT : Set) := {
9+
getF : T -> FT;
10+
setF : T -> FT -> T
11+
(* In theory we could also require a proof that it satisfies the theory
12+
of arrays, e.g. forall x v, getF (setF x v) = v. *)
1213
}.
1314

1415
(* Field-aware heap access primitives *)
15-
Axiom field_read : forall {T B Res:Set}{P R G}{n:nat}{ft:FieldTypes n}`{rel_fold T}
16+
Axiom field_read : forall {T B F Res:Set}{P R G}`{rel_fold T}
1617
`{rgfold R G = B}
1718
`{hreflexive G}
18-
`{FieldAccess B n ft}
19-
(r:ref{T|P}[R,G]) (f:fin n)
20-
`{ft f = Res}, (* <-- another weak pattern matching/conversion hack *)
19+
(r:ref{T|P}[R,G]) (f:F)
20+
`{FieldType B F f Res},
2121
Res.
22-
Axiom field_write : forall {Γ}{T:Set}{P R G}{n:nat}{ft:FieldTypes n}
23-
`{FieldAccess T n ft}
24-
(r:ref{T|P}[R,G]) (f:fin n) (e : ft f)
25-
`{forall h v, P v h -> G v (fieldUpdate v f e) h (heap_write r (fieldUpdate v f e) h)},
22+
Axiom field_write : forall {Γ}{T F Res:Set}{P R G}
23+
(r:ref{T|P}[R,G]) (f:F) (e : Res)
24+
`{FieldType T F f Res}
25+
`{forall h v, P v h -> G v (setF v e) h (heap_write r (setF v e) h)},
2626
rgref Γ unit Γ.
2727

2828
Section FieldDemo.
@@ -35,64 +35,25 @@ Section FieldDemo.
3535
Lemma refl_deltaD : hreflexive deltaD. Proof. red. intros. destruct x. apply incCount. eauto with arith. Qed.
3636
Hint Resolve refl_deltaD.
3737

38-
(* This demonstrates why Fin is more heavily used in Agda than Coq.
39-
Coq's pattern matching is too weak to determine that F1 and FS _ (F1 _)
40-
is an exhaustive match! *)
41-
Definition DFieldSize := FieldTypes 2.
42-
Definition DFieldTypes : FieldTypes 2 :=
43-
fun f => match f as F with
44-
| F1 _ => nat
45-
| FS _ _ => bool
46-
end.
4738
Inductive Dfield : Set := Count | Flag.
48-
Definition DField2Fin (df : Dfield) : fin 2 := match df with Count => F1 | Flag => FS (F1) end.
49-
Coercion DField2Fin : Dfield >-> fin.
50-
Require Import Coq.Program.Equality. (* dependent induction tactic *)
51-
(* More hacks for weak conversion and pattern matching... *)
52-
Definition nat2DField (n : nat) : DFieldTypes Count. compute; assumption. Defined.
53-
Definition nat2DField' (n : nat) : DFieldTypes (@F1 (S O)). compute; assumption. Defined.
54-
Definition Count2nat (n : DFieldTypes Count) : nat. compute; assumption. Defined.
55-
Definition bool2DField (b : bool) : DFieldTypes Flag. compute; assumption. Defined.
56-
Print nat2DField'.
39+
Instance dfields : FieldTyping D Dfield.
40+
Instance dfield_count : FieldType D Dfield Count nat := {
41+
getF := fun v => match v with (mkD n b) => n end;
42+
setF := fun v fv => match v with (mkD n b) => (mkD fv b) end
43+
}.
44+
Instance dfield_flag : FieldType D Dfield Flag bool := {
45+
getF := fun v => match v with (mkD n b) => b end;
46+
setF := fun v fv => match v with (mkD n b) => (mkD n fv) end
47+
}.
48+
5749
Definition getCount (d:D) := match d with (mkD n b) => n end.
5850
Definition getFlag (d:D) := match d with (mkD n b) => b end.
59-
Program Instance DAccess : FieldAccess D DFieldTypes :=
60-
(* Ideally we'd just directly define, but Coq's pattern matching is weak, so we'll use the refine tactic. :=*)
61-
{ fieldOf := fun obj x => (*match obj with (mkD n b) =>
62-
match x as x in t _ return DFieldTypes _ with
63-
| F1 f1n => _
64-
| FS fsn finB => _
65-
end
66-
end;*)
67-
(* match x as y return (x = y -> DFieldTypes x) with*)
68-
match x as y return DFieldTypes x with
69-
| F1 f1n => _
70-
| FS fsn finB => _
71-
end ;
7251

73-
fieldUpdate := fun obj f v =>
74-
match obj with (mkD n b) =>
75-
match f as f return D with
76-
| (F1 f1n) => mkD (_ n) b
77-
| (FS fsn finB) => mkD n (_ b)
78-
end
79-
end
80-
}.
81-
Next Obligation. compute. induction x. refine (getCount obj). refine (getFlag obj). Defined.
82-
Next Obligation. compute. induction x. refine (getCount obj). refine (getFlag obj). Defined.
83-
84-
Print DAccess.
85-
(*
86-
constructor.
87-
(* fieldOf *) intro obj. intro x. destruct obj.
88-
dependent induction x; red; auto.
89-
(* fieldUpdate *) intros obj x v. destruct obj.
90-
dependent induction x; compute [DFieldTypes] in *. exact (mkD v b). exact (mkD n v).
91-
Defined.*)
9252
(* Print DAccess. (* <-- that is a terrible term due to dependent induction *) *)
9353
Instance pureD : pure_type D.
9454
Program Example demo {Γ} (r : ref{D|any}[deltaD,deltaD]) : rgref Γ unit Γ :=
95-
@field_write Γ D _ _ _ _ _ DAccess r Count (nat2DField ((Count2nat (@field_read _ _ _ _ _ _ _ _ _ _ _ DAccess r (DField2Fin Count) _)) + 1)) _.
55+
@field_write Γ D Dfield nat _ _ _ r Count ((@field_read _ D Dfield _ _ _ _ _ _ _ r Count _ _)+1) _ _ _.
56+
(* @field_write Γ D _ _ _ _ _ DAccess r Count (nat2DField ((Count2nat (@field_read _ _ _ _ _ _ _ _ _ _ _ DAccess r (DField2Fin Count) _)) + 1)) _.
9657
Next Obligation.
9758
cut (forall f p1 p2 p3, @eq (DFieldTypes f) (@field_read D D _ _ _ _ _ DFieldTypes _ p1 p2 DAccess r f p3) (@fieldOf D _ DFieldTypes DAccess (@fold D _ deltaD deltaD v) f)).
9859
intro Hcomp. rewrite Hcomp with (f := F1).
@@ -107,5 +68,19 @@ Print DAccess.
10768
(* At this point we *should* be done, but the use of dependent induction to work around
10869
Coq's pattern matching has introduced some uses of JMeq to deal with *)
10970
generalize (@JMeq_eq (t (S (S O))) (@F1 (S O)) (@F1 (S O)) (@JMeq_refl (t (S (S O))) (@F1 (S O)))).
110-
intro e. elim e.
71+
intro e. elim e.*)
72+
73+
Next Obligation. unfold demo_obligation_1. unfold demo_obligation_2.
74+
Check @getF.
75+
cut (forall P R G pf1 pf2 r f fs fi,
76+
@field_read D D Dfield nat P R G (@pure_fold D pureD) pf1 pf2 r f fs fi =
77+
@getF D Dfield _ f nat _ v).
78+
intros Hfieldstuff.
79+
destruct v.
80+
rewrite Hfieldstuff.
81+
compute. fold plus. constructor. eauto with arith.
82+
(* this should be abstracted to a general hypothesis supplied by
83+
the write framework. *)
84+
admit.
85+
Qed.
11186
End FieldDemo.

0 commit comments

Comments
 (0)