├── .github └── workflows │ └── docker-action.yml ├── .gitignore ├── Makefile ├── README.md ├── _CoqProject ├── coq-inf-seq-ext.opam ├── dune-project ├── meta.yml └── theories ├── classical.v ├── dune ├── exteq.v ├── infseq.v ├── map.v └── subseq.v /.github/workflows/docker-action.yml: -------------------------------------------------------------------------------- 1 | # This file was generated from `meta.yml`, please do not edit manually. 2 | # Follow the instructions on https://github.com/coq-community/templates to regenerate. 3 | name: Docker CI 4 | 5 | on: 6 | push: 7 | branches: 8 | - master 9 | pull_request: 10 | branches: 11 | - '**' 12 | 13 | jobs: 14 | build: 15 | # the OS must be GNU/Linux to be able to use the docker-coq-action 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | image: 20 | - 'coqorg/coq:dev' 21 | - 'coqorg/coq:8.17' 22 | - 'coqorg/coq:8.16' 23 | - 'coqorg/coq:8.15' 24 | - 'coqorg/coq:8.14' 25 | - 'coqorg/coq:8.13' 26 | - 'coqorg/coq:8.12' 27 | - 'coqorg/coq:8.11' 28 | - 'coqorg/coq:8.10' 29 | - 'coqorg/coq:8.9' 30 | fail-fast: false 31 | steps: 32 | - uses: actions/checkout@v3 33 | - uses: coq-community/docker-coq-action@v1 34 | with: 35 | opam_file: 'coq-inf-seq-ext.opam' 36 | custom_image: ${{ matrix.image }} 37 | 38 | 39 | # See also: 40 | # https://github.com/coq-community/docker-coq-action#readme 41 | # https://github.com/erikmd/docker-coq-github-action-demo 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.vo 2 | *.glob 3 | *.v.d 4 | Makefile.coq 5 | Makefile.coq.bak 6 | Makefile.coq.conf 7 | .Makefile.coq.d 8 | *~ 9 | .coq-native/ 10 | *.aux 11 | *.vos 12 | *.vok 13 | *.vio 14 | .coqdeps.d 15 | _build 16 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | clean: Makefile.coq 5 | @+$(MAKE) -f Makefile.coq cleanall 6 | @rm -f Makefile.coq Makefile.coq.conf 7 | 8 | Makefile.coq: _CoqProject 9 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 10 | 11 | force _CoqProject Makefile: ; 12 | 13 | %: Makefile.coq force 14 | @+$(MAKE) -f Makefile.coq $@ 15 | 16 | .PHONY: all clean force 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # InfSeqExt 2 | 3 | [![Docker CI][docker-action-shield]][docker-action-link] 4 | 5 | [docker-action-shield]: https://github.com/DistributedComponents/InfSeqExt/workflows/Docker%20CI/badge.svg?branch=master 6 | [docker-action-link]: https://github.com/DistributedComponents/InfSeqExt/actions?query=workflow:"Docker%20CI" 7 | 8 | 9 | 10 | 11 | Coq library for reasoning inductively and coinductively on infinite sequences, 12 | using modal operators similar to those in linear temporal logic (LTL). 13 | 14 | ## Meta 15 | 16 | - Author(s): 17 | - Yuxin Deng (initial) 18 | - Jean-Francois Monin (initial) 19 | - Karl Palmskog 20 | - Ryan Doenges 21 | - Compatible Coq versions: 8.9 or later 22 | - Additional dependencies: none 23 | - Coq namespace: `InfSeqExt` 24 | - Related publication(s): none 25 | 26 | ## Building and installation instructions 27 | 28 | The easiest way to install InfSeqExt is via 29 | [OPAM](https://opam.ocaml.org/doc/Install.html): 30 | ```shell 31 | opam repo add coq-extra-dev https://coq.inria.fr/opam/extra-dev 32 | opam install coq-inf-seq-ext 33 | ``` 34 | 35 | To instead build and install manually, do: 36 | ```shell 37 | git clone https://github.com/DistributedComponents/InfSeqExt.git 38 | cd InfSeqExt 39 | make # or make -j 40 | make install 41 | ``` 42 | 43 | ## Documentation 44 | 45 | InfSeqExt is based on an [earlier library][infseq-paper] by Deng and Monin. 46 | It is intended as a more comprehensive alternative to [Streams][streams-link] 47 | in the Coq standard library. In particular, InfSeqExt provides machinery commonly 48 | used when reasoning about temporal properties of system execution traces, and 49 | follows the modal operator [name conventions][spin-ltl-link] used in the Spin model checker. 50 | 51 | ### Files 52 | 53 | - `infseq.v`: main definitions and results 54 | - coinductive definition of infinite sequences 55 | - definitions and notations for modal operators and connectors 56 | - basic modal operators: `now`, `next`, `consecutive`, `always1`, `always`, `weak_until`, `until`, `release`, `eventually` 57 | - composite modal operators: `inf_often`, `continuously` 58 | - modal connectors: `impl_tl` (`->_`), `and_tl` (`/\_`), `or_tl` (`\/_`), `not_tl` (`~_`) 59 | - lemmas about modal operators and connectors 60 | - tactics 61 | - `map.v`: corecursive definitions of the `map` and `zip` functions for use on infinite sequences, and related lemmas 62 | - `exteq.v`: coinductive definition of extensional equality (`exteq`) for infinite sequences, and related lemmas 63 | - `subseq.v`: coinductive definitions of infinite subsequences and related lemmas 64 | - `classical.v`: lemmas about modal operators and connectors when assuming classical logic (excluded middle) 65 | 66 | ### Related libraries 67 | 68 | InfSeqExt has some overlap with the less exhaustive [CTLTCTL][ctltctl-link] 69 | and [LTL][ltl-link] Coq contributions, which provide similar machinery. 70 | In contrast to CTLTCTL and LTL, InfSeqExt does not provide a definition 71 | of traces following some labeled reduction relation, nor an explicit 72 | notion of time. Fairness is also left up to library users to define. 73 | 74 | [infseq-paper]: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5198503 75 | [streams-link]: https://coq.inria.fr/library/Coq.Lists.Streams.html 76 | [spin-ltl-link]: http://spinroot.com/spin/Man/ltl.html 77 | [ctltctl-link]: https://github.com/coq-contribs/ctltctl 78 | [ltl-link]: https://github.com/coq-contribs/ltl 79 | -------------------------------------------------------------------------------- /_CoqProject: -------------------------------------------------------------------------------- 1 | -Q theories InfSeqExt 2 | 3 | theories/subseq.v 4 | theories/exteq.v 5 | theories/infseq.v 6 | theories/classical.v 7 | theories/map.v 8 | -------------------------------------------------------------------------------- /coq-inf-seq-ext.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | maintainer: "palmskog@gmail.com" 3 | version: "dev" 4 | 5 | homepage: "https://github.com/DistributedComponents/InfSeqExt" 6 | dev-repo: "git+https://github.com/DistributedComponents/InfSeqExt.git" 7 | bug-reports: "https://github.com/DistributedComponents/InfSeqExt/issues" 8 | license: "Unknown" 9 | 10 | synopsis: "Coq library for reasoning inductively and coinductively on infinite sequences" 11 | description: """ 12 | Coq library for reasoning inductively and coinductively on infinite sequences, 13 | using modal operators similar to those in linear temporal logic (LTL).""" 14 | 15 | build: ["dune" "build" "-p" name "-j" jobs] 16 | depends: [ 17 | "dune" {>= "2.5"} 18 | "coq" {>= "8.9"} 19 | ] 20 | 21 | tags: [ 22 | "category:Mathematics/Logic/Modal logic" 23 | "keyword:temporal logic" 24 | "keyword:infinite transition systems" 25 | "keyword:coinduction" 26 | "logpath:InfSeqExt" 27 | ] 28 | authors: [ 29 | "Yuxin Deng" 30 | "Jean-Francois Monin" 31 | "Karl Palmskog" 32 | "Ryan Doenges" 33 | ] 34 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.5) 2 | (using coq 0.2) 3 | (name InfSeqExt) 4 | -------------------------------------------------------------------------------- /meta.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fullname: InfSeqExt 3 | shortname: InfSeqExt 4 | opam_name: coq-inf-seq-ext 5 | organization: DistributedComponents 6 | community: false 7 | action: true 8 | dune: true 9 | coqdoc: false 10 | 11 | synopsis: Coq library for reasoning inductively and coinductively on infinite sequences 12 | 13 | description: |- 14 | Coq library for reasoning inductively and coinductively on infinite sequences, 15 | using modal operators similar to those in linear temporal logic (LTL). 16 | 17 | authors: 18 | - name: Yuxin Deng 19 | initial: true 20 | - name: Jean-Francois Monin 21 | initial: true 22 | - name: Karl Palmskog 23 | initial: false 24 | - name: Ryan Doenges 25 | initial: false 26 | 27 | maintainers: 28 | - name: Karl Palmskog 29 | nickname: palmskog 30 | 31 | opam-file-maintainer: palmskog@gmail.com 32 | 33 | opam-file-version: dev 34 | 35 | license: 36 | fullname: Unknown 37 | identifier: Unknown 38 | 39 | supported_coq_versions: 40 | text: 8.9 or later 41 | opam: '{>= "8.9"}' 42 | 43 | tested_coq_opam_versions: 44 | - version: dev 45 | - version: '8.17' 46 | - version: '8.16' 47 | - version: '8.15' 48 | - version: '8.14' 49 | - version: '8.13' 50 | - version: '8.12' 51 | - version: '8.11' 52 | - version: '8.10' 53 | - version: '8.9' 54 | 55 | namespace: InfSeqExt 56 | 57 | keywords: 58 | - name: temporal logic 59 | - name: infinite transition systems 60 | - name: coinduction 61 | 62 | categories: 63 | - name: Mathematics/Logic/Modal logic 64 | 65 | build: |- 66 | ## Building and installation instructions 67 | 68 | The easiest way to install InfSeqExt is via 69 | [OPAM](https://opam.ocaml.org/doc/Install.html): 70 | ```shell 71 | opam repo add coq-extra-dev https://coq.inria.fr/opam/extra-dev 72 | opam install coq-inf-seq-ext 73 | ``` 74 | 75 | To instead build and install manually, do: 76 | ```shell 77 | git clone https://github.com/DistributedComponents/InfSeqExt.git 78 | cd InfSeqExt 79 | make # or make -j 80 | make install 81 | ``` 82 | 83 | documentation: |- 84 | ## Documentation 85 | 86 | InfSeqExt is based on an [earlier library][infseq-paper] by Deng and Monin. 87 | It is intended as a more comprehensive alternative to [Streams][streams-link] 88 | in the Coq standard library. In particular, InfSeqExt provides machinery commonly 89 | used when reasoning about temporal properties of system execution traces, and 90 | follows the modal operator [name conventions][spin-ltl-link] used in the Spin model checker. 91 | 92 | ### Files 93 | 94 | - `infseq.v`: main definitions and results 95 | - coinductive definition of infinite sequences 96 | - definitions and notations for modal operators and connectors 97 | - basic modal operators: `now`, `next`, `consecutive`, `always1`, `always`, `weak_until`, `until`, `release`, `eventually` 98 | - composite modal operators: `inf_often`, `continuously` 99 | - modal connectors: `impl_tl` (`->_`), `and_tl` (`/\_`), `or_tl` (`\/_`), `not_tl` (`~_`) 100 | - lemmas about modal operators and connectors 101 | - tactics 102 | - `map.v`: corecursive definitions of the `map` and `zip` functions for use on infinite sequences, and related lemmas 103 | - `exteq.v`: coinductive definition of extensional equality (`exteq`) for infinite sequences, and related lemmas 104 | - `subseq.v`: coinductive definitions of infinite subsequences and related lemmas 105 | - `classical.v`: lemmas about modal operators and connectors when assuming classical logic (excluded middle) 106 | 107 | ### Related libraries 108 | 109 | InfSeqExt has some overlap with the less exhaustive [CTLTCTL][ctltctl-link] 110 | and [LTL][ltl-link] Coq contributions, which provide similar machinery. 111 | In contrast to CTLTCTL and LTL, InfSeqExt does not provide a definition 112 | of traces following some labeled reduction relation, nor an explicit 113 | notion of time. Fairness is also left up to library users to define. 114 | 115 | [infseq-paper]: http://ieeexplore.ieee.org/xpls/abs_all.jsp?arnumber=5198503 116 | [streams-link]: https://coq.inria.fr/library/Coq.Lists.Streams.html 117 | [spin-ltl-link]: http://spinroot.com/spin/Man/ltl.html 118 | [ctltctl-link]: https://github.com/coq-contribs/ctltctl 119 | [ltl-link]: https://github.com/coq-contribs/ltl 120 | --- 121 | -------------------------------------------------------------------------------- /theories/classical.v: -------------------------------------------------------------------------------- 1 | Require Import InfSeqExt.infseq. 2 | Require Import Classical. 3 | 4 | Section sec_classical. 5 | 6 | Variable T : Type. 7 | 8 | Lemma weak_until_until_or_always : 9 | forall (J P : infseq T -> Prop) (s : infseq T), 10 | weak_until J P s -> until J P s \/ always J s. 11 | Proof using. 12 | intros J P s. 13 | case (classic (eventually P s)). 14 | - intros evP wu. 15 | left. 16 | induction evP. 17 | * apply U0. assumption. 18 | * apply weak_until_Cons in wu. 19 | case wu. 20 | + intros PC. 21 | apply U0. assumption. 22 | + intros [Js wu']. 23 | apply U_next; trivial. 24 | apply IHevP. 25 | assumption. 26 | - intros evP wu. 27 | right. 28 | apply not_eventually_always_not in evP. 29 | apply weak_until_always_not_always in wu; trivial. 30 | Qed. 31 | 32 | Lemma not_until_weak_until : 33 | forall (J P : infseq T -> Prop) (s : infseq T), 34 | ~ until J P s -> weak_until (J /\_ ~_ P) (~_ J /\_ ~_ P) s. 35 | Proof using. 36 | intros J P. 37 | cofix c. 38 | intros s. 39 | case (classic (P s)). 40 | - intros Ps un. 41 | contradict un. 42 | apply U0. 43 | assumption. 44 | - intros Ps. 45 | case (classic (J s)); destruct s as [x s]. 46 | * intros Js un. 47 | apply W_tl. 48 | + unfold and_tl, not_tl. 49 | split; trivial. 50 | + simpl. 51 | apply c. 52 | intros unn. 53 | contradict un. 54 | apply U_next; trivial. 55 | * intros Js un. 56 | apply W0. 57 | split; trivial. 58 | Qed. 59 | 60 | Lemma not_weak_until_until : 61 | forall (J P : infseq T -> Prop) (s : infseq T), 62 | ~ weak_until J P s -> until (J /\_ ~_ P) (~_ J /\_ ~_ P) s. 63 | Proof using. 64 | intros J P s wun. 65 | case (classic (until (J /\_ ~_ P) (~_ J /\_ ~_ P) s)); trivial. 66 | intros un. 67 | contradict wun. 68 | revert s un. 69 | cofix c. 70 | intros s. 71 | case (classic (P s)). 72 | - intros Ps un. 73 | apply W0. 74 | assumption. 75 | - intros Ps. 76 | case (classic (J s)); destruct s as [x s]. 77 | * intros Js un. 78 | apply W_tl; trivial. 79 | simpl. 80 | apply c. 81 | intros unn. 82 | contradict un. 83 | apply U_next; trivial. 84 | split; trivial. 85 | * intros Js un. 86 | contradict un. 87 | apply U0. 88 | split; trivial. 89 | Qed. 90 | 91 | Lemma not_eventually_not_always : 92 | forall (P : infseq T -> Prop) (s : infseq T), 93 | ~ eventually (~_ P) s -> always P s. 94 | Proof using. 95 | intros P. 96 | cofix c. 97 | intro s. 98 | destruct s as [e s]. 99 | intros evnP. 100 | apply Always. 101 | - case (classic (P (Cons e s))); trivial. 102 | intros orP. 103 | apply (E0 _ (~_ P)) in orP. 104 | contradict evnP. 105 | assumption. 106 | - apply c. 107 | simpl. 108 | intros evP. 109 | contradict evnP. 110 | apply E_next. 111 | assumption. 112 | Qed. 113 | 114 | Lemma not_always_eventually_not : 115 | forall (P : infseq T -> Prop) (s : infseq T), 116 | ~ always P s -> eventually (~_ P) s. 117 | Proof using. 118 | intros P s alP. 119 | case (classic ((eventually (~_ P)) s)); trivial. 120 | intros evP. 121 | apply not_eventually_not_always in evP. 122 | contradict alP. 123 | assumption. 124 | Qed. 125 | 126 | Lemma not_until_release : 127 | forall (J P : infseq T -> Prop) (s : infseq T), 128 | ~ until (~_ J) (~_ P) s -> release J P s. 129 | Proof using. 130 | intros J P. 131 | cofix c. 132 | intros s. 133 | case (classic (J s)). 134 | - intros Js un. 135 | destruct s as [x s]. 136 | apply R0; trivial. 137 | case (classic (P (Cons x s))); trivial. 138 | intros Ps. 139 | contradict un. 140 | apply U0. 141 | apply Ps. 142 | - intros Js un. 143 | destruct s as [x s]. 144 | apply R_tl. 145 | * case (classic (P (Cons x s))); trivial. 146 | intros Ps. 147 | contradict un. 148 | apply U0. 149 | apply Ps. 150 | * simpl. 151 | apply c. 152 | intros unn. 153 | contradict un. 154 | apply U_next; trivial. 155 | Qed. 156 | 157 | Lemma not_release_until : 158 | forall (J P : infseq T -> Prop) (s : infseq T), 159 | ~ release (~_ J) (~_ P) s -> until J P s. 160 | Proof using. 161 | intros J P s rl. 162 | case (classic (until J P s)); trivial. 163 | intros un. 164 | contradict rl. 165 | revert s un. 166 | cofix c. 167 | intros s un. 168 | case (classic (P s)). 169 | - intros Ps. 170 | contradict un. 171 | apply U0. 172 | assumption. 173 | - intros Ps. 174 | case (classic (J s)). 175 | * intros Js. 176 | destruct s as [x s]. 177 | apply R_tl; trivial. 178 | simpl. 179 | apply c. 180 | intros unn. 181 | contradict un. 182 | apply U_next; trivial. 183 | * intros Js. 184 | destruct s as [x s]. 185 | apply R0; unfold not_tl; assumption. 186 | Qed. 187 | 188 | Lemma not_inf_often_continuously_not : 189 | forall (P : infseq T -> Prop) (s : infseq T), 190 | ~ inf_often P s -> continuously (~_ P) s. 191 | Proof using. 192 | intros P s ioP. 193 | apply not_always_eventually_not in ioP. 194 | induction ioP. 195 | - apply not_eventually_always_not in H. 196 | apply E0. 197 | assumption. 198 | - apply E_next. 199 | assumption. 200 | Qed. 201 | 202 | Lemma not_continously_inf_often_not : 203 | forall (P : infseq T -> Prop) (s : infseq T), 204 | ~ continuously P s -> inf_often (~_ P) s. 205 | Proof using. 206 | intros P. 207 | cofix c. 208 | intros [x s] cnyP. 209 | apply Always. 210 | - unfold continuously in cnyP. 211 | apply not_eventually_always_not in cnyP. 212 | apply always_now in cnyP. 213 | unfold not_tl in cnyP. 214 | apply not_always_eventually_not in cnyP. 215 | assumption. 216 | - apply c. 217 | intros cnynP. 218 | contradict cnyP. 219 | apply E_next. 220 | assumption. 221 | Qed. 222 | 223 | Lemma not_tl_and_tl_or_tl : 224 | forall (P Q : infseq T -> Prop) (s : infseq T), 225 | (~_ (P /\_ Q)) s -> ((~_ P) \/_ (~_ Q)) s. 226 | Proof using. 227 | intros P Q s; unfold not_tl, and_tl, or_tl. 228 | apply not_and_or. 229 | Qed. 230 | 231 | End sec_classical. 232 | 233 | Arguments weak_until_until_or_always [T J P s] _. 234 | Arguments not_until_weak_until [T J P s] _. 235 | Arguments not_weak_until_until [T J P s] _. 236 | Arguments not_eventually_not_always [T P s] _. 237 | Arguments not_always_eventually_not [T P s] _. 238 | Arguments not_until_release [T J P s] _. 239 | Arguments not_release_until [T J P s] _. 240 | Arguments not_inf_often_continuously_not [T P s] _. 241 | Arguments not_continously_inf_often_not [T P s] _. 242 | Arguments not_tl_and_tl_or_tl [T P Q s] _. 243 | -------------------------------------------------------------------------------- /theories/dune: -------------------------------------------------------------------------------- 1 | (coq.theory 2 | (name InfSeqExt) 3 | (package coq-inf-seq-ext) 4 | (synopsis "Coq library for reasoning inductively and coinductively on infinite sequences")) 5 | -------------------------------------------------------------------------------- /theories/exteq.v: -------------------------------------------------------------------------------- 1 | Require Import InfSeqExt.infseq. 2 | 3 | (* ------------------------------------------------------------------------- *) 4 | (* Extensional equality on infinite sequences *) 5 | Section sec_exteq. 6 | 7 | Variable T: Type. 8 | 9 | CoInductive exteq : infseq T -> infseq T -> Prop := 10 | exteq_intro : 11 | forall x s1 s2, exteq s1 s2 -> exteq (Cons x s1) (Cons x s2). 12 | 13 | Lemma exteq_inversion : 14 | forall (x1:T) s1 x2 s2, 15 | exteq (Cons x1 s1) (Cons x2 s2) -> x1 = x2 /\ exteq s1 s2. 16 | Proof using. 17 | intros x1 s1 x2 s2 e. 18 | change (hd (Cons x1 s1) = hd (Cons x2 s2) /\ 19 | exteq (tl (Cons x1 s1)) (tl (Cons x2 s2))). 20 | case e; clear e x1 s1 x2 s2. simpl. intros; split; trivial. 21 | Qed. 22 | 23 | Lemma exteq_refl : forall s, exteq s s. 24 | Proof using. 25 | cofix cf. intros (x, s). constructor. apply cf. 26 | Qed. 27 | 28 | Lemma exteq_sym : forall s1 s2, exteq s1 s2 -> exteq s2 s1. 29 | Proof using. 30 | cofix cf. destruct 1. constructor. apply cf. assumption. 31 | Qed. 32 | 33 | Lemma exteq_trans : 34 | forall s1 s2 s3, exteq s1 s2 -> exteq s2 s3 -> exteq s1 s3. 35 | Proof using. 36 | cofix cf. 37 | intros (x1, s1) (x2, s2) (x3, s3) e12 e23. 38 | case (exteq_inversion _ _ _ _ e12); clear e12; intros e12 ex12. 39 | case (exteq_inversion _ _ _ _ e23); clear e23; intros e23 ex23. 40 | rewrite e12; rewrite e23. constructor. apply cf with s2; assumption. 41 | Qed. 42 | 43 | End sec_exteq. 44 | 45 | Arguments exteq [T] _ _. 46 | Arguments exteq_inversion [T x1 s1 x2 s2] _. 47 | Arguments exteq_refl [T] _. 48 | Arguments exteq_sym [T] _ _ _. 49 | Arguments exteq_trans [T] _ _ _ _ _. 50 | 51 | (* --------------------------------------------------------------------------- *) 52 | (* Extensional equality and temporal logic *) 53 | 54 | Section sec_exteq_congruence. 55 | 56 | Variable T: Type. 57 | 58 | (* All useful predicates are extensional in the following sense *) 59 | Definition extensional (P: infseq T -> Prop) := 60 | forall s1 s2, exteq s1 s2 -> P s1 -> P s2. 61 | 62 | Lemma extensional_True_tl : 63 | extensional True_tl. 64 | Proof using. 65 | intros s1 s2 eq; auto. 66 | Qed. 67 | 68 | Lemma extensional_False_tl : 69 | extensional False_tl. 70 | Proof using. 71 | intros s1 s2 eq; auto. 72 | Qed. 73 | 74 | Lemma extensional_and_tl : 75 | forall (P Q: infseq T -> Prop), 76 | extensional P -> extensional Q -> extensional (P /\_ Q). 77 | Proof using. 78 | intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold and_tl. intuition. 79 | - apply eP with (Cons x s1); [constructor; assumption | assumption]. 80 | - apply eQ with (Cons x s1); [constructor; assumption | assumption]. 81 | Qed. 82 | 83 | Lemma extensional_or_tl : 84 | forall (P Q: infseq T -> Prop), 85 | extensional P -> extensional Q -> extensional (P \/_ Q). 86 | Proof using. 87 | intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold or_tl. intuition. 88 | - left; apply eP with (Cons x s1); [constructor; assumption | assumption]. 89 | - right; apply eQ with (Cons x s1); [constructor; assumption | assumption]. 90 | Qed. 91 | 92 | Lemma extensional_impl_tl : 93 | forall (P Q: infseq T -> Prop), 94 | extensional P -> extensional Q -> extensional (P ->_ Q). 95 | Proof using. 96 | intros P Q eP eQ s1 s2 e. destruct e; simpl. unfold impl_tl. 97 | intros PQ1 P2. 98 | apply eQ with (Cons x s1); [constructor; assumption | idtac]. 99 | apply PQ1. apply eP with (Cons x s2). 100 | - constructor. apply exteq_sym. assumption. 101 | - assumption. 102 | Qed. 103 | 104 | Lemma extensional_not_tl : 105 | forall (P: infseq T -> Prop), 106 | extensional P -> extensional (~_ P). 107 | Proof using. 108 | intros P eP s1 s2 e; destruct e; simpl. unfold not_tl. 109 | intros P1 nP2. 110 | contradict P1. 111 | apply eP with (Cons x s2); trivial. 112 | apply exteq_sym. 113 | apply exteq_intro. 114 | assumption. 115 | Qed. 116 | 117 | Lemma extensional_now : 118 | forall (P: T -> Prop), extensional (now P). 119 | Proof using. 120 | intros P s1 s2 e. destruct e; simpl. trivial. 121 | Qed. 122 | 123 | Lemma extensional_next : 124 | forall (P: infseq T -> Prop), 125 | extensional P -> extensional (next P). 126 | Proof using. 127 | intros P eP s1 s2 exP; destruct exP; simpl. 128 | apply eP; assumption. 129 | Qed. 130 | 131 | Lemma extensional_consecutive : 132 | forall (P: T -> T -> Prop), extensional (consecutive P). 133 | Proof using. 134 | intros P s1 s2 e. do 2 destruct e; simpl. trivial. 135 | Qed. 136 | 137 | Lemma extensional_always : 138 | forall (P: infseq T -> Prop), 139 | extensional P -> extensional (always P). 140 | Proof using. 141 | intros P eP. cofix cf. 142 | intros (x1, s1) (x2, s2) e al1. case (always_Cons al1); intros Px1s1 als1. constructor. 143 | - eapply eP; eassumption. 144 | - simpl. apply cf with s1; try assumption. case (exteq_inversion e); trivial. 145 | Qed. 146 | 147 | Lemma extensional_weak_until : 148 | forall (P Q: infseq T -> Prop), 149 | extensional P -> extensional Q -> extensional (weak_until P Q). 150 | Proof using. 151 | intros P Q eP eQ. cofix cf. 152 | intros (x1, s1) (x2, s2) e un1. case (weak_until_Cons un1). 153 | - intro Q1. constructor 1. eapply eQ; eassumption. 154 | - intros (Px1s1, uns1). constructor 2. 155 | * eapply eP; eassumption. 156 | * simpl. apply cf with s1; try assumption. case (exteq_inversion e); trivial. 157 | Qed. 158 | 159 | Lemma extensional_until : 160 | forall (P Q: infseq T -> Prop), 161 | extensional P -> extensional Q -> extensional (until P Q). 162 | Proof using. 163 | intros P Q eP eQ s1 s2 e un1; genclear e; genclear s2. 164 | induction un1. 165 | - intros s2 e; apply U0; apply eQ with s; assumption. 166 | - intros (x2, s2) e. 167 | apply U_next. 168 | * apply eP with (Cons x s); assumption. 169 | * apply IHun1. 170 | case (exteq_inversion e). trivial. 171 | Qed. 172 | 173 | Lemma extensional_release : 174 | forall (P Q: infseq T -> Prop), 175 | extensional P -> extensional Q -> extensional (release P Q). 176 | Proof using. 177 | intros P Q eP eQ. cofix cf. 178 | intros (x1, s1) (x2, s2) e rl1. case (release_Cons rl1). intros Qx orR. case orR; intro orRx. 179 | - apply R0. 180 | * eapply eQ; eassumption. 181 | * eapply eP; eassumption. 182 | - apply R_tl. 183 | * eapply eQ; eassumption. 184 | * simpl. apply cf with s1; trivial. case (exteq_inversion e); trivial. 185 | Qed. 186 | 187 | Lemma extensional_eventually : 188 | forall (P: infseq T -> Prop), 189 | extensional P -> extensional (eventually P). 190 | Proof using. 191 | intros P eP s1 s2 e ev1. genclear e; genclear s2. 192 | induction ev1 as [s1 ev1 | x1 s1 ev1 induc_hyp]. 193 | - intros s2 e. constructor 1. apply eP with s1; assumption. 194 | - intros (x2, s2) e. constructor 2. apply induc_hyp. 195 | case (exteq_inversion e). trivial. 196 | Qed. 197 | 198 | Lemma extensional_inf_often : 199 | forall (P: infseq T -> Prop), 200 | extensional P -> extensional (inf_often P). 201 | Proof using. 202 | intros P eP; apply extensional_always; apply extensional_eventually; assumption. 203 | Qed. 204 | 205 | Lemma extensional_continuously : 206 | forall (P: infseq T -> Prop), 207 | extensional P -> extensional (continuously P). 208 | Proof using. 209 | intros P eP; apply extensional_eventually; apply extensional_always; assumption. 210 | Qed. 211 | 212 | End sec_exteq_congruence. 213 | 214 | Arguments extensional [T] _. 215 | Arguments extensional_True_tl [T] _ _ _ _. 216 | Arguments extensional_False_tl [T] _ _ _ _. 217 | Arguments extensional_and_tl [T P Q] _ _ _ _ _ _. 218 | Arguments extensional_or_tl [T P Q] _ _ _ _ _ _. 219 | Arguments extensional_impl_tl [T P Q] _ _ _ _ _ _ _. 220 | Arguments extensional_not_tl [T P] _ _ _ _ _ _. 221 | Arguments extensional_now [T P] _ _ _ _. 222 | Arguments extensional_next [T P] _ _ _ _ _. 223 | Arguments extensional_consecutive [T P] _ _ _ _. 224 | Arguments extensional_always [T P] _ _ _ _ _. 225 | Arguments extensional_weak_until [T P Q] _ _ _ _ _ _. 226 | Arguments extensional_until [T P Q] _ _ _ _ _ _. 227 | Arguments extensional_release [T P Q] _ _ _ _ _ _. 228 | Arguments extensional_eventually [T P] _ _ _ _ _. 229 | Arguments extensional_inf_often [T P] _ _ _ _ _. 230 | Arguments extensional_continuously [T P] _ _ _ _ _. 231 | -------------------------------------------------------------------------------- /theories/infseq.v: -------------------------------------------------------------------------------- 1 | (* ------------------------------------------------------------------------- *) 2 | (* General tactics *) 3 | 4 | Ltac genclear H := generalize H; clear H. 5 | 6 | Ltac clearall := 7 | repeat 8 | match goal with [H : _ |- _ ] => clear H end 9 | || match goal with [H : _ |- _ ] => genclear H end. 10 | 11 | (* ------------------------------------------------------------------------- *) 12 | (* Infinite traces *) 13 | 14 | Section sec_infseq. 15 | 16 | Variable T: Type. 17 | 18 | CoInductive infseq : Type := Cons : T -> infseq -> infseq. 19 | 20 | Definition hd (s:infseq) : T := match s with Cons x _ => x end. 21 | 22 | Definition tl (s:infseq) : infseq := match s with Cons _ s => s end. 23 | 24 | Lemma recons : forall s, Cons (hd s) (tl s) = s. 25 | Proof using. 26 | intros s. 27 | (* Trick : simpl doesn't progress, you have to eat s first *) 28 | case s. simpl. reflexivity. 29 | Qed. 30 | 31 | End sec_infseq. 32 | 33 | Arguments Cons [T] _ _. 34 | Arguments hd [T] _. 35 | Arguments tl [T] _. 36 | Arguments recons [T] _. 37 | 38 | (* --------------------------------------------------------------------------- *) 39 | (* Temporal logic operations *) 40 | 41 | Section sec_modal_op_defn. 42 | 43 | Variable T : Type. 44 | 45 | Definition now (P: T->Prop) (s: infseq T) : Prop := 46 | match s with Cons x s => P x end. 47 | 48 | Definition next (P: infseq T -> Prop) (s: infseq T) : Prop := 49 | match s with Cons x s => P s end. 50 | 51 | Definition consecutive (R: T -> T -> Prop) (s: infseq T) : Prop := 52 | match s with Cons x1 (Cons x2 s) => R x1 x2 end. 53 | 54 | CoInductive always1 (P: T->Prop) : infseq T -> Prop := 55 | | Always1 : forall x s, P x -> always1 P s -> always1 P (Cons x s). 56 | 57 | CoInductive always (P: infseq T->Prop) : infseq T -> Prop := 58 | | Always : forall s, P s -> always P (tl s) -> always P s. 59 | 60 | CoInductive weak_until (J P: infseq T->Prop) : infseq T -> Prop := 61 | | W0 : forall s, P s -> weak_until J P s 62 | | W_tl : forall s, J s -> weak_until J P (tl s) -> weak_until J P s. 63 | 64 | Inductive until (J P: infseq T->Prop) : infseq T -> Prop := 65 | | U0 : forall s, P s -> until J P s 66 | | U_next : forall x s, J (Cons x s) -> until J P s -> until J P (Cons x s). 67 | 68 | CoInductive release (J P: infseq T->Prop) : infseq T -> Prop := 69 | | R0 : forall s, P s -> J s -> release J P s 70 | | R_tl : forall s, P s -> release J P (tl s) -> release J P s. 71 | 72 | Inductive eventually (P: infseq T->Prop) : infseq T -> Prop := 73 | | E0 : forall s, P s -> eventually P s 74 | | E_next : forall x s, eventually P s -> eventually P (Cons x s). 75 | 76 | Definition inf_often (P: infseq T->Prop) (s: infseq T) : Prop := 77 | always (eventually P) s. 78 | 79 | Definition continuously (P: infseq T->Prop) (s: infseq T) : Prop := 80 | eventually (always P) s. 81 | 82 | (* temporal logic connectors *) 83 | Definition impl_tl (P Q: infseq T -> Prop) : infseq T -> Prop := 84 | fun s => P s -> Q s. 85 | Definition and_tl (P Q: infseq T -> Prop) : infseq T -> Prop := 86 | fun s => P s /\ Q s. 87 | Definition or_tl (P Q: infseq T -> Prop) : infseq T -> Prop := 88 | fun s => P s \/ Q s. 89 | Definition not_tl (P : infseq T -> Prop) : infseq T -> Prop := 90 | fun s => ~ P s. 91 | 92 | (* constants *) 93 | Definition True_tl : infseq T -> Prop := fun _ => True. 94 | Definition False_tl : infseq T -> Prop := fun _ => False. 95 | 96 | End sec_modal_op_defn. 97 | 98 | #[global] Hint Unfold True_tl False_tl : core. 99 | 100 | Arguments now [T] _ _. 101 | Arguments next [T] _ _. 102 | Arguments consecutive [T] _ _. 103 | Arguments always [T] _ _. 104 | Arguments always1 [T] _ _. 105 | Arguments eventually [T] _ _. 106 | Arguments weak_until [T] _ _ _. 107 | Arguments until [T] _ _ _. 108 | Arguments release [T] _ _ _. 109 | Arguments inf_often [T] _ _. 110 | Arguments continuously [T] _ _. 111 | 112 | Arguments impl_tl [T] _ _ _. 113 | Arguments and_tl [T] _ _ _. 114 | Arguments or_tl [T] _ _ _. 115 | Arguments not_tl [T] _ _. 116 | 117 | Arguments True_tl {T} _. 118 | Arguments False_tl {T} _. 119 | 120 | Notation "A ->_ B" := (impl_tl A B) (right associativity, at level 90). 121 | Notation "A /\_ B" := (and_tl A B) (right associativity, at level 80). 122 | Notation "A \/_ B" := (or_tl A B) (right associativity, at level 85). 123 | Notation "~_ A" := (not_tl A) (right associativity, at level 75). 124 | 125 | Section sec_modal_op_lemmas. 126 | 127 | Variable T : Type. 128 | 129 | (* now facts *) 130 | Lemma now_hd : 131 | forall (P : T -> Prop) ex, 132 | now P ex -> 133 | P (hd ex). 134 | Proof using. 135 | now destruct ex. 136 | Qed. 137 | 138 | (* always facts *) 139 | 140 | Lemma always_inv : 141 | forall (inv: infseq T -> Prop), 142 | (forall x s, inv (Cons x s) -> inv s) -> forall s, inv s -> always inv s. 143 | Proof using. 144 | intros P invP. 145 | cofix c. 146 | intros [x s] Pxs; apply Always; trivial. 147 | apply c; apply invP in Pxs. 148 | assumption. 149 | Qed. 150 | 151 | Lemma always_Cons : 152 | forall (x: T) (s: infseq T) P, 153 | always P (Cons x s) -> P (Cons x s) /\ always P s. 154 | Proof using. 155 | intros x s P al. change (P (Cons x s) /\ always P (tl (Cons x s))). 156 | destruct al. split; assumption. 157 | Qed. 158 | 159 | Lemma always_now : 160 | forall (x: T) (s: infseq T) P, always P (Cons x s) -> P (Cons x s). 161 | Proof using. 162 | intros x s P al. case (always_Cons x s P al); trivial. 163 | Qed. 164 | 165 | Lemma always_now' : 166 | forall (P : infseq T -> Prop) ex, 167 | always P ex -> 168 | P ex. 169 | Proof using. 170 | destruct ex. 171 | apply always_now. 172 | Qed. 173 | 174 | Lemma always_invar : 175 | forall (x: T) (s: infseq T) P, always P (Cons x s) -> always P s. 176 | Proof using. 177 | intros x s P al. case (always_Cons x s P al); trivial. 178 | Qed. 179 | 180 | Lemma always_tl : 181 | forall (s: infseq T) P, always P s -> always P (tl s). 182 | Proof using. 183 | intros (x, s). simpl. apply always_invar. 184 | Qed. 185 | 186 | Lemma always_not_false : 187 | forall s : infseq T, always (~_ False_tl) s. 188 | Proof using. 189 | cofix c. 190 | intros [x s]. 191 | apply Always. 192 | - unfold not_tl, False_tl; auto. 193 | - apply c. 194 | Qed. 195 | 196 | Lemma always_true : 197 | forall s : infseq T, always True_tl s. 198 | Proof using. 199 | cofix c. 200 | intros [x s]. 201 | apply Always. 202 | - unfold True_tl; trivial. 203 | - apply c. 204 | Qed. 205 | 206 | Lemma always_and_tl : 207 | forall (P Q : infseq T -> Prop), 208 | forall s, always P s -> always Q s -> always (P /\_ Q) s. 209 | Proof using. 210 | intros P Q. 211 | cofix c. 212 | intros s alP alQ. 213 | destruct alP. 214 | destruct alQ. 215 | apply Always. 216 | - split; assumption. 217 | - apply c; assumption. 218 | Qed. 219 | 220 | Lemma always_always : 221 | forall (P : infseq T -> Prop) s, 222 | always P s -> 223 | always (always P) s. 224 | Proof using. 225 | intro P. 226 | cofix c. 227 | constructor. 228 | - auto. 229 | - do 2 destruct s. 230 | constructor; eauto using always_invar. 231 | Qed. 232 | 233 | Lemma always_always1 : 234 | forall P (s: infseq T), always (now P) s -> always1 P s. 235 | Proof using. 236 | intros P. 237 | cofix alwn. 238 | intros s a; case a; clear a s. intros (x, s); simpl. constructor. 239 | - assumption. 240 | - apply alwn; assumption. 241 | Qed. 242 | 243 | Lemma always1_always : 244 | forall P (s: infseq T), always1 P s -> always (now P) s. 245 | Proof using. 246 | intros P. 247 | cofix alwn. destruct 1. constructor; simpl. 248 | - assumption. 249 | - apply alwn; assumption. 250 | Qed. 251 | 252 | Lemma always_weak_until : 253 | forall (J P : infseq T -> Prop) (s : infseq T), always J s -> weak_until J P s. 254 | Proof using. 255 | intros J P. 256 | cofix c. 257 | intros [x s] alJ. 258 | apply W_tl. 259 | - apply always_now in alJ. 260 | assumption. 261 | - apply c. 262 | apply always_invar in alJ. 263 | assumption. 264 | Qed. 265 | 266 | Lemma always_release : 267 | forall (J P : infseq T -> Prop) (s : infseq T), always P s -> release J P s. 268 | Proof using. 269 | intros J P. 270 | cofix c. 271 | intros [x s] al. 272 | apply R_tl. 273 | - apply always_now in al. 274 | assumption. 275 | - simpl. 276 | apply c. 277 | apply always_invar in al. 278 | assumption. 279 | Qed. 280 | 281 | Lemma always_inf_often : 282 | forall (P: infseq T -> Prop) (s : infseq T), always P s -> inf_often P s. 283 | Proof using. 284 | intros P. cofix f. intros s a. destruct a. constructor. 285 | - constructor 1. assumption. 286 | - apply f. assumption. 287 | Qed. 288 | 289 | Lemma always_continuously : 290 | forall (P: infseq T -> Prop) (s : infseq T), always P s -> continuously P s. 291 | Proof using. 292 | intros P s alP. 293 | apply E0. 294 | assumption. 295 | Qed. 296 | 297 | (* weak_until and eventually facts *) 298 | 299 | Lemma weak_until_Cons : 300 | forall (x: T) (s: infseq T) J P, 301 | weak_until J P (Cons x s) -> P (Cons x s) \/ (J (Cons x s) /\ weak_until J P s). 302 | Proof using. 303 | intros x s J P un. 304 | change (P (Cons x s) \/ (J (Cons x s) /\ weak_until J P (tl (Cons x s)))). 305 | destruct un; intuition. 306 | Qed. 307 | 308 | Lemma weak_until_always : 309 | forall (J J' P : infseq T -> Prop) s, 310 | weak_until J P s -> 311 | always J' s -> 312 | weak_until (J' /\_ J) P s. 313 | Proof using. 314 | cofix cf. 315 | intros J J' P s Hweak Halways. 316 | destruct s. 317 | inversion Hweak. 318 | - now eauto using W0. 319 | - inversion Halways. 320 | eapply W_tl. 321 | + now unfold and_tl. 322 | + simpl. now eauto. 323 | Qed. 324 | 325 | Lemma until_weak_until : 326 | forall (J P : infseq T -> Prop) (s : infseq T), 327 | until J P s -> weak_until J P s. 328 | Proof using. 329 | intros J P s un. 330 | induction un. 331 | - apply W0. assumption. 332 | - apply W_tl; trivial. 333 | Qed. 334 | 335 | Lemma eventually_Cons : 336 | forall (x: T) (s: infseq T) P, 337 | eventually P (Cons x s) -> P (Cons x s) \/ eventually P s. 338 | Proof using. 339 | intros x s P al. change (P (Cons x s) \/ eventually P (tl (Cons x s))). case al; auto. 340 | Qed. 341 | 342 | Lemma eventually_trans : 343 | forall (P Q inv: infseq T -> Prop), 344 | (forall x s, inv (Cons x s) -> inv s) -> 345 | (forall s, inv s -> P s -> eventually Q s) -> 346 | forall s, inv s -> eventually P s -> eventually Q s. 347 | Proof using. 348 | intros P Q inv is_inv PeQ s invs ev. induction ev as [s Ps | x s ev IHev]. 349 | - apply PeQ; assumption. 350 | - constructor 2. apply IHev. apply is_inv with x; assumption. 351 | Qed. 352 | 353 | Lemma not_eventually : 354 | forall (P : infseq T -> Prop), 355 | forall x s, ~ eventually P (Cons x s) -> ~ eventually P s. 356 | Proof using. 357 | intros P x s evCP evP. 358 | contradict evCP. 359 | apply E_next. 360 | assumption. 361 | Qed. 362 | 363 | Lemma eventually_next : 364 | forall (s: infseq T) P, eventually (next P) s -> eventually P s. 365 | Proof using. 366 | intros e P ev. induction ev as [(x, s) Ps | x s ev induc_hyp]. 367 | - constructor 2; constructor 1; exact Ps. 368 | - constructor 2. apply induc_hyp. 369 | Qed. 370 | 371 | Lemma eventually_always_cumul : 372 | forall (s: infseq T) P Q, 373 | eventually P s -> always Q s -> eventually (P /\_ always Q) s. 374 | Proof using. 375 | induction 1 as [s Ps | x s evPs induc_hyp]; intro al. 376 | - constructor 1. split; assumption. 377 | - constructor 2. apply induc_hyp. eapply always_invar; eauto. 378 | Qed. 379 | 380 | Lemma eventually_weak_until_cumul : 381 | forall (s: infseq T) P J, 382 | eventually P s -> weak_until J P s -> eventually (P /\_ weak_until J P) s. 383 | Proof using. 384 | intros s P J ev. induction ev as [s Ps | x s evPs induc_hyp]. 385 | - intro un. constructor 1. split; assumption. 386 | - intro unxs. case (weak_until_Cons _ _ _ _ unxs). 387 | * intro Pxs. constructor 1; split; assumption. 388 | * intros (_, uns). constructor 2. apply induc_hyp. exact uns. 389 | Qed. 390 | 391 | Lemma weak_until_eventually : 392 | forall (P Q J: infseq T -> Prop), 393 | (forall s, J s -> P s -> Q s) -> 394 | forall s, J s -> weak_until J Q s -> eventually P s -> eventually Q s. 395 | Proof using. 396 | intros P Q J impl s Js J_weak_until_Q ev. 397 | genclear J_weak_until_Q; genclear Js. 398 | induction ev as [s Ps | x s ev induc_hyp]. 399 | - intros Js J_weak_until_Q. constructor 1. apply impl; assumption. 400 | - intros _ J_weak_until_Q. cut (s = tl (Cons x s)); [idtac | reflexivity]. 401 | case J_weak_until_Q; clear J_weak_until_Q x. 402 | * constructor 1; assumption. 403 | * intros (x, s1) _ J_weak_until_Q e; simpl in *. 404 | constructor 2. generalize e J_weak_until_Q; clear e x. (* trick: keep J_weak_until_Q!! *) 405 | case J_weak_until_Q; clear J_weak_until_Q s1. 406 | + clearall. constructor 1; assumption. 407 | + intros s2 Js2 _ e J_weak_until_Q2. rewrite e in induc_hyp; clear e. 408 | apply induc_hyp; assumption. 409 | Qed. 410 | 411 | Lemma eventually_or_tl_intror : 412 | forall (P Q : infseq T -> Prop) s, 413 | eventually Q s -> 414 | eventually (P \/_ Q) s. 415 | Proof using. 416 | induction 1; firstorder using E0, E_next. 417 | Qed. 418 | 419 | Lemma eventually_or_tl_introl : 420 | forall (P Q : infseq T -> Prop) s, 421 | eventually P s -> 422 | eventually (P \/_ Q) s. 423 | Proof using. 424 | induction 1; firstorder using E0, E_next. 425 | Qed. 426 | 427 | Lemma eventually_or_tl_or : 428 | forall (P Q : infseq T -> Prop) s, 429 | eventually (P \/_ Q) s -> 430 | eventually P s \/ eventually Q s. 431 | Proof using. 432 | induction 1; firstorder using E0, E_next. 433 | Qed. 434 | 435 | (* until facts *) 436 | 437 | Lemma until_Cons : 438 | forall (x: T) (s: infseq T) J P, 439 | until J P (Cons x s) -> P (Cons x s) \/ (J (Cons x s) /\ until J P s). 440 | Proof using. 441 | intros x s J P ul. 442 | change (P (Cons x s) \/ (J (Cons x s) /\ until J P (tl (Cons x s)))). case ul; auto. 443 | Qed. 444 | 445 | Lemma until_eventually : 446 | forall (J P : infseq T -> Prop), 447 | forall s, until J P s -> eventually P s. 448 | Proof using. 449 | intros P J s unP. 450 | induction unP. 451 | - apply E0; assumption. 452 | - apply E_next; assumption. 453 | Qed. 454 | 455 | (* release facts *) 456 | 457 | Lemma release_Cons : 458 | forall (x: T) (s: infseq T) J P, 459 | release J P (Cons x s) -> P (Cons x s) /\ (J (Cons x s) \/ release J P s). 460 | Proof using. 461 | intros x s J P rl. 462 | change (P (Cons x s) /\ (J (Cons x s) \/ release J P (tl (Cons x s)))). 463 | destruct rl; intuition. 464 | Qed. 465 | 466 | (* inf_often and continuously facts *) 467 | 468 | Lemma inf_often_invar : 469 | forall (x: T) (s: infseq T) P, inf_often P (Cons x s) -> inf_often P s. 470 | Proof using. 471 | intros x s P; apply always_invar. 472 | Qed. 473 | 474 | Lemma continuously_invar : 475 | forall (x: T) (s: infseq T) P, continuously P (Cons x s) -> continuously P s. 476 | Proof using. 477 | intros x s P cny. 478 | apply eventually_Cons in cny. 479 | case cny; trivial. 480 | intro alP. 481 | apply E0. 482 | apply always_invar in alP; assumption. 483 | Qed. 484 | 485 | Lemma continuously_and_tl : 486 | forall (P Q : infseq T -> Prop) (s : infseq T), 487 | continuously P s -> continuously Q s -> continuously (P /\_ Q) s. 488 | Proof using. 489 | intros P Q s cnyP. 490 | induction cnyP as [s alP|]. 491 | - intro cnyQ. 492 | induction cnyQ. 493 | apply E0. 494 | apply always_and_tl; trivial. 495 | apply E_next. 496 | apply IHcnyQ. 497 | apply always_invar in alP; assumption. 498 | - intro cnyQ. 499 | apply E_next. 500 | apply IHcnyP. 501 | apply continuously_invar in cnyQ; assumption. 502 | Qed. 503 | 504 | Lemma continuously_inf_often : 505 | forall (P : infseq T -> Prop) (s : infseq T), 506 | continuously P s -> inf_often P s. 507 | Proof using. 508 | intros P. 509 | cofix c. 510 | intros s cnyP. 511 | induction cnyP. 512 | - apply always_inf_often. assumption. 513 | - apply Always. 514 | * apply E_next. destruct s as [s x']. apply always_now in IHcnyP. assumption. 515 | * apply IHcnyP. 516 | Qed. 517 | 518 | (* monotony *) 519 | 520 | Lemma now_monotonic : 521 | forall (P Q: T -> Prop), 522 | (forall x, P x -> Q x) -> forall s, now P s -> now Q s. 523 | Proof using. 524 | intros P Q PQ (x, s) nP; simpl. apply PQ. assumption. 525 | Qed. 526 | 527 | Lemma next_monotonic : 528 | forall (P Q: infseq T -> Prop), 529 | (forall s, P s -> Q s) -> forall s, next P s -> next Q s. 530 | Proof using. 531 | intros P Q PQ [x s]; apply PQ. 532 | Qed. 533 | 534 | Lemma consecutive_monotonic : 535 | forall (P Q: T -> T -> Prop), 536 | (forall x y, P x y -> Q x y) -> forall s, consecutive P s -> consecutive Q s. 537 | Proof using. 538 | intros P Q PQ (x, (y, s)) nP; simpl. apply PQ. assumption. 539 | Qed. 540 | 541 | Lemma always_monotonic : 542 | forall (P Q: infseq T -> Prop), 543 | (forall s, P s -> Q s) -> forall s, always P s -> always Q s. 544 | Proof using. 545 | intros P Q PQ. cofix cf. intros(x, s) a. 546 | generalize (always_Cons x s P a); simpl; intros (a1, a2). constructor; simpl. 547 | - apply PQ. assumption. 548 | - apply cf. assumption. 549 | Qed. 550 | 551 | Lemma weak_until_monotonic : 552 | forall (P Q J K: infseq T -> Prop), 553 | (forall s, P s -> Q s) -> (forall s, J s -> K s) -> 554 | forall s, weak_until J P s -> weak_until K Q s. 555 | Proof using. 556 | intros P Q J K PQ JK. cofix cf. intros(x, s) un. 557 | generalize (weak_until_Cons x s J P un); simpl. intros [Pxs | (Jxs, uns)]. 558 | - constructor 1; simpl; auto. 559 | - constructor 2; simpl; auto. 560 | Qed. 561 | 562 | Lemma until_monotonic : 563 | forall (P Q J K: infseq T -> Prop), 564 | (forall s, P s -> Q s) -> (forall s, J s -> K s) -> 565 | forall s, until J P s -> until K Q s. 566 | Proof using. 567 | intros P Q J K PQ JK s unJP. 568 | induction unJP. 569 | - apply U0, PQ; assumption. 570 | - apply U_next. 571 | * apply JK; assumption. 572 | * assumption. 573 | Qed. 574 | 575 | Lemma release_monotonic : 576 | forall (P Q J K: infseq T -> Prop), 577 | (forall s, P s -> Q s) -> (forall s, J s -> K s) -> 578 | forall s, release J P s -> release K Q s. 579 | Proof using. 580 | intros P Q J K PQ JK. 581 | cofix cf. intros [x s] rl. 582 | generalize (release_Cons x s J P rl); simpl. 583 | intros [Pxs rlCJP]. 584 | case rlCJP; intros rlJP. 585 | - apply R0. 586 | * apply PQ; assumption. 587 | * apply JK; assumption. 588 | - apply R_tl. 589 | * apply PQ; assumption. 590 | * simpl. 591 | apply cf. assumption. 592 | Qed. 593 | 594 | Lemma eventually_monotonic : 595 | forall (P Q J: infseq T -> Prop), 596 | (forall x s, J (Cons x s) -> J s) -> 597 | (forall s, J s -> P s -> Q s) -> 598 | forall s, J s -> eventually P s -> eventually Q s. 599 | Proof using. 600 | intros P Q J is_inv JPQ s Js ev. 601 | apply (eventually_trans P Q J is_inv); try assumption. 602 | intros; constructor 1. apply JPQ; assumption. 603 | Qed. 604 | 605 | (* corollary which turns out to be too weak in practice *) 606 | Lemma eventually_monotonic_simple : 607 | forall (P Q: infseq T -> Prop), 608 | (forall s, P s -> Q s) -> 609 | forall s, eventually P s -> eventually Q s. 610 | Proof using. 611 | intros P Q PQ s. 612 | apply (eventually_monotonic P Q True_tl); auto. 613 | Qed. 614 | 615 | Lemma inf_often_monotonic : 616 | forall (P Q : infseq T -> Prop), 617 | (forall s, P s -> Q s) -> 618 | forall s, inf_often P s -> inf_often Q s. 619 | Proof using. 620 | intros P Q impl. 621 | apply always_monotonic. 622 | apply eventually_monotonic_simple. 623 | assumption. 624 | Qed. 625 | 626 | Lemma cumul_eventually_always : 627 | forall (P Q : infseq T -> Prop) s, 628 | always P s -> 629 | eventually Q s -> 630 | eventually (P /\_ Q) s. 631 | Proof using. 632 | intros until 1. 633 | intro H_eventually. 634 | induction H_eventually. 635 | - apply E0. 636 | destruct s. 637 | firstorder using always_Cons. 638 | - eauto using E_next, always_invar. 639 | Qed. 640 | 641 | Lemma cumul_inf_often_always : 642 | forall (P Q : infseq T -> Prop) s, 643 | always P s -> 644 | inf_often Q s -> 645 | inf_often (P /\_ Q) s. 646 | Proof using. 647 | intros. 648 | eapply always_monotonic 649 | with (P := always P /\_ eventually Q) (Q := eventually (P /\_ Q)). 650 | - intros. 651 | unfold and_tl in * |-. 652 | firstorder using cumul_eventually_always. 653 | - eapply always_and_tl; eauto using always_always. 654 | Qed. 655 | 656 | (** This theorem is an analog of eventually_monotonic. *) 657 | Lemma inf_often_monotonic_invar : 658 | forall (invariant P Q : infseq T -> Prop), 659 | (forall s, 660 | invariant s -> 661 | P s -> 662 | Q s) -> 663 | forall ex, 664 | always invariant ex -> 665 | inf_often P ex -> 666 | inf_often Q ex. 667 | Proof using. 668 | intros. 669 | eapply inf_often_monotonic with (P:=invariant /\_ P). 670 | - intros. 671 | unfold and_tl in *; firstorder. 672 | - eapply cumul_inf_often_always; eauto. 673 | Qed. 674 | 675 | Lemma continuously_monotonic : 676 | forall (P Q : infseq T -> Prop), 677 | (forall s, P s -> Q s) -> 678 | forall s, continuously P s -> continuously Q s. 679 | Proof using. 680 | intros P Q impl. 681 | apply eventually_monotonic_simple. 682 | apply always_monotonic. 683 | assumption. 684 | Qed. 685 | 686 | (* not_tl inside operators *) 687 | 688 | Lemma not_eventually_always_not : 689 | forall (P : infseq T -> Prop) (s : infseq T), 690 | ~ eventually P s -> always (~_ P) s. 691 | Proof using. 692 | intros P. 693 | cofix c. 694 | intros s evP. 695 | destruct s as [e s]. 696 | apply Always. 697 | * unfold not_tl. 698 | intro Pn. 699 | case evP. 700 | apply E0. 701 | assumption. 702 | * apply c. 703 | intro evPn. 704 | contradict evP. 705 | apply E_next. 706 | assumption. 707 | Qed. 708 | 709 | Lemma always_not_eventually : 710 | forall (P : infseq T -> Prop) (s : infseq T), 711 | always (~_ P) s -> ~ eventually P s. 712 | Proof using. 713 | intros P. 714 | intros s alP evP. 715 | induction evP. 716 | * destruct s as [e s]. 717 | apply always_Cons in alP. 718 | destruct alP as [nP alP]. 719 | unfold not_tl in nP. 720 | contradict nP; assumption. 721 | * apply always_invar in alP. 722 | contradict IHevP; assumption. 723 | Qed. 724 | 725 | Lemma eventually_not_always : 726 | forall (P : infseq T -> Prop) (s : infseq T), 727 | eventually (~_ P) s -> ~ always P s. 728 | Proof using. 729 | intros P s eP alP. 730 | induction eP. 731 | - destruct s as [x s]. 732 | unfold not_tl in H. 733 | contradict H. 734 | apply always_Cons in alP. 735 | destruct alP as [PC alP]. 736 | assumption. 737 | - apply always_invar in alP. 738 | contradict IHeP. 739 | assumption. 740 | Qed. 741 | 742 | Lemma weak_until_always_not_always : 743 | forall (J P : infseq T -> Prop) (s : infseq T), 744 | weak_until J P s -> always (~_ P) s -> always J s. 745 | Proof using. 746 | intros J P. 747 | cofix c. 748 | intros s unJP alP. 749 | destruct s as [e s]. 750 | apply weak_until_Cons in unJP. 751 | case unJP. 752 | - intro PC. 753 | apply always_Cons in alP. 754 | destruct alP as [nP alP]. 755 | unfold not_tl in nP. 756 | contradict nP. 757 | assumption. 758 | - intros Jun. 759 | destruct Jun as [JC unJPs]. 760 | apply Always; trivial. 761 | apply c; trivial. 762 | apply always_invar in alP. 763 | assumption. 764 | Qed. 765 | 766 | Lemma weak_until_latch_eventually : 767 | forall (P Q : infseq T -> Prop) ex, 768 | weak_until (P /\_ ~_ Q) (P /\_ Q) ex -> 769 | eventually Q ex -> 770 | eventually (P /\_ Q) ex. 771 | Proof using. 772 | intros P Q ex H_w. 773 | induction 1; 774 | inversion H_w; firstorder using E0, E_next. 775 | Qed. 776 | 777 | Lemma always_not_eventually_not : 778 | forall (P : infseq T -> Prop) (s : infseq T), 779 | always P s -> ~ eventually (~_ P) s. 780 | Proof using. 781 | intros P s alP evP. 782 | induction evP. 783 | - unfold not_tl in H. 784 | contradict H. 785 | destruct s as [x s]. 786 | apply always_now in alP. 787 | assumption. 788 | - contradict IHevP. 789 | apply always_invar in alP. 790 | assumption. 791 | Qed. 792 | 793 | Lemma continuously_not_inf_often : 794 | forall (P : infseq T -> Prop) (s : infseq T), 795 | continuously (~_ P) s -> ~ inf_often P s. 796 | Proof using. 797 | intros P s cnyP. 798 | induction cnyP. 799 | - destruct s as [e s]. 800 | intros ifP. 801 | apply always_now in ifP. 802 | induction ifP. 803 | * destruct s0 as [e0 s0]. 804 | apply always_now in H. 805 | unfold not_tl in H. 806 | contradict H. 807 | trivial. 808 | * apply always_invar in H. 809 | contradict IHifP. 810 | trivial. 811 | - intro ioP. 812 | apply always_invar in ioP. 813 | contradict IHcnyP. 814 | trivial. 815 | Qed. 816 | 817 | Lemma inf_often_not_continuously : 818 | forall (P : infseq T -> Prop) (s : infseq T), 819 | inf_often (~_ P) s -> ~ continuously P s. 820 | Proof using. 821 | intros P s ioP cnyP. 822 | induction cnyP. 823 | - destruct s as [x s]. 824 | apply always_now in ioP. 825 | induction ioP. 826 | * destruct s0 as [x' s0]. 827 | apply always_now in H. 828 | unfold not_tl in H0. 829 | contradict H0. 830 | assumption. 831 | * apply always_invar in H. 832 | contradict IHioP. 833 | assumption. 834 | - apply inf_often_invar in ioP. 835 | contradict IHcnyP. 836 | assumption. 837 | Qed. 838 | 839 | Lemma release_not_until : 840 | forall (J P : infseq T -> Prop) (s : infseq T), 841 | release J P s -> ~ until (~_ J) (~_ P) s. 842 | Proof using. 843 | intros J P s rl un. 844 | induction un as [s Ps |x s Js IHun IH]. 845 | - destruct s as [x s]. 846 | unfold not_tl in Ps. 847 | apply release_Cons in rl. 848 | destruct rl as [Psr rl]. 849 | contradict Ps. 850 | assumption. 851 | - apply release_Cons in rl. 852 | destruct rl as [Ps rl]. 853 | unfold not_tl in Js. 854 | case rl; trivial. 855 | Qed. 856 | 857 | Lemma until_not_release : 858 | forall (J P : infseq T -> Prop) (s : infseq T), 859 | until J P s -> ~ release (~_ J) (~_ P) s. 860 | Proof using. 861 | intros J P s un rl. 862 | induction un. 863 | - destruct s as [x s]. 864 | apply release_Cons in rl. 865 | destruct rl as [Ps rl]. 866 | unfold not_tl in Ps. 867 | contradict Ps. 868 | assumption. 869 | - apply release_Cons in rl. 870 | destruct rl as [Ps rl]. 871 | case rl; trivial. 872 | unfold not_tl. 873 | intros Js. 874 | contradict Js. 875 | assumption. 876 | Qed. 877 | 878 | Lemma weak_until_not_until : 879 | forall (J P : infseq T -> Prop) (s : infseq T), 880 | weak_until (J /\_ ~_ P) (~_ J /\_ ~_ P) s -> ~ until J P s. 881 | Proof using. 882 | intros J P s wu un. 883 | induction un. 884 | - destruct s as [x s]. 885 | apply weak_until_Cons in wu. 886 | case wu; unfold not_tl, and_tl. 887 | * intros [Js Ps]. 888 | contradict Ps. 889 | assumption. 890 | * intros [[Js Ps] wun]. 891 | contradict Ps. 892 | assumption. 893 | - apply weak_until_Cons in wu. 894 | case wu. 895 | * unfold not_tl, and_tl. 896 | intros [Js Ps]. 897 | contradict Js. 898 | assumption. 899 | * intros [[Js Ps] wun]. 900 | contradict IHun. 901 | assumption. 902 | Qed. 903 | 904 | Lemma until_not_weak_until : 905 | forall (J P : infseq T -> Prop) (s : infseq T), 906 | until (J /\_ ~_ P) (~_ J /\_ ~_ P) s -> ~ weak_until J P s. 907 | Proof using. 908 | intros J P s un wun. 909 | induction un as [s JPs | x s JPs IHun IH]; unfold not_tl, and_tl in JPs; destruct JPs as [Js Ps]. 910 | - destruct s as [x s]. 911 | apply weak_until_Cons in wun. 912 | case wun; trivial. 913 | intros [JCs wu]. 914 | contradict Js. 915 | assumption. 916 | - apply weak_until_Cons in wun. 917 | case wun. 918 | * intros PCs. 919 | contradict Ps. 920 | assumption. 921 | * intros [JCs wu]. 922 | contradict IH. 923 | assumption. 924 | Qed. 925 | 926 | (* connector facts *) 927 | 928 | Lemma and_tl_comm : 929 | forall (P Q : infseq T -> Prop) (s : infseq T), 930 | (P /\_ Q) s <-> (Q /\_ P) s. 931 | Proof using. 932 | intros; split; unfold and_tl; apply and_comm. 933 | Qed. 934 | 935 | Lemma and_tl_assoc : 936 | forall (P Q R : infseq T -> Prop) (s : infseq T), 937 | ((P /\_ Q) /\_ R) s <-> (P /\_ Q /\_ R) s. 938 | Proof using. 939 | intros; split; unfold and_tl; apply and_assoc. 940 | Qed. 941 | 942 | Lemma or_tl_comm : 943 | forall (P Q : infseq T -> Prop) (s : infseq T), 944 | (P \/_ Q) s <-> (Q \/_ P) s. 945 | Proof using. 946 | intros; split; unfold or_tl; apply or_comm. 947 | Qed. 948 | 949 | Lemma or_tl_assoc : 950 | forall (P Q R : infseq T -> Prop) (s : infseq T), 951 | ((P \/_ Q) \/_ R) s <-> (P \/_ Q \/_ R) s. 952 | Proof using. 953 | intros; split; unfold or_tl; apply or_assoc. 954 | Qed. 955 | 956 | Lemma not_tl_or_tl : 957 | forall (P Q : infseq T -> Prop) (s : infseq T), 958 | (~_ (P \/_ Q)) s <-> ((~_ P) /\_ (~_ Q)) s. 959 | Proof using. 960 | intros P Q s; unfold not_tl, and_tl, or_tl; split; [ intros PQs | intros [Ps Qs] PQs]. 961 | - split; intro Ps; contradict PQs; [left|right]; assumption. 962 | - case PQs; assumption. 963 | Qed. 964 | 965 | Lemma not_tl_or_tl_and_tl : 966 | forall (P Q : infseq T -> Prop) (s : infseq T), 967 | ((~_ P) \/_ (~_ Q)) s -> (~_ (P /\_ Q)) s. 968 | Proof using. 969 | intros P Q s; unfold not_tl, and_tl, or_tl; intros PQs [Ps Qs]; case PQs; intros nPQs; contradict nPQs; assumption. 970 | Qed. 971 | 972 | End sec_modal_op_lemmas. 973 | 974 | Arguments always_inv [T inv] _ [s] _. 975 | Arguments always_Cons [T x s P] _. 976 | Arguments always_now [T x s P] _. 977 | Arguments always_invar [T x s P] _. 978 | Arguments always_tl [T s P] _. 979 | Arguments always_not_false {T s}. 980 | Arguments always_true {T s}. 981 | Arguments always_and_tl [T P Q s] _ _. 982 | Arguments always_always1 [T P s] _. 983 | Arguments always1_always [T P s] _. 984 | Arguments always_weak_until [T J P s] _. 985 | Arguments always_release [T J P s] _. 986 | Arguments always_inf_often [T P s] _. 987 | Arguments always_continuously [T P s] _. 988 | 989 | Arguments weak_until_Cons [T x s J P] _. 990 | Arguments weak_until_always [T J J' P s] _ _. 991 | Arguments until_weak_until [T J P s] _. 992 | Arguments eventually_Cons [T x s P] _. 993 | Arguments eventually_trans [T P Q inv] _ _ [s] _ _. 994 | Arguments not_eventually [T P x s] _ _. 995 | Arguments eventually_next [T s P] _. 996 | Arguments eventually_always_cumul [T s P Q] _ _. 997 | Arguments eventually_weak_until_cumul [T s P J] _ _. 998 | Arguments weak_until_eventually [T P Q J] _ [s] _ _ _. 999 | Arguments until_Cons [T x s J P] _. 1000 | Arguments until_eventually [T J P s] _. 1001 | Arguments release_Cons [T x s J P] _. 1002 | Arguments inf_often_invar [T x s P] _. 1003 | Arguments continuously_invar [T x s P] _. 1004 | Arguments continuously_and_tl [T P Q s] _ _. 1005 | Arguments continuously_inf_often [T P s] _. 1006 | 1007 | Arguments now_monotonic [T P Q] _ [s] _. 1008 | Arguments next_monotonic [T P Q] _ [s] _. 1009 | Arguments consecutive_monotonic [T P Q] _ [s] _. 1010 | Arguments always_monotonic [T P Q] _ [s] _. 1011 | Arguments weak_until_monotonic [T P Q J K] _ _ [s] _. 1012 | Arguments until_monotonic [T P Q J K] _ _ [s] _. 1013 | Arguments release_monotonic [T P Q J K] _ _ [s] _. 1014 | Arguments eventually_monotonic [T P Q] _ _ _ [s] _ _. 1015 | Arguments eventually_monotonic_simple [T P Q] _ [s] _. 1016 | Arguments inf_often_monotonic [T P Q] _ [s] _. 1017 | Arguments continuously_monotonic [T P Q] _ [s] _. 1018 | 1019 | Arguments not_eventually_always_not [T P s] _. 1020 | Arguments always_not_eventually [T P s] _ _. 1021 | Arguments eventually_not_always [T P s] _ _. 1022 | Arguments weak_until_always_not_always [T J P s] _ _. 1023 | Arguments always_not_eventually_not [T P s] _ _. 1024 | Arguments continuously_not_inf_often [T P s] _ _. 1025 | Arguments inf_often_not_continuously [T P s] _ _. 1026 | Arguments release_not_until [T J P s] _ _. 1027 | Arguments until_not_release [T J P s] _ _. 1028 | Arguments weak_until_not_until [T J P s] _ _. 1029 | Arguments until_not_weak_until [T J P s] _ _. 1030 | 1031 | Arguments and_tl_comm {T P Q s}. 1032 | Arguments and_tl_assoc {T P Q R s}. 1033 | Arguments or_tl_comm {T P Q s}. 1034 | Arguments or_tl_assoc {T P Q R s}. 1035 | Arguments not_tl_or_tl {T P Q s}. 1036 | Arguments not_tl_or_tl_and_tl [T P Q s] _ _. 1037 | 1038 | Ltac monotony := 1039 | match goal with 1040 | | [ |- now ?P ?s -> now ?Q ?s ] => 1041 | apply now_monotonic 1042 | | [ |- next ?P ?s -> next ?Q ?s ] => 1043 | apply next_monotonic 1044 | | [ |- consecutive ?P ?s -> consecutive ?Q ?s ] => 1045 | apply consecutive_monotonic 1046 | | [ |- always ?P ?s -> always ?Q ?s ] => 1047 | apply always_monotonic 1048 | | [ |- weak_until ?J ?P ?s -> weak_until ?K ?Q ?s ] => 1049 | apply weak_until_monotonic 1050 | | [ |- until ?J ?P ?s -> until ?K ?Q ?s ] => 1051 | apply until_monotonic 1052 | | [ |- release ?J ?P ?s -> release ?K ?Q ?s ] => 1053 | apply release_monotonic 1054 | | [ |- ?J ?s -> eventually ?P ?s -> eventually ?Q ?s ] => 1055 | apply eventually_monotonic 1056 | | [ |- continuously ?P ?s -> continuously ?Q ?s ] => 1057 | apply continuously_monotonic 1058 | | [ |- inf_often ?P ?s -> inf_often ?Q ?s ] => 1059 | apply inf_often_monotonic 1060 | end. 1061 | -------------------------------------------------------------------------------- /theories/map.v: -------------------------------------------------------------------------------- 1 | Require Import InfSeqExt.infseq. 2 | Require Import InfSeqExt.exteq. 3 | 4 | (* map *) 5 | Section sec_map. 6 | 7 | Variable A B: Type. 8 | 9 | CoFixpoint map (f: A->B) (s: infseq A): infseq B := 10 | match s with 11 | | Cons x s => Cons (f x) (map f s) 12 | end. 13 | 14 | Lemma map_Cons: forall (f:A->B) x s, map f (Cons x s) = Cons (f x) (map f s). 15 | Proof using. 16 | intros. pattern (map f (Cons x s)). rewrite <- recons. simpl. reflexivity. 17 | Qed. 18 | 19 | End sec_map. 20 | 21 | Arguments map [A B] _ _. 22 | Arguments map_Cons [A B] _ _ _. 23 | 24 | (* --------------------------------------------------------------------------- *) 25 | (* Zipping two infseqs: useful for map theory *) 26 | Section sec_zip. 27 | 28 | Variable A B: Type. 29 | 30 | CoFixpoint zip (sA: infseq A) (sB: infseq B) : infseq (A*B) := 31 | match sA, sB with 32 | | Cons a sA0, Cons b sB0 => Cons (a, b) (zip sA0 sB0) 33 | end. 34 | 35 | Lemma zip_Cons: forall (a:A) (b:B) sA sB, zip (Cons a sA) (Cons b sB) = Cons (a, b) (zip sA sB). 36 | Proof using. 37 | intros. pattern (zip (Cons a sA) (Cons b sB)); rewrite <- recons. simpl. reflexivity. 38 | Qed. 39 | 40 | End sec_zip. 41 | 42 | Arguments zip [A B] _ _. 43 | Arguments zip_Cons [A B] _ _ _ _. 44 | 45 | (* --------------------------------------------------------------------------- *) 46 | (* map and_tl temporal logic *) 47 | 48 | Section sec_map_modalop. 49 | 50 | Variable A B: Type. 51 | 52 | Lemma and_tl_map : 53 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 54 | (forall s, P s -> Q (map f s)) -> 55 | (forall s, P' s -> Q' (map f s)) -> 56 | forall (s: infseq A), 57 | (P /\_ P') s -> (Q /\_ Q') (map f s). 58 | Proof using. 59 | unfold and_tl; intuition. 60 | Qed. 61 | 62 | Lemma and_tl_map_conv : 63 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 64 | (forall s, Q (map f s) -> P s) -> 65 | (forall s, Q' (map f s) -> P' s) -> 66 | forall (s: infseq A), 67 | (Q /\_ Q') (map f s) -> (P /\_ P') s. 68 | Proof using. 69 | unfold and_tl; intuition. 70 | Qed. 71 | 72 | Lemma or_tl_map : 73 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 74 | (forall s, P s -> Q (map f s)) -> 75 | (forall s, P' s -> Q' (map f s)) -> 76 | forall (s: infseq A), 77 | (P \/_ P') s -> (Q \/_ Q') (map f s). 78 | Proof using. 79 | unfold or_tl; intuition. 80 | Qed. 81 | 82 | Lemma or_tl_map_conv : 83 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 84 | (forall s, Q (map f s) -> P s) -> 85 | (forall s, Q' (map f s) -> P' s) -> 86 | forall (s: infseq A), 87 | (Q \/_ Q') (map f s) -> (P \/_ P') s. 88 | Proof using. 89 | unfold or_tl; intuition. 90 | Qed. 91 | 92 | Lemma impl_tl_map : 93 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 94 | (forall s, Q (map f s) -> P s) -> 95 | (forall s, P' s -> Q' (map f s)) -> 96 | forall (s: infseq A), 97 | (P ->_ P') s -> (Q ->_ Q') (map f s). 98 | Proof using. 99 | unfold impl_tl; intuition. 100 | Qed. 101 | 102 | Lemma impl_tl_map_conv : 103 | forall (f: A->B) (P P': infseq A->Prop) (Q Q': infseq B->Prop), 104 | (forall s, P s -> Q (map f s)) -> 105 | (forall s, Q' (map f s) -> P' s) -> 106 | forall (s: infseq A), 107 | (Q ->_ Q') (map f s) -> (P ->_ P') s. 108 | Proof using. 109 | unfold impl_tl; intuition. 110 | Qed. 111 | 112 | Lemma not_tl_map : 113 | forall (f: A->B) (P : infseq A->Prop) (Q: infseq B->Prop), 114 | (forall s, Q (map f s) -> P s) -> 115 | forall (s: infseq A), (~_ P) s -> (~_ Q) (map f s). 116 | Proof using. 117 | unfold not_tl; intuition. 118 | Qed. 119 | 120 | Lemma not_tl_map_conv : 121 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 122 | (forall s, P s -> Q (map f s)) -> 123 | forall (s: infseq A), (~_ Q) (map f s) -> (~_ P) s. 124 | Proof using. 125 | unfold not_tl; intuition. 126 | Qed. 127 | 128 | Lemma now_map : 129 | forall (f: A->B) (P: B->Prop) (s: infseq A), 130 | now (fun x => P (f x)) s -> now P (map f s). 131 | Proof using. 132 | intros f P (x, s) nP; assumption. 133 | Qed. 134 | 135 | Lemma now_map_conv : 136 | forall (f: A->B) (P: B->Prop) (s: infseq A), 137 | now P (map f s) -> now (fun x => P (f x)) s. 138 | Proof using. 139 | intros f P (x, s) nP; assumption. 140 | Qed. 141 | 142 | Lemma next_map : 143 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 144 | (forall s, P s -> Q (map f s)) -> 145 | forall (s: infseq A), next P s -> next Q (map f s). 146 | Proof using. 147 | intros f P Q PQ [x s]; apply PQ. 148 | Qed. 149 | 150 | Lemma next_map_conv : 151 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 152 | (forall s, Q (map f s) -> P s) -> 153 | forall (s: infseq A), next Q (map f s) -> next P s. 154 | Proof using. 155 | intros f P Q QP [x s]; apply QP. 156 | Qed. 157 | 158 | Lemma consecutive_map : 159 | forall (f: A->B) (P: B->B->Prop) (s: infseq A), 160 | consecutive (fun x y => P (f x) (f y)) s -> consecutive P (map f s). 161 | Proof using. 162 | intros f P (x, (y, s)) nP; assumption. 163 | Qed. 164 | 165 | Lemma consecutive_map_conv : 166 | forall (f: A->B) (P: B->B->Prop) (s: infseq A), 167 | consecutive P (map f s) -> consecutive (fun x y => P (f x) (f y)) s. 168 | Proof using. 169 | intros f P (x, (y, s)) nP; assumption. 170 | Qed. 171 | 172 | Lemma always_map : 173 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 174 | (forall s, P s -> Q (map f s)) -> 175 | forall (s: infseq A), always P s -> always Q (map f s). 176 | Proof using. 177 | intros f P Q PQ. cofix cf. 178 | intros (x, s) a. case (always_Cons a); intros a1 a2. constructor. 179 | - apply PQ. assumption. 180 | - rewrite map_Cons; simpl. apply cf; assumption. 181 | Qed. 182 | 183 | Lemma always_map_conv_ext : 184 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop) (J : infseq A -> Prop), 185 | (forall x s, J (Cons x s) -> J s) -> 186 | (forall s, J s -> Q (map f s) -> P s) -> 187 | forall s, J s -> always Q (map f s) -> always P s. 188 | Proof using. 189 | intros f J P Q inv JQP. cofix c. 190 | intros [x s] Js a. 191 | rewrite map_Cons in a. case (always_Cons a); intros a1 a2. constructor. 192 | - apply JQP. assumption. 193 | rewrite map_Cons; assumption. 194 | - simpl. apply c. 195 | * apply (inv x). assumption. 196 | * assumption. 197 | Qed. 198 | 199 | Lemma always_map_conv : 200 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 201 | (forall s, Q (map f s) -> P s) -> 202 | forall (s: infseq A), always Q (map f s) -> always P s. 203 | Proof using. 204 | intros f P Q QP s. 205 | apply (always_map_conv_ext f P Q True_tl); auto. 206 | Qed. 207 | 208 | Lemma weak_until_map : 209 | forall (f: A->B) (J P: infseq A->Prop) (K Q: infseq B->Prop), 210 | (forall s, J s -> K (map f s)) -> 211 | (forall s, P s -> Q (map f s)) -> 212 | forall (s: infseq A), 213 | weak_until J P s -> weak_until K Q (map f s). 214 | Proof using. 215 | intros f J P K Q JK PQ. cofix cf. 216 | intros (x, s) un. case (weak_until_Cons un); clear un. 217 | - intro Pxs; constructor 1. apply PQ. assumption. 218 | - intros (Jxs, un). rewrite map_Cons. constructor 2. 219 | * rewrite <- map_Cons. auto. 220 | * simpl. auto. 221 | Qed. 222 | 223 | Lemma weak_until_map_conv : 224 | forall (f: A->B) (J P: infseq A->Prop) (K Q: infseq B->Prop), 225 | (forall s, K (map f s) -> J s) -> 226 | (forall s, Q (map f s) -> P s) -> 227 | forall (s: infseq A), 228 | weak_until K Q (map f s) -> weak_until J P s. 229 | Proof using. 230 | intros f J P K Q KJ QP. cofix cf. 231 | intros (x, s) un. 232 | rewrite map_Cons in un; case (weak_until_Cons un); clear un; rewrite <- map_Cons. 233 | - intro Qxs; constructor 1. apply QP. assumption. 234 | - intros (Kxs, un). constructor 2; simpl; auto. 235 | Qed. 236 | 237 | Lemma until_map : 238 | forall (f: A->B) (J P: infseq A->Prop) (K Q: infseq B->Prop), 239 | (forall s, J s -> K (map f s)) -> 240 | (forall s, P s -> Q (map f s)) -> 241 | forall (s: infseq A), 242 | until J P s -> until K Q (map f s). 243 | Proof using. 244 | intros f J P K Q JK PQ s un. 245 | induction un. 246 | - apply U0, PQ. assumption. 247 | - rewrite map_Cons. 248 | apply U_next. 249 | * rewrite <- map_Cons. 250 | apply JK. 251 | assumption. 252 | * assumption. 253 | Qed. 254 | 255 | Lemma release_map : 256 | forall (f: A->B) (J P: infseq A->Prop) (K Q: infseq B->Prop), 257 | (forall s, J s -> K (map f s)) -> 258 | (forall s, P s -> Q (map f s)) -> 259 | forall (s: infseq A), 260 | release J P s -> release K Q (map f s). 261 | Proof using. 262 | intros f J P K Q JK PQ. cofix cf. 263 | intros (x, s) rl. case (release_Cons rl); clear rl. 264 | intros Pxs orR. 265 | case orR; intro cR. 266 | - apply R0. 267 | * apply PQ. assumption. 268 | * apply JK. assumption. 269 | - apply R_tl. 270 | * apply PQ. assumption. 271 | * apply cf. assumption. 272 | Qed. 273 | 274 | Lemma release_map_conv : 275 | forall (f: A->B) (J P: infseq A->Prop) (K Q: infseq B->Prop), 276 | (forall s, K (map f s) -> J s) -> 277 | (forall s, Q (map f s) -> P s) -> 278 | forall (s: infseq A), 279 | release K Q (map f s) -> release J P s. 280 | Proof using. 281 | intros f J P K Q KJ QP. cofix cf. 282 | intros (x, s) rl. 283 | rewrite map_Cons in rl; case (release_Cons rl); clear rl; rewrite <- map_Cons; intros QC orR; case orR; intro cR. 284 | - apply R0. 285 | * apply QP. assumption. 286 | * apply KJ. assumption. 287 | - apply R_tl. 288 | * apply QP. assumption. 289 | * apply cf. assumption. 290 | Qed. 291 | 292 | Lemma eventually_map : 293 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 294 | (forall s, P s -> Q (map f s)) -> 295 | forall s, eventually P s -> eventually Q (map f s). 296 | Proof using. 297 | intros f P Q PQ s e. induction e as [s ok | x s e induc_hyp]. 298 | - destruct s as (x, s); simpl in *. rewrite map_Cons. constructor 1. 299 | rewrite <- map_Cons. apply PQ. exact ok. 300 | - rewrite map_Cons. constructor 2. exact induc_hyp. 301 | Qed. 302 | 303 | (* The converse seems to require much more work *) 304 | 305 | Definition fstAB := fst (A:=A) (B:=B). 306 | 307 | Lemma exteq_fst_zip: 308 | forall sA sB, exteq (map fstAB (zip sA sB)) sA. 309 | Proof using. 310 | cofix cf. intros (a, sA) (b, sB). 311 | rewrite zip_Cons. rewrite map_Cons. constructor. apply cf. 312 | Qed. 313 | 314 | Lemma exteq_zip_map : 315 | forall (f: A->B) (sA: infseq A) (sB: infseq B), 316 | always (now (fun c: A*B => let (x, y) := c in y = f x)) (zip sA sB) -> 317 | exteq sB (map f (map fstAB (zip sA (map f sA)))). 318 | Proof using. 319 | intros f. cofix cf. 320 | intros (a, sA) (b, sB). 321 | repeat rewrite map_Cons; repeat rewrite zip_Cons; repeat rewrite map_Cons; simpl. 322 | intro al; case (always_Cons al); clear al; simpl. intros e al. case e. constructor. 323 | apply cf. exact al. 324 | Qed. 325 | 326 | Lemma eventually_map_conv_aux : 327 | forall (f: A->B) (Q: infseq B->Prop), extensional Q -> 328 | forall (s: infseq A) (sB: infseq B), 329 | always (now (fun c: A*B => let (x, y) := c in y = f x)) (zip s sB) -> 330 | eventually Q sB -> 331 | eventually (fun sc => Q (map f (map fstAB sc))) (zip s (map f s)). 332 | Proof using. 333 | intros f Q extQ s sB al ev. genclear al; genclear s. 334 | induction ev as [(b, sB) QbsB | b sB ev induc_hyp]. 335 | - intros (a, sA) al. 336 | constructor 1. apply extQ with (Cons b sB); try assumption. 337 | apply exteq_zip_map. apply al. 338 | - intros (a, sA). repeat rewrite map_Cons. repeat rewrite zip_Cons. 339 | intro al. case (always_Cons al); simpl. clear al; intros e al. 340 | constructor 2. apply induc_hyp. exact al. 341 | Qed. 342 | 343 | Lemma eventually_map_conv_ext : 344 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop) (J : infseq A -> Prop), 345 | extensional P -> extensional Q -> extensional J -> 346 | (forall x s, J (Cons x s) -> J s) -> 347 | (forall s, J s -> Q (map f s) -> eventually P s) -> 348 | forall s, J s -> eventually Q (map f s) -> eventually P s. 349 | Proof using. 350 | intros f P Q J extP extQ extJ inv QP s Js ev. 351 | revert Js. 352 | assert (efst: J (map fstAB (zip s (map f s))) -> eventually P (map fstAB (zip s (map f s)))). 353 | - assert (evzip : eventually (fun sc => Q (map f (map fstAB sc))) (zip s (map f s))). 354 | * clear extP QP P. 355 | assert (alzip : (always (now (fun c : A * B => let (x, y) := c in y = f x)) (zip s (map f s)))). 356 | + clear ev extQ. generalize s. cofix cf. intros (x, s0). constructor. 357 | -- simpl. reflexivity. 358 | -- simpl. apply cf. 359 | + apply (eventually_map_conv_aux f Q extQ s (map f s) alzip ev). 360 | * clear ev. induction evzip as [((a, b), sAB) QabsAB | c sAB _ induc_hyp]. 361 | + intros Js. 362 | apply QP; assumption. 363 | + intros Js. 364 | rewrite map_Cons. 365 | apply E_next. 366 | apply induc_hyp. 367 | rewrite map_Cons in Js. 368 | apply (inv (fstAB c)). 369 | assumption. 370 | - intros Js. 371 | assert (emJ: J (map fstAB (zip s (map f s)))). 372 | * unfold extensional in extJ. 373 | apply (extJ s). 374 | + apply exteq_sym. apply exteq_fst_zip. 375 | + assumption. 376 | * apply efst in emJ. 377 | genclear emJ. 378 | apply extensional_eventually. 379 | + exact extP. 380 | + apply exteq_fst_zip. 381 | Qed. 382 | 383 | Lemma eventually_map_conv : 384 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 385 | extensional P -> extensional Q -> 386 | (forall s, Q (map f s) -> P s) -> 387 | forall s, eventually Q (map f s) -> eventually P s. 388 | Proof using. 389 | intros f P Q extP extQ QP s. 390 | apply eventually_map_conv_ext with (J := True_tl); auto. 391 | - apply extensional_True_tl. 392 | - intros. apply E0. apply QP. assumption. 393 | Qed. 394 | 395 | Lemma eventually_map_monotonic : 396 | forall (f: A->B) (P Q J: infseq A->Prop) (K : infseq B -> Prop), 397 | (forall x s, J (Cons x s) -> J s) -> 398 | (forall x s, K (map f (Cons x s)) -> K (map f s)) -> 399 | (forall s, J s -> K (map f s) -> Q s -> P s) -> 400 | forall s, J s -> K (map f s) -> eventually Q s -> eventually P s. 401 | Proof using. 402 | intros f P Q J K Jinv Kinv JKQP s invJ invK ev. 403 | induction ev as [s Qs | x s ev IHev]. 404 | - apply E0. 405 | apply JKQP; assumption. 406 | - apply E_next. 407 | apply IHev. 408 | * apply (Jinv x); assumption. 409 | * apply (Kinv x); assumption. 410 | Qed. 411 | 412 | Lemma inf_often_map : 413 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 414 | (forall s, P s -> Q (map f s)) -> 415 | forall (s: infseq A), inf_often P s -> inf_often Q (map f s). 416 | Proof using. 417 | intros f P Q PQ. 418 | apply always_map; apply eventually_map; assumption. 419 | Qed. 420 | 421 | Lemma inf_often_map_conv : 422 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 423 | extensional P -> extensional Q -> 424 | (forall s, Q (map f s) -> P s) -> 425 | forall (s: infseq A), inf_often Q (map f s) -> inf_often P s. 426 | Proof using. 427 | intros f P Q eP eQ QP. 428 | apply always_map_conv; apply eventually_map_conv; trivial. 429 | Qed. 430 | 431 | Lemma continuously_map : 432 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 433 | (forall s, P s -> Q (map f s)) -> 434 | forall (s: infseq A), continuously P s -> continuously Q (map f s). 435 | Proof using. 436 | intros f P Q PQ. 437 | apply eventually_map; apply always_map; assumption. 438 | Qed. 439 | 440 | Lemma continuously_map_conv : 441 | forall (f: A->B) (P: infseq A->Prop) (Q: infseq B->Prop), 442 | extensional P -> extensional Q -> 443 | (forall s, Q (map f s) -> P s) -> 444 | forall (s: infseq A), continuously Q (map f s) -> continuously P s. 445 | Proof using. 446 | intros f P Q eP eQ QP. 447 | apply eventually_map_conv. 448 | - apply extensional_always; assumption. 449 | - apply extensional_always; assumption. 450 | - apply always_map_conv; assumption. 451 | Qed. 452 | 453 | (* Some corollaries *) 454 | 455 | Lemma eventually_now_map : 456 | forall (f: A->B) (P: B->Prop) (s: infseq A), 457 | eventually (now (fun x => P (f x))) s -> eventually (now P) (map f s). 458 | Proof using. 459 | intros f P. apply eventually_map. apply now_map. 460 | Qed. 461 | 462 | Lemma eventually_now_map_conv : 463 | forall (f: A->B) (P: B->Prop) (s: infseq A), 464 | eventually (now P) (map f s) -> eventually (now (fun x => P (f x))) s. 465 | Proof using. 466 | intros f P s. apply eventually_map_conv. 467 | - apply extensional_now. 468 | - apply extensional_now. 469 | - clear s. intros (x, s). repeat rewrite map_Cons. simpl. trivial. 470 | Qed. 471 | 472 | Lemma eventually_map_now_eq : 473 | forall (f: A -> B) a s, eventually (now (eq a)) s -> 474 | eventually (now (eq (f a))) (map f s). 475 | Proof using. 476 | intros f a. apply eventually_map. 477 | intros s noa. apply now_map. 478 | genclear noa. monotony. apply f_equal. 479 | Qed. 480 | 481 | End sec_map_modalop. 482 | 483 | Arguments and_tl_map [A B f P P' Q Q'] _ _ [s] _. 484 | Arguments and_tl_map_conv [A B f P P' Q Q'] _ _ [s] _. 485 | Arguments or_tl_map [A B f P P' Q Q'] _ _ [s] _. 486 | Arguments or_tl_map_conv [A B f P P' Q Q'] _ _ [s] _. 487 | Arguments impl_tl_map [A B f P P' Q Q'] _ _ [s] _ _. 488 | Arguments impl_tl_map_conv [A B f P P' Q Q'] _ _ [s] _ _. 489 | Arguments not_tl_map [A B f P Q] _ [s] _ _. 490 | Arguments not_tl_map_conv [A B f P Q] _ [s] _ _. 491 | Arguments now_map [A B f P s] _. 492 | Arguments now_map_conv [A B f P s] _. 493 | Arguments next_map [A B f P Q] _ [s] _. 494 | Arguments next_map_conv [A B f P Q] _ [s] _. 495 | Arguments consecutive_map [A B f P s] _. 496 | Arguments consecutive_map_conv [A B f P s] _. 497 | Arguments always_map [A B f P Q] _ [s] _. 498 | Arguments always_map_conv_ext [A B f P Q J] _ _ [s] _ _. 499 | Arguments always_map_conv [A B f P Q] _ [s] _. 500 | Arguments weak_until_map [A B f J P K Q] _ _ [s] _. 501 | Arguments weak_until_map_conv [A B f J P K Q] _ _ [s] _. 502 | Arguments until_map [A B f J P K Q] _ _ [s] _. 503 | Arguments release_map [A B f J P K Q] _ _ [s] _. 504 | Arguments release_map_conv [A B f J P K Q] _ _ [s] _. 505 | Arguments eventually_map [A B f P Q] _ [s] _. 506 | Arguments eventually_map_conv_ext [A B f P Q J] _ _ _ _ _ [s] _ _. 507 | Arguments eventually_map_conv [A B f P Q] _ _ _ [s] _. 508 | Arguments eventually_map_monotonic [A B f P Q] _ _ _ _ _ [s] _ _ _. 509 | Arguments inf_often_map [A B f P Q] _ [s] _. 510 | Arguments inf_often_map_conv [A B f P Q] _ _ _ [s] _. 511 | Arguments continuously_map [A B f P Q] _ [s] _. 512 | Arguments continuously_map_conv [A B f P Q] _ _ _ [s] _. 513 | Arguments eventually_now_map [A B f P s] _. 514 | Arguments eventually_now_map_conv [A B f P s] _. 515 | Arguments eventually_map_now_eq [A B f a s] _. 516 | -------------------------------------------------------------------------------- /theories/subseq.v: -------------------------------------------------------------------------------- 1 | Require Import InfSeqExt.infseq. 2 | Require Import InfSeqExt.exteq. 3 | 4 | (* --------------------------------------------------------------------------- *) 5 | (* Infinite subsequences *) 6 | 7 | Section sec_subseq. 8 | 9 | Variable T: Type. 10 | 11 | (* suff s s' means s is a suffix of s' *) 12 | Inductive suff (s : infseq T) : infseq T -> Prop := 13 | | sp_eq : suff s s 14 | | sp_next : forall x s0, suff s s0 -> suff s (Cons x s0). 15 | 16 | (* simple but not the most useful -- useless indeed *) 17 | CoInductive subseq : infseq T -> infseq T -> Prop := 18 | | Subseq : forall s s0 s1, 19 | suff s1 s0 -> subseq s (tl s1) -> subseq (Cons (hd s1) s) s0. 20 | 21 | CoInductive subseqs' : infseq (infseq T) -> infseq T -> Prop := 22 | | Subseqs' : forall si s0 s1, 23 | suff s1 s0 -> subseqs' si (tl s1) -> subseqs' (Cons s1 si) s0. 24 | 25 | CoInductive subseqs : infseq (infseq T) -> infseq T -> Prop := 26 | | Subseqs : forall si s, 27 | suff (hd si) s -> subseqs (tl si) (tl (hd si)) -> subseqs si s. 28 | 29 | Lemma subseqs_subseqs' : forall si s, subseqs si s -> subseqs' si s. 30 | Proof using. 31 | cofix subsub. 32 | intros si s su. case su; clear su si s. 33 | intros (s1, si) s0. simpl. intros su sb. constructor. 34 | - assumption. 35 | - apply subsub. assumption. 36 | Qed. 37 | 38 | Lemma subseqs'_subseqs : forall si s, subseqs' si s -> subseqs si s. 39 | cofix subsub. 40 | intros si s su. case su; clear su si s. 41 | intros si s0 s1 su sb. constructor; simpl. 42 | - assumption. 43 | - apply subsub. assumption. 44 | Qed. 45 | 46 | (* Relating inf subseq to infinitely often *) 47 | 48 | (* In the next lemma, always1 is bit overkill, but is just what is needed below *) 49 | Lemma subseqs_eventually : 50 | forall P si s, subseqs si s -> always1 P si -> eventually P s. 51 | Proof using. 52 | intros P si s su. destruct su as [si s sf _]. 53 | induction sf as [ | x s0 _ Hrec]; intro a. 54 | - constructor 1. case a; simpl. intros; assumption. 55 | - constructor 2. apply Hrec. apply a. 56 | Qed. 57 | 58 | Lemma subseqs_tl : forall si s, subseqs si (tl s) -> subseqs si s. 59 | Proof using. 60 | intros si (x, s) su. simpl in su. 61 | case su. clear su si s; intros si s sf su. 62 | constructor. 63 | - constructor 2. exact sf. 64 | - exact su. 65 | Qed. 66 | 67 | Theorem subseq_inf_often : 68 | forall P si s, subseqs si s -> always1 P si -> inf_often P s. 69 | Proof using. 70 | intros P. red. cofix sio. 71 | intros si s su a. 72 | constructor. 73 | - apply subseqs_eventually with si; assumption. 74 | - genclear a. case su. 75 | clear su si s; intros (s0, si) s sf su a; simpl in * |- * . 76 | apply (sio si); clear sio. 77 | * induction sf; simpl. 78 | trivial. 79 | apply subseqs_tl. assumption (* induction hyp *). 80 | * change (always1 P (tl (Cons s0 si))). case a; simpl; trivial. 81 | Qed. 82 | 83 | (* Conversely : TODO *) 84 | 85 | Inductive ex_suff (P: infseq T -> Prop) (s' : infseq T) : Prop := 86 | Esp : forall s, suff s s' -> P s -> ex_suff P s'. 87 | 88 | Theorem eventually_suff : 89 | forall P s', eventually P s' -> ex_suff P s'. 90 | Proof using. 91 | intros P s ev. induction ev. 92 | - exists s; [ constructor | assumption]. 93 | - destruct IHev. exists s0. 94 | * constructor; assumption. 95 | * assumption. 96 | Qed. 97 | 98 | (* Extensional version *) 99 | 100 | Inductive suff_exteq (s : infseq T) : infseq T -> Prop := 101 | | sb_eq : forall s', exteq s s' -> suff_exteq s s' 102 | | sb_next : forall x s', suff_exteq s s' -> suff_exteq s (Cons x s'). 103 | 104 | Inductive suffb (x : T) (s : infseq T) : infseq T -> Prop := 105 | | sp_eqb : forall s', exteq (Cons x s) s' -> suffb x s s' 106 | | sp_nextb : forall y s', suffb x s s' -> suffb x s (Cons y s'). 107 | 108 | CoInductive subseqb : infseq T -> infseq T -> Prop := 109 | | Subseqb : forall x s s', suffb x s s' -> subseqb s s' -> subseqb (Cons x s) s'. 110 | 111 | Inductive mem (x : T) : infseq T -> Prop := 112 | | mem0 : forall s, mem x (Cons x s) 113 | | mem_next : forall y s, mem x s -> mem x (Cons y s). 114 | 115 | Lemma subseqb_included : forall x s, mem x s -> forall s', subseqb s s' -> mem x s'. 116 | Proof using. 117 | induction 1 as [| y s M IHmem]. 118 | - inversion_clear 1 as [a b c ssp _]. induction ssp as [s' ssp | ]. 119 | inversion_clear ssp. constructor. 120 | constructor. assumption. 121 | - inversion_clear 1. apply IHmem; assumption. 122 | Qed. 123 | 124 | End sec_subseq. 125 | --------------------------------------------------------------------------------