From f1d236b83003eda71e12840732d159fd23b1b771 Mon Sep 17 00:00:00 2001 From: xleroy Date: Tue, 29 Apr 2014 13:58:18 +0000 Subject: Integration of Jacques-Henri Jourdan's verified parser. (Merge of branch newparser.) git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2469 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- cparser/validator/Alphabet.v | 321 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) create mode 100644 cparser/validator/Alphabet.v (limited to 'cparser/validator/Alphabet.v') diff --git a/cparser/validator/Alphabet.v b/cparser/validator/Alphabet.v new file mode 100644 index 00000000..f47f1360 --- /dev/null +++ b/cparser/validator/Alphabet.v @@ -0,0 +1,321 @@ +(* *********************************************************************) +(* *) +(* The Compcert verified compiler *) +(* *) +(* Jacques-Henri Jourdan, INRIA Paris-Rocquencourt *) +(* *) +(* Copyright Institut National de Recherche en Informatique et en *) +(* Automatique. All rights reserved. This file is distributed *) +(* under the terms of the GNU General Public License as published by *) +(* the Free Software Foundation, either version 2 of the License, or *) +(* (at your option) any later version. This file is also distributed *) +(* under the terms of the INRIA Non-Commercial License Agreement. *) +(* *) +(* *********************************************************************) + +Require Import Int31. +Require Import Cyclic31. +Require Import Omega. +Require Import List. +Require Import Syntax. +Require Import Relations. +Require Import RelationClasses. + +Local Obligation Tactic := intros. + +(** A comparable type is equiped with a [compare] function, that define an order + relation. **) +Class Comparable (A:Type) := { + compare : A -> A -> comparison; + compare_antisym : forall x y, CompOpp (compare x y) = compare y x; + compare_trans : forall x y z c, + (compare x y) = c -> (compare y z) = c -> (compare x z) = c +}. + +Theorem compare_refl {A:Type} (C: Comparable A) : + forall x, compare x x = Eq. +Proof. +intros. +pose proof (compare_antisym x x). +destruct (compare x x); intuition; try discriminate. +Qed. + +(** The corresponding order is a strict order. **) +Definition comparableLt {A:Type} (C: Comparable A) : relation A := + fun x y => compare x y = Lt. + +Instance ComparableLtStrictOrder {A:Type} (C: Comparable A) : + StrictOrder (comparableLt C). +Proof. +apply Build_StrictOrder. +unfold Irreflexive, Reflexive, complement, comparableLt. +intros. +pose proof H. +rewrite <- compare_antisym in H. +rewrite H0 in H. +discriminate H. +unfold Transitive, comparableLt. +intros x y z. +apply compare_trans. +Qed. + +(** nat is comparable. **) +Program Instance natComparable : Comparable nat := + { compare := nat_compare }. +Next Obligation. +symmetry. +destruct (nat_compare x y) as [] eqn:?. +rewrite nat_compare_eq_iff in Heqc. +destruct Heqc. +rewrite nat_compare_eq_iff. +trivial. +rewrite <- nat_compare_lt in *. +rewrite <- nat_compare_gt in *. +trivial. +rewrite <- nat_compare_lt in *. +rewrite <- nat_compare_gt in *. +trivial. +Qed. +Next Obligation. +destruct c. +rewrite nat_compare_eq_iff in *; destruct H; assumption. +rewrite <- nat_compare_lt in *. +apply (lt_trans _ _ _ H H0). +rewrite <- nat_compare_gt in *. +apply (gt_trans _ _ _ H H0). +Qed. + +(** A pair of comparable is comparable. **) +Program Instance PairComparable {A:Type} (CA:Comparable A) {B:Type} (CB:Comparable B) : + Comparable (A*B) := + { compare := fun x y => + let (xa, xb) := x in let (ya, yb) := y in + match compare xa ya return comparison with + | Eq => compare xb yb + | x => x + end }. +Next Obligation. +destruct x, y. +rewrite <- (compare_antisym a a0). +rewrite <- (compare_antisym b b0). +destruct (compare a a0); intuition. +Qed. +Next Obligation. +destruct x, y, z. +destruct (compare a a0) as [] eqn:?, (compare a0 a1) as [] eqn:?; +try (rewrite <- H0 in H; discriminate); +try (destruct (compare a a1) as [] eqn:?; + try (rewrite <- compare_antisym in Heqc0; + rewrite CompOpp_iff in Heqc0; + rewrite (compare_trans _ _ _ _ Heqc0 Heqc2) in Heqc1; + discriminate); + try (rewrite <- compare_antisym in Heqc1; + rewrite CompOpp_iff in Heqc1; + rewrite (compare_trans _ _ _ _ Heqc2 Heqc1) in Heqc0; + discriminate); + assumption); +rewrite (compare_trans _ _ _ _ Heqc0 Heqc1); +try assumption. +apply (compare_trans _ _ _ _ H H0). +Qed. + +(** Special case of comparable, where equality is usual equality. **) +Class ComparableUsualEq {A:Type} (C: Comparable A) := + compare_eq : forall x y, compare x y = Eq -> x = y. + +(** Boolean equality for a [Comparable]. **) +Definition compare_eqb {A:Type} {C:Comparable A} (x y:A) := + match compare x y with + | Eq => true + | _ => false + end. + +Theorem compare_eqb_iff {A:Type} {C:Comparable A} {U:ComparableUsualEq C} : + forall x y, compare_eqb x y = true <-> x = y. +Proof. +unfold compare_eqb. +intuition. +apply compare_eq. +destruct (compare x y); intuition; discriminate. +destruct H. +rewrite compare_refl; intuition. +Qed. + +(** [Comparable] provides a decidable equality. **) +Definition compare_eqdec {A:Type} {C:Comparable A} {U:ComparableUsualEq C} (x y:A): + {x = y} + {x <> y}. +Proof. +destruct (compare x y) as [] eqn:?; [left; apply compare_eq; intuition | ..]; + right; intro; destruct H; rewrite compare_refl in Heqc; discriminate. +Defined. + +Instance NComparableUsualEq : ComparableUsualEq natComparable := nat_compare_eq. + +(** A pair of ComparableUsualEq is ComparableUsualEq **) +Instance PairComparableUsualEq + {A:Type} {CA:Comparable A} (UA:ComparableUsualEq CA) + {B:Type} {CB:Comparable B} (UB:ComparableUsualEq CB) : + ComparableUsualEq (PairComparable CA CB). +Proof. +intros x y; destruct x, y; simpl. +pose proof (compare_eq a a0); pose proof (compare_eq b b0). +destruct (compare a a0); try discriminate. +intuition. +destruct H2, H0. +reflexivity. +Qed. + +(** An [Finite] type is a type with the list of all elements. **) +Class Finite (A:Type) := { + all_list : list A; + all_list_forall : forall x:A, In x all_list +}. + +(** An alphabet is both [ComparableUsualEq] and [Finite]. **) +Class Alphabet (A:Type) := { + AlphabetComparable :> Comparable A; + AlphabetComparableUsualEq :> ComparableUsualEq AlphabetComparable; + AlphabetFinite :> Finite A +}. + +(** The [Numbered] class provides a conveniant way to build [Alphabet] instances, + with a good computationnal complexity. It is mainly a injection from it to + [Int31] **) +Class Numbered (A:Type) := { + inj : A -> int31; + surj : int31 -> A; + surj_inj_compat : forall x, surj (inj x) = x; + inj_bound : int31; + inj_bound_spec : forall x, (phi (inj x) < phi inj_bound)%Z +}. + +Program Instance NumberedAlphabet {A:Type} (N:Numbered A) : Alphabet A := + { AlphabetComparable := + {| compare := fun x y => compare31 (inj x) (inj y) |}; + AlphabetFinite := + {| all_list := fst (iter_int31 inj_bound _ + (fun p => (cons (surj (snd p)) (fst p), incr (snd p))) ([], 0%int31)) |} }. +Next Obligation. apply Zcompare_antisym. Qed. +Next Obligation. +destruct c. unfold compare31 in *. +rewrite Z.compare_eq_iff in *. congruence. +eapply Zcompare_Lt_trans; eauto. +eapply Zcompare_Gt_trans; eauto. +Qed. +Next Obligation. +intros x y H. unfold compare, compare31 in H. +rewrite Z.compare_eq_iff in *. +rewrite <- surj_inj_compat, <- phi_inv_phi with (inj y), <- H. +rewrite phi_inv_phi, surj_inj_compat; reflexivity. +Qed. +Next Obligation. +rewrite iter_int31_iter_nat. +pose proof (inj_bound_spec x). +match goal with |- In x (fst ?p) => destruct p as [] eqn:? end. +replace inj_bound with i in H. +revert l i Heqp x H. +apply iter_nat_invariant; intros. +inversion Heqp; clear Heqp; subst. +destruct x; specialize (H _ _ (eq_refl _) x0); simpl in *. +rewrite phi_incr in H0. +pose proof (phi_bounded i). +pose proof (phi_bounded (inj x0)). +destruct (Z_lt_le_dec (Zsucc (phi i)) (2 ^ Z_of_nat size)%Z). +rewrite Zmod_small in H0 by omega. +apply Zlt_succ_le, Zle_lt_or_eq in H0. +destruct H0; eauto. +left. +rewrite <- surj_inj_compat, <- phi_inv_phi with (inj x0), H0, phi_inv_phi; reflexivity. +replace (Zsucc (phi i)) with (2 ^ Z_of_nat size)%Z in H0 by omega. +rewrite Z_mod_same_full in H0. +exfalso; omega. +exfalso; inversion Heqp; subst; + pose proof (phi_bounded (inj x)); change (phi 0) with 0%Z in H; omega. +clear H. +rewrite <- phi_inv_phi with i, <- phi_inv_phi with inj_bound; f_equal. +pose proof (phi_bounded inj_bound); pose proof (phi_bounded i). +rewrite <- Zabs_eq with (phi i), <- Zabs_eq with (phi inj_bound) by omega. +clear H H0. +do 2 rewrite <- inj_Zabs_nat. +f_equal. +revert l i Heqp. +assert (Zabs_nat (phi inj_bound) < Zabs_nat (2^31)). +apply Zabs_nat_lt, phi_bounded. +induction (Zabs_nat (phi inj_bound)); intros. +inversion Heqp; reflexivity. +inversion Heqp; clear H1 H2 Heqp. +match goal with |- _ (_ (_ (snd ?p))) = _ => destruct p end. +pose proof (phi_bounded i0). +erewrite <- IHn, <- Zabs_nat_Zsucc in H |- *; eauto; try omega. +rewrite phi_incr, Zmod_small; intuition; try omega. +apply inj_lt in H. +pose proof Zle_le_succ. +do 2 rewrite inj_Zabs_nat, Zabs_eq in H; eauto. +Qed. + +(** Previous class instances for [option A] **) +Program Instance OptionComparable {A:Type} (C:Comparable A) : Comparable (option A) := + { compare := fun x y => + match x, y return comparison with + | None, None => Eq + | None, Some _ => Lt + | Some _, None => Gt + | Some x, Some y => compare x y + end }. +Next Obligation. +destruct x, y; intuition. +apply compare_antisym. +Qed. +Next Obligation. +destruct x, y, z; try now intuition; +try (rewrite <- H in H0; discriminate). +apply (compare_trans _ _ _ _ H H0). +Qed. + +Instance OptionComparableUsualEq {A:Type} {C:Comparable A} (U:ComparableUsualEq C) : + ComparableUsualEq (OptionComparable C). +Proof. +intros x y. +destruct x, y; intuition; try discriminate. +rewrite (compare_eq a a0); intuition. +Qed. + +Program Instance OptionFinite {A:Type} (E:Finite A) : Finite (option A) := + { all_list := None :: map Some all_list }. +Next Obligation. +destruct x; intuition. +right. +apply in_map. +apply all_list_forall. +Defined. + +(** Definitions of [FSet]/[FMap] from [Comparable] **) +Require Import OrderedType. +Require Import OrderedTypeAlt. +Require FSetAVL. +Require FMapAVL. + +Module Type ComparableM. + Parameter t : Type. + Declare Instance tComparable : Comparable t. +End ComparableM. + +Module OrderedTypeAlt_from_ComparableM (C:ComparableM) <: OrderedTypeAlt. + Definition t := C.t. + Definition compare : t -> t -> comparison := compare. + + Infix "?=" := compare (at level 70, no associativity). + + Lemma compare_sym x y : (y?=x) = CompOpp (x?=y). + Proof. exact (Logic.eq_sym (compare_antisym x y)). Qed. + Lemma compare_trans c x y z : + (x?=y) = c -> (y?=z) = c -> (x?=z) = c. + Proof. + apply compare_trans. + Qed. +End OrderedTypeAlt_from_ComparableM. + +Module OrderedType_from_ComparableM (C:ComparableM) <: OrderedType. + Module Alt := OrderedTypeAlt_from_ComparableM C. + Include (OrderedType_from_Alt Alt). +End OrderedType_from_ComparableM. -- cgit