Library DistributedReferenceCounting.expose


Set Asymmetric Patterns.

Require Export ZArith.
Require Export Omega.


Section CONFIGURATION.

Definition counter := Z.

Record Config : Set := mkconfig {co : counter}.

Variable x : Z.

Definition mk_init_config := mkconfig x.

End CONFIGURATION.


Section TRANSITIONS.

Definition decrement_trans (c : Config) := mkconfig (co c - 1)%Z.

Definition divide_trans (c : Config) := mkconfig (Zeven.Zdiv2 (co c)).

Inductive transition (c : Config) : Set :=
  | decrement : (co c > 0)%Z Zeven.Zodd (co c) transition c
  | divide : (co c > 0)%Z Zeven.Zeven (co c) transition c.

Definition next_config (c : Config) (t : transition c) :=
  match t with
  | decrement h1 h2decrement_trans c
  | divide h1 h2divide_trans c
  end.

Variable x : Z.

Inductive legal : Config Prop :=
  | begin : legal (mk_init_config x)
  | after :
       (c : Config) (t : transition c),
      legal c legal (next_config c t).

End TRANSITIONS.


Lemma Zdiv2_positive :
  x : Z, Zeven.Zeven x (x 0)%Z (Zeven.Zdiv2 x 0)%Z.
Proof.
  simple destruct x.
  simpl in |- ×.
  omega.

  simpl in |- ×.
  simple destruct p.
  intuition.

  simpl in |- ×.
  intros.
  auto.

  intuition.

  simpl in |- ×.
  simple destruct p.
  intuition.

  simpl in |- ×.
  intuition.

  intuition.
Qed.

Lemma x_gt_Zdiv2 :
  x : Z, Zeven.Zeven x (x > 0)%Z (x > Zeven.Zdiv2 x)%Z.
Proof.
  simple destruct x.
  simpl in |- ×.
  auto.

  simpl in |- ×.
  simple destruct p.
  intuition.

  simpl in |- ×.
  intros.
  rewrite BinInt.Zpos_xO.
  generalize H0.
  rewrite BinInt.Zpos_xO.
  intro.
  omega.

  auto.

  discriminate.
Qed.

Lemma counter_remains_positive_or_null :
  (x : Z) (c : Config), (x 0)%Z legal x c (co c 0)%Z.
Proof.
  intros.
  elim H0.
  simpl in |- ×.
  auto.

  simple induction t.
  simpl in |- ×.
  intros.
  omega.

  simpl in |- ×.
  intros.
  apply Zdiv2_positive.
  auto.

  auto.

Qed.

Lemma decreasing_measure :
  (c : Config) (t : transition c), (co c > co (next_config c t))%Z.
Proof.
  simple induction t.
  simpl in |- *; intros.
  omega.
  simpl in |- ×.
  intros.
  apply x_gt_Zdiv2.
  auto.
  auto.
Qed.

Lemma liveness :
  (x : Z) (c : Config),
 legal x c
 (co c > 0)%Z t : transition c, legal x (next_config c t).
Proof.
  intros.
  generalize (Zeven.Zeven_odd_dec (co c)).
  intro.
  elim H1.
  intro.
  split with (divide c H0 a).
  apply after.
  auto.

  intro.
  split with (decrement c H0 b).
  apply after.
  auto.
Qed.

Lemma blocked :
  c : Config, (co c 0)%Z ¬ ( t : transition c, True).
Proof.
  intros.
  unfold not in |- *; intro.
  elim H0.
  intro.
  elim x.
  intro.
  intuition.

  intro.
  intuition.
Qed.

Lemma recur2 :
  P : nat Prop,
 ( n : nat, ( p : nat, p < n P p) P n)
  m : nat, P m.
Proof.
intros; apply H; elim m.
intros; absurd (p < 0); auto with arith.

intros; case (le_lt_eq_dec p n).
 auto with arith.
 auto with arith.
intro; rewrite e; apply H; auto.
Qed.

