(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
(* This file is (C) Copyright 2006-2015 Microsoft Corporation and Inria. *)
(** Declare Ssr keywords: "is" "isn't" "of" "//" "/=" and "//=". **)
Reserved Notation"(* x 'is' y 'of' z 'isn't' // /= //= *)".
(** Non ambiguous keyword to check if the SsrSyntax module is imported **)
Reserved Notation"(* Use to test if 'SsrSyntax_is_Imported' *)".
Reserved Notation"<hidden n >" (at level 0, n at level 0,
format "<hidden n >").
#[warning="-postfix-notation-not-level-1"]
Reserved Notation"T (* n *)" (at level 200, format "T (* n *)").
End SsrSyntax.
Export SsrMatchingSyntax. Export SsrSyntax.
(** Save primitive notation that will be overloaded. **) LocalNotation RocqGenericIf c vT vF := (if c then vT else vF) (only parsing). LocalNotation RocqGenericDependentIf c x R vT vF :=
(if c as x return R then vT else vF) (only parsing).
(** Reserve notation that introduced in this file. **)
Reserved Notation"'if' c 'then' vT 'else' vF" (at level 200,
c, vT, vF at level 200).
Reserved Notation"'if' c 'return' R 'then' vT 'else' vF" (at level 200,
c, R, vT, vF at level 200).
Reserved Notation"'if' c 'as' x 'return' R 'then' vT 'else' vF" (at level 200,
c, R, vT, vF at level 200, x name).
Reserved Notation"[ 'the' sT 'of' v 'by' f ]" (at level 0,
format "[ 'the' sT 'of' v 'by' f ]").
Reserved Notation"[ 'the' sT 'of' v ]" (at level 0,
format "[ 'the' sT 'of' v ]").
Reserved Notation"{ 'type' 'of' c 'for' s }" (at level 0,
format "{ 'type' 'of' c 'for' s }").
Reserved Notation"=^~ r" (at level 100, format "=^~ r").
Reserved Notation"[ 'unlockable' 'of' C ]" (at level 0,
format "[ 'unlockable' 'of' C ]").
Reserved Notation"[ 'unlockable' 'fun' C ]" (at level 0,
format "[ 'unlockable' 'fun' C ]").
Reserved Notation"[ 'elaborate' x ]" (at level 0).
(** Todefinenotationsfortacticinintropatterns.
When "=> /t" is parsed, "t:%ssripat" is actually interpreted. **) DeclareScope ssripat_scope. DelimitScope ssripat_scope with ssripat.
(** Makethegeneral"if"intoanotation,sothatwecanoverrideitbelow. Thenotationsare"onlyparsing"becausetheRocqdecompilerwillnot recognizetheexpansionofthebooleanif;usingthedefaultprinter
avoids a spurious trailing %%GEN_IF. **)
DeclareScope general_if_scope. DelimitScope general_if_scope with GEN_IF.
Notation"'if' c 'then' vT 'else' vF" :=
(RocqGenericIf c vT vF) (only parsing) : general_if_scope.
Notation"'if' c 'return' R 'then' vT 'else' vF" :=
(RocqGenericDependentIf c c R vT vF) (only parsing) : general_if_scope.
Notation"'if' c 'as' x 'return' R 'then' vT 'else' vF" :=
(RocqGenericDependentIf c x R vT vF) (only parsing) : general_if_scope.
(** Force boolean interpretation of simple if expressions. **)
DeclareScope boolean_if_scope. DelimitScope boolean_if_scope with BOOL_IF.
Notation"'if' c 'return' R 'then' vT 'else' vF" :=
(if c is true as c in bool return R then vT else vF) : boolean_if_scope.
Notation"'if' c 'then' vT 'else' vF" :=
(if c%bool is true as _ in bool return _ then vT else vF) : boolean_if_scope.
Notation"'if' c 'as' x 'return' R 'then' vT 'else' vF" :=
(if c%bool is true as x in bool return R then vT else vF) : boolean_if_scope.
OpenScope boolean_if_scope.
(** Toallowawidervarietyofnotationswithoutreservingalargenumberof ofidentifiers,thessreflectlibrarysystematicallyuses"forms"to enclosecomplexmixfixsyntax.A"form"issimplyamixfixexpression enclosedinsquarebracketsandintroducedbyakeyword: #[#keyword...#]# Becausethekeywordfollowsabracketitdoesnotneedtobereserved. Non-ssreflectlibrariesthatdonotrespecttheformsyntax(e.g.,theRocq Listslibrary)shouldbeloadedbeforessreflectsothattheirnotations
do not mask all ssreflect forms. **) DeclareScope form_scope. DelimitScope form_scope with FORM. OpenScope form_scope.
(** Constants for abstract: and #[#: name #]# intro pattern **) Definition abstract_lock := unit. Definition abstract_key := tt.
Definition abstract (statement : Type) (id : nat) (lock : abstract_lock) := let: tt := lock in statement.
DeclareScope ssr_scope. Notation"<hidden n >" := (abstract _ n _) : ssr_scope. Notation"T (* n *)" := (abstract T n abstract_key) : ssr_scope. OpenScope ssr_scope.
Register abstract_lock as plugins.ssreflect.abstract_lock.
Register abstract_key as plugins.ssreflect.abstract_key.
Register abstract as plugins.ssreflect.abstract.
(** Constants for tactic-views **) Inductive external_view : Type := tactic_view of Type.
Notation"[ 'the' sT 'of' v 'by' f ]" :=
(@get_by _ sT f _ _ ((fun v' (s : sT) => Put v' (f s) s) v _))
(only parsing) : form_scope.
Notation"[ 'the' sT 'of' v ]" := (get ((fun s : sT => Put v (*coerce*) s s) _))
(only parsing) : form_scope.
(** Thefollowingare"formatonly"versionsoftheabovenotations. Weneedtodothistopreventtheformatterfrombeingbethrownoffby applicationcollapsing,coercioninsertionandbetareductionintheright
hand side of the notations above. **)
Notation"[ 'the' sT 'of' v 'by' f ]" := (@get_by _ sT f v _ _)
(only printing) : form_scope.
Notation"[ 'the' sT 'of' v ]" := (@get _ sT v _ _)
(only printing) : form_scope.
Definition argumentType T P & forall x : T, P x := T. Definition dependentReturnType T P & forall x : T, P x := P. Definition returnType aT rT & aT -> rT := rT.
Notation"{ 'type' 'of' c 'for' s }" := (dependentReturnType c s) : type_scope.
(** Ageneric"phantom"type(actually,aunittypewithaphantomparameter). ThistypecanbeusedfortypedefinitionsthatrequiresomeStructure ononeoftheirparameters,toallowRocqtoinfersaidstructuresoit doesnothavetobesuppliedexplicitlyorviathe"#[#the_of_#]#"notation (thelatterinteractspoorlywithotherNotation). Thedefinitionofa(co)inductivetypewithaparameterp:p_type,that needstousetheoperationsofastructure Structurep_str:Type:=p_Str{p_repr:>p_type;p_op:p_repr->...} shouldbegivenas Inductiveindt_type(p:p_str):=Indt.... Definitionindt_of(p:p_str)&phantomp_typep:=indt_typep. Notation"{'indt'p}":=(indt_of(Phantomp)). Definitionindtpxy...z:{indtp}:=@Indtpxy...z. Notation"#[#'indt'xy...z#]#":=(indtxy...z). Thatis,theconcretetypeanditsconstructorshouldbeshadowedby definitionsthatuseaphantomargumenttoinferanddisplaythetrue valueofp(inpractice,the"indt"constructoroftenperformsadditional functions,like"locking"therepresentation--seebelow). Wealsodefineasimplerversion("phant"/"Phant")ofphantomforthe
common case where p_type is Type. **)
(** Internal tagging used by the implementation of the ssreflect elim. **)
Definition protect_term (A : Type) (x : A) : A := x.
Register protect_term as plugins.ssreflect.protect_term.
(** Thessreflectidiomforanon-keyedpattern: -unkeyedtwillmatchanysubtermthatunifieswitht,regardlessof whetheritdisplaysthesameheadsymbolast. -unkeyedtabwillmatchanyapplicationofatermfunifyingwitht, totwoargumentsunifyingwithaandb,respectively,regardlessof apparentheadsymbols. -unkeyedxwherexisavariablewillmatchanysubtermwiththesame
type as x (when x would raise the 'indeterminate pattern' error). **)
(** Quicker done tactic not including split, syntax: /0/ **) Ltac ssrdone0 := trivial; hnf; intros; solve
[ do ![solve [trivial | apply: sym_equal; trivial]
| discriminate | contradiction ]
| matchgoalwith H : ~ _ |- _ => solve [case H; trivial] end ].
(** To unlock opaque constants. **)
#[universes(template)]
Structure unlockable T v := Unlockable {unlocked : T; _ : unlocked = v}. Lemma unlock T x C : @unlocked T x C = x. Proof. bycase: C. Qed.
Notation"[ 'unlockable' 'of' C ]" :=
(@Unlockable _ _ C (unlock _)) : form_scope.
Notation"[ 'unlockable' 'fun' C ]" :=
(@Unlockable _ (fun _ => _) C (unlock _)) : form_scope.
(** Generic keyed constant locking. **)
(** The argument order ensures that k is always compared before T. **) Definition locked_with k := let: tt := k in fun T x => x : T.
(** Thiscanbeusedasacheapalternativetocloningtheunlockableinstance
below, but with caution as unkeyed matching can be expensive. **) Lemma locked_withE T k x : unkeyed (locked_with k x) = x :> T. Proof. bycase: k. Qed.
(** Intensionaly, this instance will not apply to locked u. **)
Canonical locked_with_unlockable T k x :=
@Unlockable T x (locked_with k x) (locked_withE k x).
(** More accurate variant of unlock, and safer alternative to locked_withE. **) Lemma unlock_with T k x : unlocked (locked_with_unlockable k x) = x :> T. Proof. exact: unlock. Qed.
(** Notation to trigger Rocq elaboration to fill the holes **) Notation"[ 'elaborate' x ]" := (ltac:(refine x)) (only parsing).
Register ssr_have_upoly as plugins.ssreflect.ssr_have_upoly.
(** Internal N-ary congruence lemmas for the congr tactic. **)
Fixpoint nary_congruence_statement (n : nat)
: (forall B, (B -> B -> Prop) -> Prop) -> Prop := match n with
| O => fun k => forall B, k B (fun x1 x2 : B => x1 = x2)
| S n' => let k' A B e (f1 f2 : A -> B) := forall x1 x2, x1 = x2 -> (e (f1 x1) (f2 x2) : Prop) in fun k => forall A, nary_congruence_statement n' (fun B e => k _ (k' A B e)) end.
Lemma nary_congruence n (k := fun B e => forall y : B, (e y y : Prop)) :
nary_congruence_statement n k. Proof.
have: k _ _ := _; rewrite {1}/k. elim: n k => [|n IHn] k k_P /= A; first exact: k_P. byapply: IHn => B e He; apply: k_P => f x1 x2 <-. Qed.
Hint View for move/ iffLRn|2 iffRLn|2 iffLR|2 iffRL|2. Hint View for apply/ iffRLn|2 iffLRn|2 iffRL|2 iffLR|2.
(** Tofocusnon-ssreflecttacticsonasubterm,egvm_compute. Usage: elim/abstract_context:(pattern)=>GdefG. vm_compute;rewrite{}defG{G}. Notethatvm_castarenotstoredintheproofterm forreductionsoccurringinthecontext,hence sethere:=pattern;vm_computein(valueofhere)
blows up at Qed time. **) Lemma abstract_context T (P : T -> Type) x :
(forall Q, Q = P -> Q x) -> P x. Proof. by move=> /(_ P); apply. Qed.
(*****************************************************************************) (* Material for under/over (to rewrite under binders using "context lemmas") *)
Structure test_of (result : bool) := Test {condition :> unit}. Definition test_Prop (P : Prop) := Test true (maybeProp P). Definition test_negative := Test false tt.
Structure type := Check {result : bool; test : test_of result; frame : call_of test result}. Definitioncheck result test frame := @Check result test frame.
Notation"'[' 'apply' ']'" := (ltac:(let f := fresh "_top_" in move=> f {}/f))
(at level 0, only parsing) : ssripat_scope.
(* we try to preserve the naming by matching the names from the goal *) (* we do move to perform a hnf before trying to match *) Notation"'[' 'swap' ']'" := (ltac:(move; let x := lazymatch goalwith
| |- forall (x : _), _ => fresh x | |- let x := _ in _ => fresh x | _ => fresh "_top_" end in intro x; move; let y := lazymatch goalwith
| |- forall (y : _), _ => fresh y | |- let y := _ in _ => fresh y | _ => fresh "_top_" end in intro y; revert x; revert y))
(at level 0, only parsing) : ssripat_scope.
(* we try to preserve the naming by matching the names from the goal *) (* we do move to perform a hnf before trying to match *) Notation"'[' 'dup' ']'" := (ltac:(move;
lazymatch goalwith
| |- forall (x : _), _ => let x := fresh x in intro x; let copy := fresh x in have copy := x; revert x; revert copy
| |- let x := _ in _ => let x := fresh x in intro x; let copy := fresh x in pose copy := x;
do [unfold x in (value of copy)]; revert x; revert copy
| |- _ => let x := fresh "_top_" in move=> x; let copy := fresh "_top" in have copy := x; revert x; revert copy end))
(at level 0, only parsing) : ssripat_scope.
Notation"'[' '1' '!' rules ']'" := (ltac:(rewrite rules))
(at level 0, rules at level 200, only parsing) : ssripat_scope. Notation"'[' '!' rules ']'" := (ltac:(rewrite !rules))
(at level 0, rules at level 200, only parsing) : ssripat_scope.
End ipat.
(* A class to trigger reduction by rewriting. *) (* Usage: rewrite [pattern]vm_compute. *) (* Alternatively one may redefine a lemma as in algebra/rat.v : *) (* Lemma rat_vm_compute n (x : rat) : vm_compute_eq n%:Q x -> n%:Q = x. *) (* Proof. exact. Qed. *)
Class vm_compute_eq {T : Type} (x y : T) := vm_compute : x = y.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.