Contents:
Library ConCert.Utils.Env
From Coq Require Import String.
From Coq Require Import List.
From Coq Require Import PeanoNat.
From Coq Require Import Lia.
From ConCert.Utils Require Import Automation.
Import ListNotations.
Definition env (A : Type) := list (string * A).
Lookup by variable name
Fixpoint lookup {A} (ρ : env A) (key : string) : option A :=
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (eqb nm key)
then Some a
else lookup ρ' key
end.
Fixpoint lookup_with_ind_rec {A}
(i : nat)
(ρ : env A)
(key : string)
: option (nat * A) :=
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (eqb nm key)
then Some (i, a)
else lookup_with_ind_rec (1 + i) ρ' key
end.
Definition lookup_with_ind {A} (ρ : env A) (key : string) : option (nat * A) :=
lookup_with_ind_rec 0 ρ key.
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (eqb nm key)
then Some a
else lookup ρ' key
end.
Fixpoint lookup_with_ind_rec {A}
(i : nat)
(ρ : env A)
(key : string)
: option (nat * A) :=
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (eqb nm key)
then Some (i, a)
else lookup_with_ind_rec (1 + i) ρ' key
end.
Definition lookup_with_ind {A} (ρ : env A) (key : string) : option (nat * A) :=
lookup_with_ind_rec 0 ρ key.
Lookup by index (similar to List.nth_error), but defined by recursion on env
Fixpoint lookup_i {A} (ρ : env A) (i : nat) : option A :=
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (Nat.eqb i 0)
then Some a
else lookup_i ρ' (i - 1)
end.
match ρ with
| [] => None
| (nm, a) :: ρ' =>
if (Nat.eqb i 0)
then Some a
else lookup_i ρ' (i - 1)
end.
A value environment lookup:
A value environment extension:
Notation "ρ # [ k ~> v ]" := ((k,v) :: ρ) (at level 50).
Fixpoint remove_by_key {A} (key : string) (ρ : env A) : env A :=
match ρ with
| [] => []
| (nm, a) :: ρ' =>
if (eqb nm key)
then remove_by_key key ρ'
else (nm, a) :: (remove_by_key key ρ')
end.
Lemma lookup_i_length {A} (ρ : env A) n :
(n <? length ρ) = true -> {e | lookup_i ρ n = Some e}.
Proof.
intros H. generalize dependent n.
induction ρ; intros; propify; simpl in *.
cut False; only 1: (let hn := fresh "H" in intro hn; elim hn; try clear hn).
lia.
destruct a. destruct n.
+ simpl; eauto.
+ simpl.
assert (n < length ρ) by lia.
replace (n - 0) with n by lia.
apply IHρ.
now propify.
Qed.
Lemma lookup_i_length_false {A} (ρ : env A) n :
(n <? length ρ) = false -> lookup_i ρ n = None.
Proof.
intros H. generalize dependent n.
induction ρ; intros; propify; simpl in *; auto.
destruct a. destruct n.
+ simpl; eauto.
inversion H.
+ simpl.
assert (length ρ <= n) by lia.
replace (n - 0) with n by lia.
rewrite <- PeanoNat.Nat.ltb_ge in *.
now apply IHρ.
Qed.
Fixpoint remove_by_key {A} (key : string) (ρ : env A) : env A :=
match ρ with
| [] => []
| (nm, a) :: ρ' =>
if (eqb nm key)
then remove_by_key key ρ'
else (nm, a) :: (remove_by_key key ρ')
end.
Lemma lookup_i_length {A} (ρ : env A) n :
(n <? length ρ) = true -> {e | lookup_i ρ n = Some e}.
Proof.
intros H. generalize dependent n.
induction ρ; intros; propify; simpl in *.
cut False; only 1: (let hn := fresh "H" in intro hn; elim hn; try clear hn).
lia.
destruct a. destruct n.
+ simpl; eauto.
+ simpl.
assert (n < length ρ) by lia.
replace (n - 0) with n by lia.
apply IHρ.
now propify.
Qed.
Lemma lookup_i_length_false {A} (ρ : env A) n :
(n <? length ρ) = false -> lookup_i ρ n = None.
Proof.
intros H. generalize dependent n.
induction ρ; intros; propify; simpl in *; auto.
destruct a. destruct n.
+ simpl; eauto.
inversion H.
+ simpl.
assert (length ρ <= n) by lia.
replace (n - 0) with n by lia.
rewrite <- PeanoNat.Nat.ltb_ge in *.
now apply IHρ.
Qed.