Lemma natgen_ind :
  P : Z Prop,
 ( x : Z,
  (0 x)%Z ( y : Z, (0 y)%Z (y < x)%Z P y) P x)
  x : Z, (0 x)%Z P x.
Proof.
intros; apply Z_of_nat_prop.
intro; apply recur2 with (P := fun n : natP (Z_of_nat n)).
intros; apply H.
omega.

intro; intro;
 apply Z_of_nat_prop with (P := fun y : Z ⇒ (y < Z_of_nat n0)%Z P y).
intros; apply H1; omega.

trivial.

trivial.
Qed.

Lemma rec2_princ :
  P : Z Prop,
 P 0%Z
 ( x : Z, Zeven.Zeven x (x > 0)%Z P (Zeven.Zdiv2 x) P x)
 ( x : Z, Zeven.Zodd x (x > 0)%Z P (x - 1)%Z P x)
  x : Z, (x 0)%Z P x.
Proof.
intros; apply natgen_ind; intros.
case (Z_le_lt_eq_dec 0 x0 H3); intro.
case (Zeven.Zeven_odd_dec x0); intro.
apply H0.
auto.

omega.

apply H4.
apply Zge_le; apply Zdiv2_positive; [ trivial | omega ].

apply Zgt_lt; apply x_gt_Zdiv2; [ trivial | omega ].

apply H1.
trivial.

omega.

apply H4; omega.

rewrite <- e; trivial.

omega.
Qed.

Lemma legal_x_x : x : Z, legal x (mkconfig x).
Proof.
intro; generalize (begin x); unfold mk_init_config in |- *; trivial.
Qed.

Lemma simpl_config : c : Config, mkconfig (co c) = c.
Proof.
simple induction c; auto.
Qed.

Lemma legal_trans :
  (x : Z) (c c' : Config), legal x c legal (co c) c' legal x c'.
Proof.
intros; elim H0.
unfold mk_init_config in |- *; rewrite simpl_config; trivial.

intros; apply after; trivial.
Qed.

Lemma legal_decrement :
  (x : Z) (c : Config),
 (x > 0)%Z Zeven.Zodd x legal (x - 1) c legal x c.
Proof.
intros; apply legal_trans with (c := decrement_trans (mkconfig x)).
cut (co (mkconfig x) > 0)%Z.
intro; cut (Zeven.Zodd (co (mkconfig x))).
intro;
 replace (decrement_trans (mkconfig x)) with
  (next_config (mkconfig x) (decrement (mkconfig x) H2 H3)).
apply after.
apply legal_x_x.

auto.

auto.

simpl in |- ×.
auto.

auto.
Qed.

Lemma legal_divide :
  (x : Z) (c : Config),
 (x > 0)%Z Zeven.Zeven x legal (Zeven.Zdiv2 x) c legal x c.
Proof.
intros; apply legal_trans with (c := divide_trans (mkconfig x)).
cut (co (mkconfig x) > 0)%Z.
intro; cut (Zeven.Zeven (co (mkconfig x))).
intro;
 replace (divide_trans (mkconfig x)) with
  (next_config (mkconfig x) (divide (mkconfig x) H2 H3)).
apply after.
apply legal_x_x.

auto.

auto.

auto.

auto.
Qed.

Lemma fin_O : x : Z, (x 0)%Z legal x (mkconfig 0%Z).
Proof.
intros; apply rec2_princ with (P := fun x : Zlegal x (mkconfig 0%Z)).
apply legal_x_x.

intros; apply legal_divide; auto.

intros; apply legal_decrement; auto.

trivial.
Qed.

Lemma termination :
  x : Z,
  c : Config, legal x c ¬ ( t : transition c, True).
Proof.
intro; case (Z_lt_ge_dec x 0); intros.
split with (mkconfig x).
split.
apply legal_x_x.

apply blocked; simpl in |- *; omega.

split with (mkconfig 0%Z); split.
apply fin_O; auto with arith.

apply blocked; simpl in |- *; auto with zarith.
Qed.