Qcert.Basic.Util.RUtil
Section RUtil.
Section bools.
Lemma andb_true_inversion:
∀ b1 b2 : bool,
andb b1 b2 = true ↔ b1 = true ∧ b2 = true.
Lemma four_cases {A:Type} :
∀ (p1 p2: A → bool) (a:A),
((((p1 a) = true) ∧ ((p2 a) = true)) ∨
(((p1 a) = true) ∧ ((p2 a) = false))) ∨
((((p1 a) = false) ∧ ((p2 a) = true)) ∨
(((p1 a) = false) ∧ ((p2 a) = false))).
Lemma two_cases {A:Type} :
∀ (p: A → bool) (a:A),
((p a) = true) ∨ ((p a) = false).
Lemma notand p q:
~(p ∨ q) → ¬p ∧ ¬q.
Lemma eq_implies_pred {A:Type} :
∀ (p:A → bool), ∀ (x1 x2:A),
x1 = x2 → (p x1) = (p x2).
Lemma not_pred_implies_neq {A:Type}:
∀ (p:A → bool), ∀ (x1 x2:A),
(p x1) ≠ (p x2) → x1 ≠ x2.
End bools.
Section In.
Context {A:Type}.
Lemma In_app (x:A) (l1 l2:list A):
In x (l1 ++ l2) → In x l1 ∨ In x l2.
Lemma In_app_comm (v:A) (l1 l2:list A) :
In v (l1++l2) → In v (l2++l1).
Lemma In_app_iff (v:A) (l1 l2:list A) :
In v (l1++l2) ↔ In v (l2++l1).
Lemma find_In {f l} {b:A} : find f l = Some b → In b l.
Lemma find_correct {f l} {b:A} : find f l = Some b → f b = true.
Lemma app_or_in (x:A) (l1 l2: list A) :
In x (l1 ++ l2) → In x l1 ∨ In x l2.
Lemma app_or_in_iff (x:A) (l1 l2: list A) :
In x (l1 ++ l2) ↔ In x l1 ∨ In x l2.
Lemma in_or_not (eqd:∀ a a':A, {a=a'} + {a≠a'}) (l:list A) a:
(In a l) ∨ ~(In a l).
Lemma nin_app_or (x:A) a b :
(¬ In x (a ++ b)) ↔ (¬ In x a ∧ ¬ In x b).
Lemma in_in_app_false {l l1 l2} :
(∀ x:A,
In x l →
In x (l1 ++ l2) → False) →
((∀ x,
In x l →
In x l1 → False) ∧
(∀ x,
In x l →
In x l2 → False)).
Lemma in_in_cons_app_false {v l l1 l2} :
(∀ x:A,
In x l →
v = x ∨ In x (l1 ++ l2) → False) →
((∀ x,
In x l →
In x (l1) → False) ∧
(∀ x,
In x l →
In x (l2) → False) ∧
¬ (In v l)).
Lemma in_in_cons_cons_app_app_false {v v0 l l1 l2 l3} :
(∀ x:A,
In x l →
v = x ∨ v0 = x ∨ In x (l1 ++ l2 ++ l3) → False) →
((∀ x,
In x l →
In x l1 → False) ∧
(∀ x,
In x l →
In x l2 → False) ∧
(∀ x,
In x l →
In x l3 → False) ∧
¬ (In v l) ∧
¬ (In v0 l)).
End In.
Section forallt.
Inductive Forallt {A : Type} (P : A → Type) : list A → Type :=
Forallt_nil : Forallt P nil
| Forallt_cons : ∀ (x : A) (l : list A),
P x → Forallt P l → Forallt P (x :: l).
Lemma list_Forallt_eq_dec {A:Type}:
∀ (c l: list A),
Forallt (fun x : A ⇒ ∀ y : A, {x = y} + {x ≠ y}) c → {c = l} + {c ≠ l}.
Lemma forallt_impl {A} {P1 P2:A→Type} {l:list A} :
Forallt P1 l → Forallt (fun x ⇒ P1 x → P2 x) l → Forallt P2 l.
Lemma forallt_weaken {A} P : (∀ x:A, P x) → ∀ l, Forallt P l.
Lemma Forallt_inv: ∀ A P (a:A) l, Forallt P (a :: l) → P a.
Lemma Forallt_inv2: ∀ A P (a:A) l, Forallt P (a :: l) → Forallt P l.
Lemma Forallt_In {A:Type} {P:A→Type} {r} {eq:EqDec A eq}:
Forallt P r → ∀ a, In a r → P a.
Lemma Forall_app {A} (P:A→Prop) (l1 l2:list A):
Forall P l1 → Forall P l2 →
Forall P (l1 ++ l2).
Lemma Forall_app_inv {A : Type} {P : A → Prop} (l1 l2 : list A) :
Forall P (l1 ++ l2) → Forall P l1 ∧ Forall P l2.
Lemma Forall_map {A B} P (f:A→B) l:
Forall P (map f l) ↔
Forall (fun x ⇒ P (f x)) l.
Lemma Forall_impl_in {A} {P Q : A → Prop} {l} :
(∀ a, In a l → P a → Q a) →
Forall P l → Forall Q l.
Lemma Forallt_Forall {A:Prop} (P:A→Prop) (l:list A) :
Forallt P l → Forall P l.
End forallt.
Section forallb.
Lemma forallb_ext {A} f1 f2 (l:list A) :
(∀ x, In x l → f1 x = f2 x) →
forallb f1 l = forallb f2 l.
Lemma forallb_incl {A} f (l1 l2 : list A) :
incl l1 l2 →
forallb f l2 = true →
forallb f l1 = true.
Lemma forallb_app {A} (f:A→bool) l1 l2 :
forallb f (l1 ++ l2) = true ↔
(forallb f l1 = true ∧ forallb f l2 = true).
Lemma forallb_map {A B} f (mf:A→B) m : forallb f (map mf m) = forallb ((fun x ⇒ f (mf x))) m.
Lemma existsb_not_forallb {A} f (l:list A)
: existsb f l = negb (forallb (fun x ⇒ negb (f x)) l).
Lemma forallb_not_existb {A} f (l:list A)
: forallb f l = negb (existsb (fun x ⇒ negb (f x)) l).
Lemma map_eq {A B} {f g:A→B} {l} :
Forall (fun x ⇒ f x = g x) l →
map f l = map g l.
Lemma map_cons {A B:Type} (f:A→B) (l:list A) (a:A) :
map f (a::l) = (f a)::map f l.
Lemma map_eq_cons {A B} (f : A → B) (l:list A) b l' :
map f l = b::l' →
{a : A & {ls:list A | l = a::ls ∧f a = b ∧ map f ls = l'}}.
End forallb.
Section pairs.
Lemma pair_eq_dec {A B:Type} (a1:A) (b1:B) (a2:A) (b2:B) :
{a1 = a2} + {a1 ≠ a2} →
{b1 = b2} + {b1 ≠ b2} →
{(a1, b1) = (a2, b2)} + {(a1, b1) ≠ (a2, b2)}.
Global Instance string_eqdec : EqDec String.string eq := String.string_dec.
Global Instance pair_eqdec {A B} `{EqDec A eq} `{EqDec B eq} : EqDec (prod A B) eq.
Global Instance option_eqdec {A:Type} `{EqDec A eq}: EqDec (option A) eq.
End pairs.
Section arith.
Lemma min_zero:
∀ (n1 n2:nat), min n1 (S n2) = 0 → n1 = 0.
Lemma min_against_one:
∀ (n:nat), min n 1 = 0 ∨ min n 1 = 1.
Lemma compare_either (n1 n2:nat):
(n1 ≤ n2) ∨ (n2 ≤ n1).
Lemma min_one_yields_one:
∀ n:nat, min n 1 = 1 → 1 ≤ n.
Lemma fold_left_arith_dist1 {A} (x0:nat) (l:list A) (f:A → nat):
fold_left (fun (x:nat) (y:A) ⇒ (f y) + x) l x0 =
(fold_left (fun (x:nat) (y:A) ⇒ (f y) + x) l 0) + x0.
Lemma fold_left_arith_dist2 {A} (x0 n0:nat) (l:list A) (f:A → nat):
fold_left (fun (x:nat) (y:A) ⇒ n0 × (f y) + x) l x0 =
n0 × (fold_left (fun (x:nat) (y:A) ⇒ (f y) + x) l 0) + x0.
Lemma fold_left_arith_dist3 {A} (x0 n0:nat) (l:list A) (f:A → nat):
n0 × (fold_left (fun (x:nat) (y:A) ⇒ (f y) + x) l 0) + x0 =
n0 × (fold_left (fun (x:nat) (y:A) ⇒ x + (f y)) l 0) + x0.
Lemma fold_left_arith_dist4 {A} (x0 n0:nat) (l:list A) (f:A → nat):
fold_left (fun (x:nat) (y:A) ⇒ n0 × (f y) + x) l x0 =
n0 × (fold_left (fun (x:nat) (y:A) ⇒ x + (f y)) l 0) + x0.
End arith.
Section Zutil.
Definition ZToSignedNat (z:Z) : (bool×nat) :=
match (Z.sgn z) with
| -1 ⇒ (false,(Z.to_nat z))
| _ ⇒ (true, (Z.to_nat z))
end.
Lemma pos_succ_inv (n1 n2:positive):
(Pos.succ n1 = Pos.succ n2 → n1 = n2).
Lemma Pos_of_nat_inv (n1 n2:nat) :
Pos.of_nat (S n1) = Pos.of_nat (S n2) → n1 = n2.
Lemma of_nat_inv (n1 n2:nat) :
Z.of_nat n1 = Z.of_nat n2 → n1 = n2.
Lemma pos_succ_nat_inv (n1 n2:nat) :
Pos.of_succ_nat n1 = Pos.of_succ_nat n2 → n1 = n2.
Global Instance Z_eqdec : EqDec Z eq.
End Zutil.
Section iter.
Lemma repeat_plus {A} (x:A) (n1 n2:nat) :
repeat x (n1+n2) = repeat x n1 ++ repeat x n2.
Fixpoint iter {A} (f:A→A) (iterations:nat) (a:A)
:= match iterations with
| 0 ⇒ a
| S n ⇒ iter f n (f a)
end.
Lemma iter_fold_left_list {A B} (f:A→A) (l:list B) (a:A)
: iter f (length l) a = fold_left (fun x y ⇒ f x) l a.
Lemma iter_fold_left_repeat {A} (f:A→A) (iterations:nat) (a:A)
: iter f iterations a = fold_left (fun x y ⇒ f x) (repeat 0 iterations) a.
Lemma iter_fold_right_list {A B} (f:A→A) (l:list B) (a:A)
: iter f (length l) a = fold_right (fun x y ⇒ f y) a l.
Lemma iter_plus {A} (f:A→A) (iterations1 iterations2:nat) (a:A) :
iter f (iterations1+iterations2) a = iter f iterations2 (iter f iterations1 a).
Lemma iter_trans {A} (R:relation A) {pre:PreOrder R} f
(pf:∀ x, R x (f x)) (iterations:nat) a :
R a (iter f iterations a).
End iter.
Section cost.
Context {A:Type}.
Function iter_cost (optim: A → A) (cost: A → nat) (p: A) { measure cost p } :=
let p' := optim p in
if lt_dec (cost p') (cost p)
then iter_cost optim cost p'
else p.
Lemma iter_cost_trans (R:relation A) {pre:PreOrder R} f
(pf:∀ x, R x (f x)) (cost:A→nat) a :
R a (iter_cost f cost a).
End cost.
Section vm.
Definition is_true {A B} (x:{A}+{B}) : bool :=
Eval vm_compute in (if x then true else false).
Definition holds {A B} (x:{A}+{B}) : Prop :=
is_true x = true.
End vm.
End RUtil.
Tactic Notation "assert_eq" ident(x) constr(v) :=
let H := fresh in
assert (x = v) as H by reflexivity;
clear H.
Tactic Notation "Case_aux" ident(x) constr(name) :=
first [
set (x := name); move_to_top x
| assert_eq x name; move_to_top x
| fail 1 "because we are working on a different case" ].
Tactic Notation "Case" constr(name) := Case_aux Case name.
Tactic Notation "SCase" constr(name) := Case_aux SCase name.
Tactic Notation "SSCase" constr(name) := Case_aux SSCase name.
Tactic Notation "SSSCase" constr(name) := Case_aux SSSCase name.
Tactic Notation "SSSSCase" constr(name) := Case_aux SSSSCase name.
Tactic Notation "SSSSSCase" constr(name) := Case_aux SSSSSCase name.
Tactic Notation "SSSSSSCase" constr(name) := Case_aux SSSSSSCase name.
Tactic Notation "SSSSSSSCase" constr(name) := Case_aux SSSSSSSCase name.
Definition brand := string.
Class ToString (A:Type)
:= {
toString (a:A) : string
}.