├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── doc └── chen-rosu-2019-trb-public_march182020.pdf ├── examples ├── 01_simple │ └── .gitkeep ├── 02_proofmode │ ├── Makefile │ ├── _CoqProject │ └── theories │ │ └── tutorial.v └── 03_FOL │ ├── Makefile │ ├── _CoqProject │ └── src │ └── LN_FOL.v ├── flake.lock ├── flake.nix ├── kore ├── .Makefile.d ├── Makefile ├── README.md ├── _CoqProject └── src │ ├── Basics.v │ ├── Freshness.v │ ├── Semantics.v │ ├── Signature.v │ ├── Substitution.v │ └── Syntax.v ├── koreimport-test ├── k │ └── test.k └── korefiles │ └── imp.kore ├── koreimport ├── pyproject.toml └── src │ └── koreimport │ └── __main__.py ├── matching-logic-doc ├── Makefile ├── movies │ ├── LICENSE │ ├── Makefile │ ├── Readme.md │ ├── config.mk │ ├── driver.py │ ├── extract_snippets.py │ ├── extract_snippets │ │ ├── Extractor.py │ │ ├── Reader.py │ │ ├── Snippet.py │ │ ├── __init__.py │ │ ├── cli.py │ │ ├── docutils.py │ │ └── snippetExceptions.py │ ├── gen_targets.py │ └── requirements.txt └── run_alectryon.sh ├── matching-logic ├── Makefile ├── README.md ├── _CoqProject ├── default.nix ├── dune-project ├── evaluator.hs ├── shell.nix └── src │ ├── ApplicationContext.v │ ├── BasicProofSystemLemmas.v │ ├── DerivedOperators_Semantics.v │ ├── DerivedOperators_Syntax.v │ ├── Evaluation │ ├── Complex.v │ ├── Demo.v │ ├── Extractor.v │ ├── Firstorder.v │ ├── Propositional.v │ ├── README.md │ ├── Revert_size.v │ ├── Rewrite.v │ └── tutorial.v │ ├── Experimental │ ├── DefaultModelGenerators.v │ ├── Kore.v │ ├── Kore_ProofSystem.v │ ├── Kore_alternative.v │ ├── MatchingEquivs.v │ ├── Nat_ProofSystem.v │ ├── ProofModePattern.v │ ├── SumSort_ProofSystem.v │ ├── Test.v │ └── Unification.v │ ├── FixpointReasoning.v │ ├── Freshness.v │ ├── FreshnessManager.v │ ├── IndexManipulation.v │ ├── Logic.v │ ├── ModelIsomorphism.v │ ├── NamedAxioms.v │ ├── OPML │ ├── GenericModel.v │ ├── KPreludeSignatures.v │ ├── OpmlAmlRelSpec.v │ ├── OpmlExamples.v │ ├── OpmlModel.v │ ├── OpmlPattern.v │ └── OpmlSignature.v │ ├── Pattern.v │ ├── PatternContext.v │ ├── PrePredicate.v │ ├── ProofInfo.v │ ├── ProofMode │ ├── Basics.v │ ├── Firstorder.v │ ├── FixPoint.v │ ├── MLPM.v │ ├── Misc.v │ ├── Propositional.v │ └── Reshaper.v │ ├── ProofSystem.v │ ├── ProofSystemSoundness.v │ ├── Semantics.v │ ├── Signature.v │ ├── StringSignature.v │ ├── Substitution.v │ ├── SyntacticConstruct.v │ ├── Syntax.v │ ├── SyntaxLemmas │ ├── ApplicationCtxSubstitution.v │ ├── FreshnessApplicationCtx.v │ ├── FreshnessSubstitution.v │ └── PatternCtxApplicationCtx.v │ ├── Tests │ ├── TEST_LocallyNameless.v │ ├── TEST_ProofMode_relative_completeness.v │ ├── TEST_proofmode_example.v │ └── TEST_proofmode_proof_size.v │ ├── Theories │ ├── Bool_ProofSystem.v │ ├── Bool_Semantics.v │ ├── Bool_Syntax.v │ ├── ContextualImplication.v │ ├── DeductionTheorem.v │ ├── DefaultModels.v │ ├── Definedness_ProofSystem.v │ ├── Definedness_Semantics.v │ ├── Definedness_Syntax.v │ ├── FOEquality_ProofSystem.v │ ├── ModelExtension.v │ ├── Nat_ProofSystem.v │ ├── Nat_Syntax.v │ ├── ProductSort.v │ ├── ProductSortWithLookup.v │ ├── ProductSort_ProofSystem.v │ ├── RecursiveSymbol.v │ ├── Sorts_ProofSystem.v │ ├── Sorts_Semantics.v │ ├── Sorts_Syntax.v │ ├── Subseteq_ProofSystem.v │ ├── SumSort_Syntax.v │ └── Test.v │ ├── Utils │ ├── Lattice.v │ ├── Surj.v │ ├── extralibrary.v │ └── stdpp_ext.v │ ├── dune │ ├── monotonic.v │ └── wftactics.v ├── proofmode.md ├── prover ├── Makefile ├── _CoqProject ├── check-generated-proof-objects.sh ├── mm │ └── matching-logic.mm ├── patch-extracted-hs.sh ├── proof_ex.mm ├── ref │ ├── proof_1.mm.ref │ ├── proof_2.mm.ref │ ├── proof_3.mm.ref │ ├── proof_4.mm.ref │ ├── proof_5.mm.ref │ ├── proof_6.mm.ref │ ├── proof_7.mm.ref │ ├── proof_8.mm.ref │ └── proof_9.mm.ref └── theories │ ├── MMProofExtractor.v │ ├── MMProofExtractorLoader.v │ ├── Matchers.v │ ├── NMatchers.v │ ├── Named.v │ ├── NamedProofSystem.v │ ├── PSTReader.v │ ├── PSTStateless.v │ ├── ProofSystemTranslation.v │ └── TEST_MMProofExtractor.v └── scripts └── convert_to_unicode.py /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference 2 | version: 2.1 3 | ## Use a package of configuration called an orb. 4 | #orbs: 5 | # # Declare a dependency on the welcome-orb 6 | # welcome: circleci/welcome-orb@0.4.1 7 | # Orchestrate or schedule a set of jobs 8 | 9 | jobs: 10 | build: 11 | machine: 12 | image: ubuntu-2204:current 13 | # docker: 14 | # - image: ghcr.io/numtide/nix-unstable-installer/nix:2.12.0pre20220901_4823067 15 | # The resource_class feature allows configuring CPU and RAM resources for each job. 16 | # Different resource classes are available for different executors. 17 | # https://circleci.com/docs/2.0/configuration-reference/#resourceclass 18 | resource_class: large 19 | steps: 20 | - run: 21 | name: "Install dependencies" 22 | command: | 23 | sh <(curl -L https://nixos.org/nix/install) 24 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 25 | mkdir -p ~/.config/nix/ 26 | echo 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf 27 | nix-channel --add 'https://nixos.org/channels/nixpkgs-unstable' nixpkgs 28 | nix-channel --update 29 | nix-env -iA 'nixpkgs.cachix' 'nixpkgs.bash' 30 | cachix authtoken "${CACHIX_AUTH_TOKEN}" 31 | cachix use harp-ml-in-coq 32 | nproc 33 | - checkout 34 | - run: 35 | name: "ML in Coq -- Build" 36 | command: | 37 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 38 | #cachix watch-exec harp-ml-in-coq -- 39 | nix --show-trace --print-build-logs build '.#coq-matching-logic' --no-link 40 | 41 | # - run: 42 | # name: "ML in Coq v8.17 -- Build" 43 | # command: | 44 | # source /home/circleci/.nix-profile/etc/profile.d/nix.sh 45 | # #cachix watch-exec harp-ml-in-coq -- 46 | # nix --show-trace --print-build-logs build '.#coq-matching-logic-v8_17' --no-link 47 | 48 | - run: 49 | name: "Kore Import" 50 | command: | 51 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 52 | nix --show-trace --print-build-logs build '.#koreimport-test' 53 | 54 | - run: 55 | name: "FOL -- Build" 56 | command: | 57 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 58 | #cachix watch-exec harp-ml-in-coq -- 59 | nix --show-trace --print-build-logs build '.#coq-matching-logic-example-fol' --no-link 60 | - run: 61 | name: "Kore -- Build" 62 | command: | 63 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 64 | #cachix watch-exec harp-ml-in-coq -- 65 | nix --show-trace --print-build-logs build '.#coq-kore' --no-link 66 | - run: 67 | name: "ProofMode Tutorial -- build" 68 | command: | 69 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 70 | #cachix watch-exec harp-ml-in-coq -- 71 | nix --show-trace --print-build-logs build '.#coq-matching-logic-example-proofmode' --no-link 72 | - run: 73 | name: "Prover Build & Test" 74 | command: | 75 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 76 | #cachix watch-exec harp-ml-in-coq -- 77 | nix --show-trace --print-build-logs build '.#coq-matching-logic-mm-exporter' --no-link 78 | - run: 79 | name: "Doc" 80 | command: | 81 | source /home/circleci/.nix-profile/etc/profile.d/nix.sh 82 | #cachix watch-exec harp-ml-in-coq -- 83 | nix --show-trace --print-build-logs build '.#coq-matching-logic-doc' --out-link './doc-output' 84 | no_output_timeout: 60m 85 | - persist_to_workspace: 86 | root: ./doc-output 87 | paths: share/doc/coq-matching-logic/doc 88 | 89 | 90 | # Inspired by https://circleci.com/blog/deploying-documentation-to-github-pages-with-continuous-integration/ 91 | docs-deploy: 92 | docker: 93 | - image: nixos/nix 94 | steps: 95 | - checkout 96 | - attach_workspace: 97 | at: /tmp/workspace 98 | #- run: 99 | # name: Install and configure dependencies 100 | # command: | 101 | # #nix-env -iA 'nixpkgs.ghp-import' 102 | - add_ssh_keys: 103 | fingerprints: 104 | - "e0:63:b6:98:fc:4d:b8:60:86:71:46:dd:e8:be:84:02" 105 | - run: 106 | name: Deploy docs to gh-pages branch 107 | command: | 108 | git switch gh-pages 109 | git config user.email "jenda.tusil+ci@gmail.com" 110 | git config user.name "ci-build" 111 | rm -rf "./branch/${CIRCLE_BRANCH}/" 112 | cp -R "/tmp/workspace/share/doc/coq-matching-logic/doc/" "./branch/${CIRCLE_BRANCH}/" 113 | touch "./branch/${CIRCLE_BRANCH}/.nojekyll" 114 | git add "./branch/${CIRCLE_BRANCH}" 115 | git commit --amend -m 'Update documentation' 116 | git push -f origin gh-pages 117 | 118 | workflows: 119 | # Name the workflow "welcome" 120 | welcome: 121 | jobs: 122 | - build 123 | - docs-deploy: 124 | requires: 125 | - build 126 | # filters: 127 | # branches: 128 | # only: master 129 | 130 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.aux 2 | *.a 3 | *.cma 4 | *.cmi 5 | *.cmo 6 | *.vok 7 | *.vos 8 | *.cmx 9 | *.cmxa 10 | *.cmxs 11 | *.glob 12 | *.ml.d 13 | *.ml4.d 14 | *.mli.d 15 | *.mllib.d 16 | *.mlpack.d 17 | *.native 18 | *.o 19 | *.v.d 20 | *.vio 21 | *.vo 22 | .coq-native/ 23 | .csdp.cache 24 | .lia.cache 25 | .nia.cache 26 | .nlia.cache 27 | .nra.cache 28 | csdp.cache 29 | lia.cache 30 | nia.cache 31 | nlia.cache 32 | nra.cache 33 | # Vim 34 | *.swp 35 | # Emacs 36 | *~ 37 | 38 | # Proof extraction 39 | *mm.hs 40 | *.hi 41 | 42 | # kore 43 | koreimport-test/k/imp-kompiled/* 44 | 45 | # Generated makefiles 46 | *.coq 47 | *.coq.d 48 | *.coq.conf 49 | *.crashcoqide 50 | *.v# 51 | 52 | # Generated documentation 53 | html/* 54 | 55 | # Envrc and Direnv files 56 | .envrc 57 | .direnv/* 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AML-Formalization 2 | 3 | In this project, we attempt to fully implement the "Applicative Matching Logic" framework in Coq, with example instances. 4 | 5 | ## Documentation 6 | 7 | - [coqdoc](https://harp-project.github.io/AML-Formalization/branch/master/coqdoc/toc.html) 8 | - [proofmode.md](proofmode.md) - A list of tactic of matching logic proof mode. 9 | - [Proof Mode tutorial](examples/02_proofmode/) 10 | 11 | 12 | ## For developers 13 | 14 | ### Build 15 | 16 | The matching logic library (in the directory `matching-logic/`) depends on: 17 | - [Coq 8.20.0](https://coq.inria.fr) 18 | - [stdpp 1.11.0](https://gitlab.mpi-sws.org/iris/stdpp) 19 | - [equations 1.3.1+8.20](https://github.com/mattam82/Coq-Equations) 20 | - [LibHyps 2.0.8](https://github.com/Matafou/LibHyps) 21 | 22 | The easiest way to build the library is using the [Nix package manager](https://nixos.org/download.html), 23 | using the [Nix Flakes](https://nixos.wiki/wiki/Flakes) feature. 24 | 25 | #### Build using Nix Flakes 26 | 27 | If you want to work on the matching logic library: 28 | 29 | 1. Enter a development environment for the matching logic library: 30 | ```sh 31 | $ nix develop '.#coq-matching-logic' 32 | ``` 33 | 2. Inside the `nix develop` shell, `cd` into `matching-logic/`, then run your favourite IDE (or just `make`). 34 | 35 | 36 | Alternatively, instead of entering the development environment, one may want to 37 | build the matching-logic library in an isolated environment: 38 | ```sh 39 | $ nix build '.#coq-matching-logic' 40 | ``` 41 | (this is what CI does). 42 | Every time you run `nix build`, it starts from the fresh environment. 43 | 44 | 45 | If you want to work on the Metamath extractor: 46 | ```sh 47 | nix develop '.#coq-matching-logic-mm-exporter' 48 | ``` 49 | If you want to work on examples: 50 | ```sh 51 | nix develop '.#coq-matching-logic-example-fol'. 52 | ``` 53 | If you want to go through the proof mode tutorial: 54 | ```sh 55 | nix develop '.#coq-matching-logic-example-proofmode' 56 | ``` 57 | And so on. To list all packages, run: 58 | ```sh 59 | nix flake show 60 | ``` 61 | 62 | 63 | #### If your Nix does not support Flakes: 64 | 65 | 1. Upgrade nix 66 | ```sh 67 | $ nix upgrade-nix 68 | ``` 69 | 2. [Enable Flakes](https://nixos.wiki/wiki/Flakes) 70 | 71 | 72 | Alternatively, we provide a [flake-compat](https://github.com/edolstra/flake-compat)-based wrapper for building the matching logic library 73 | with a 'classical' `nix`, without flakes. 74 | 75 | 0. [Install Nix](https://nixos.org/download.html) 76 | ```sh 77 | $ curl -L https://nixos.org/nix/install | sh 78 | ``` 79 | 80 | 1. Step into the directory with the library 81 | ```sh 82 | $ cd matching-logic 83 | ``` 84 | 85 | 2. Run Nix shell and let Nix handle all the dependencies 86 | ```sh 87 | $ nix-shell 88 | ``` 89 | 90 | 3. Build using `make` 91 | ```sh 92 | $ make 93 | ``` 94 | 95 | Note that this works only for the library located in the `matching-logic/` directory. 96 | In particular, the Metamath extractor (located in the directory `prover/`), as well as 97 | the examples in the directory `examples/`, cannot be built this way. 98 | 99 | ### IDE setup 100 | 101 | If you have ProofGeneral, CoqIde, or VSCoq, installed, just run them inside the `nix-shell`. 102 | It will detect the nix-provided coq and libraries automatically. 103 | 104 | ### Structure 105 | 106 | - `matching-logic` library contains a locally-nameless encoding of matching logic in Coq, including the soundness theorem and a proof mode for building matching logic proofs interactively. 107 | - `examples` folder contain a set of examples that use the matching logic library. 108 | - `prover` contains a proof-of-concept extractors of matching logic proofs to Metamath. 109 | 110 | 111 | ## References 112 | 113 | Official language definition http://fsl.cs.illinois.edu/index.php/Applicative_Matching_Logic 114 | 115 | Snapshot version of the technical report, that was used for the ipmlementation can be found in `doc/chen-rosu-2019-trb-public_march182020.pdf`. 116 | -------------------------------------------------------------------------------- /doc/chen-rosu-2019-trb-public_march182020.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harp-project/AML-Formalization/b1da1484bd73fd81dde4d331d5fbf64e55951d17/doc/chen-rosu-2019-trb-public_march182020.pdf -------------------------------------------------------------------------------- /examples/01_simple/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harp-project/AML-Formalization/b1da1484bd73fd81dde4d331d5fbf64e55951d17/examples/01_simple/.gitkeep -------------------------------------------------------------------------------- /examples/02_proofmode/Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | install: Makefile.coq 5 | @+$(MAKE) -f Makefile.coq install 6 | 7 | clean: Makefile.coq 8 | @+$(MAKE) -f Makefile.coq cleanall 9 | @rm -f Makefile.coq Makefile.coq.conf 10 | 11 | Makefile.coq: _CoqProject 12 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 13 | 14 | force _CoqProject Makefile: ; 15 | 16 | %: Makefile.coq force 17 | @+$(MAKE) -f Makefile.coq $@ 18 | 19 | .PHONY: all clean force install 20 | -------------------------------------------------------------------------------- /examples/02_proofmode/_CoqProject: -------------------------------------------------------------------------------- 1 | -R theories ProofModeTutorial 2 | 3 | theories/tutorial.v 4 | -------------------------------------------------------------------------------- /examples/03_FOL/Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | html: Makefile.coq 5 | @+$(MAKE) -f Makefile.coq html COQDOCEXTRAFLAGS="--gallina --external https://plv.mpi-sws.org/coqdoc/stdpp/ stdpp" 6 | 7 | clean: Makefile.coq 8 | @+$(MAKE) -f Makefile.coq cleanall 9 | @rm -f Makefile.coq Makefile.coq.conf 10 | 11 | Makefile.coq: _CoqProject 12 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 13 | 14 | force _CoqProject Makefile: ; 15 | 16 | %: Makefile.coq force 17 | @+$(MAKE) -f Makefile.coq $@ 18 | 19 | .PHONY: all clean force 20 | -------------------------------------------------------------------------------- /examples/03_FOL/_CoqProject: -------------------------------------------------------------------------------- 1 | -R src MatchingLogicExample03 2 | 3 | src/LN_FOL.v 4 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1694529238, 9 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "flake-utils_2": { 22 | "inputs": { 23 | "systems": "systems_2" 24 | }, 25 | "locked": { 26 | "lastModified": 1694529238, 27 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 28 | "owner": "numtide", 29 | "repo": "flake-utils", 30 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 31 | "type": "github" 32 | }, 33 | "original": { 34 | "owner": "numtide", 35 | "repo": "flake-utils", 36 | "type": "github" 37 | } 38 | }, 39 | "nix-github-actions": { 40 | "inputs": { 41 | "nixpkgs": [ 42 | "pyk", 43 | "poetry2nix", 44 | "nixpkgs" 45 | ] 46 | }, 47 | "locked": { 48 | "lastModified": 1693660503, 49 | "narHash": "sha256-B/g2V4v6gjirFmy+I5mwB2bCYc0l3j5scVfwgl6WOl8=", 50 | "owner": "nix-community", 51 | "repo": "nix-github-actions", 52 | "rev": "bd5bdbb52350e145c526108f4ef192eb8e554fa0", 53 | "type": "github" 54 | }, 55 | "original": { 56 | "owner": "nix-community", 57 | "repo": "nix-github-actions", 58 | "type": "github" 59 | } 60 | }, 61 | "nixpkgs": { 62 | "locked": { 63 | "lastModified": 1732625029, 64 | "narHash": "sha256-FEiBBV/rj8/aLiBfdCln3iEOcJLPES34jcVQ79oziiE=", 65 | "owner": "NixOS", 66 | "repo": "nixpkgs", 67 | "rev": "98f4971aa21355f16ea2f13c591159a110b8ca41", 68 | "type": "github" 69 | }, 70 | "original": { 71 | "owner": "NixOS", 72 | "ref": "release-24.11", 73 | "repo": "nixpkgs", 74 | "type": "github" 75 | } 76 | }, 77 | "nixpkgs_2": { 78 | "locked": { 79 | "lastModified": 1698675399, 80 | "narHash": "sha256-nj+LNEeVXGP31vxoL3x7HW7+oEiyoLVDqwMg30yFBMA=", 81 | "owner": "NixOS", 82 | "repo": "nixpkgs", 83 | "rev": "7378978469efa3b2b2f97d645a2a0b0e2447da2b", 84 | "type": "github" 85 | }, 86 | "original": { 87 | "owner": "NixOS", 88 | "repo": "nixpkgs", 89 | "type": "github" 90 | } 91 | }, 92 | "poetry2nix": { 93 | "inputs": { 94 | "flake-utils": "flake-utils_2", 95 | "nix-github-actions": "nix-github-actions", 96 | "nixpkgs": [ 97 | "pyk", 98 | "nixpkgs" 99 | ], 100 | "systems": "systems_3", 101 | "treefmt-nix": "treefmt-nix" 102 | }, 103 | "locked": { 104 | "lastModified": 1698640399, 105 | "narHash": "sha256-mXzyx79/iFLZ0UDuSkqgFfejYRcSJfsCnJ9WlMusaI0=", 106 | "owner": "nix-community", 107 | "repo": "poetry2nix", 108 | "rev": "626111646fe236cb1ddc8191a48c75e072a82b7c", 109 | "type": "github" 110 | }, 111 | "original": { 112 | "owner": "nix-community", 113 | "repo": "poetry2nix", 114 | "rev": "626111646fe236cb1ddc8191a48c75e072a82b7c", 115 | "type": "github" 116 | } 117 | }, 118 | "pyk": { 119 | "inputs": { 120 | "flake-utils": [ 121 | "pyk", 122 | "poetry2nix", 123 | "flake-utils" 124 | ], 125 | "nixpkgs": "nixpkgs_2", 126 | "poetry2nix": "poetry2nix" 127 | }, 128 | "locked": { 129 | "lastModified": 1699000029, 130 | "narHash": "sha256-IKjTlhnmB4CvVRtpFho9XV3x12lvfSYERn8MggDvUhU=", 131 | "owner": "runtimeverification", 132 | "repo": "pyk", 133 | "rev": "11ec5230566ec2b8336000e636a5d814a4dc56d1", 134 | "type": "github" 135 | }, 136 | "original": { 137 | "owner": "runtimeverification", 138 | "ref": "v0.1.491", 139 | "repo": "pyk", 140 | "type": "github" 141 | } 142 | }, 143 | "root": { 144 | "inputs": { 145 | "flake-utils": "flake-utils", 146 | "nixpkgs": "nixpkgs", 147 | "pyk": "pyk" 148 | } 149 | }, 150 | "systems": { 151 | "locked": { 152 | "lastModified": 1681028828, 153 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 154 | "owner": "nix-systems", 155 | "repo": "default", 156 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 157 | "type": "github" 158 | }, 159 | "original": { 160 | "owner": "nix-systems", 161 | "repo": "default", 162 | "type": "github" 163 | } 164 | }, 165 | "systems_2": { 166 | "locked": { 167 | "lastModified": 1681028828, 168 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 169 | "owner": "nix-systems", 170 | "repo": "default", 171 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 172 | "type": "github" 173 | }, 174 | "original": { 175 | "owner": "nix-systems", 176 | "repo": "default", 177 | "type": "github" 178 | } 179 | }, 180 | "systems_3": { 181 | "locked": { 182 | "lastModified": 1681028828, 183 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 184 | "owner": "nix-systems", 185 | "repo": "default", 186 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 187 | "type": "github" 188 | }, 189 | "original": { 190 | "id": "systems", 191 | "type": "indirect" 192 | } 193 | }, 194 | "treefmt-nix": { 195 | "inputs": { 196 | "nixpkgs": [ 197 | "pyk", 198 | "poetry2nix", 199 | "nixpkgs" 200 | ] 201 | }, 202 | "locked": { 203 | "lastModified": 1697388351, 204 | "narHash": "sha256-63N2eBpKaziIy4R44vjpUu8Nz5fCJY7okKrkixvDQmY=", 205 | "owner": "numtide", 206 | "repo": "treefmt-nix", 207 | "rev": "aae39f64f5ecbe89792d05eacea5cb241891292a", 208 | "type": "github" 209 | }, 210 | "original": { 211 | "owner": "numtide", 212 | "repo": "treefmt-nix", 213 | "type": "github" 214 | } 215 | } 216 | }, 217 | "root": "root", 218 | "version": 7 219 | } 220 | -------------------------------------------------------------------------------- /kore/.Makefile.d: -------------------------------------------------------------------------------- 1 | src/Signature.vo src/Signature.glob src/Signature.v.beautified src/Signature.required_vo: src/Signature.v 2 | src/Signature.vos src/Signature.vok src/Signature.required_vos: src/Signature.v 3 | src/Syntax.vo src/Syntax.glob src/Syntax.v.beautified src/Syntax.required_vo: src/Syntax.v src/Signature.vo ../matching-logic/src/Utils/extralibrary.vo ../matching-logic/src/Utils/Lattice.vo 4 | src/Syntax.vos src/Syntax.vok src/Syntax.required_vos: src/Syntax.v src/Signature.vos ../matching-logic/src/Utils/extralibrary.vos ../matching-logic/src/Utils/Lattice.vos 5 | -------------------------------------------------------------------------------- /kore/Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | install: Makefile.coq 5 | @+$(MAKE) -f Makefile.coq install 6 | 7 | clean: Makefile.coq 8 | @+$(MAKE) -f Makefile.coq cleanall 9 | @rm -f Makefile.coq Makefile.coq.conf 10 | 11 | Makefile.coq: _CoqProject 12 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 13 | 14 | force _CoqProject Makefile: ; 15 | 16 | %: Makefile.coq force 17 | @+$(MAKE) -f Makefile.coq $@ 18 | 19 | .PHONY: all clean force install 20 | -------------------------------------------------------------------------------- /kore/README.md: -------------------------------------------------------------------------------- 1 | # Dependently typed formalisation of Kore 2 | 3 | This subproject defines the syntax and semantics of Kore using a dependently typed, locally-nameless approach. 4 | 5 | ## Structure 6 | 7 | - `Basics.v` provides a definition for heterogeneous lists, and defines a number of properties for it alongside with computable definitions for some standard lemmas. 8 | - `Signature.v` defines Kore signatures. These signatures include sorts, infinitely many variables for each sort, and symbols. The argument and return sorts of these symbols are also specified in the signature. The file contains a default variable representation utilising strings. 9 | - `Syntax.v` defines the dependently-typed syntax of Kore and notations for the syntax. The syntax is encoded in a locally-nameless style. Therefore, the type of `Pattern` is indexed by not only a sort, but also two scopes for dangling (set and element) de Bruijn indices. 10 | - `Freshness.v` defines how fresh variables are generated (for any sort). 11 | - `Substitution.v` defines bound (set and element) variable substitutions, and it proves some simple properties about them. 12 | - `Semantics.v` defines dependently-typed models for Kore, and the notion of satisfiability. 13 | 14 | -------------------------------------------------------------------------------- /kore/_CoqProject: -------------------------------------------------------------------------------- 1 | -R src Kore 2 | 3 | src/Basics.v 4 | src/Signature.v 5 | src/Syntax.v 6 | src/Freshness.v 7 | src/Substitution.v 8 | src/Semantics.v 9 | 10 | -------------------------------------------------------------------------------- /kore/src/Basics.v: -------------------------------------------------------------------------------- 1 | From stdpp Require Export list propset. 2 | From Coq Require Export Program.Equality. 3 | 4 | Import ListNotations. 5 | 6 | Definition is_leftb {A B : Set} (x : A + B) : bool := 7 | match x with 8 | | inl _ => true 9 | | _ => false 10 | end. 11 | 12 | Definition is_rightb {A B : Set} (x : A + B) : bool := 13 | match x with 14 | | inl _ => false 15 | | _ => true 16 | end. 17 | 18 | Definition andb_split_1 (b1 b2 : bool) : andb b1 b2 = true -> b1 = true. 19 | Proof. 20 | destruct b1, b2; simpl; try reflexivity. 21 | all: intros; congruence. 22 | Defined. 23 | 24 | Definition andb_split_2 (b1 b2 : bool) : andb b1 b2 = true -> b2 = true. 25 | Proof. 26 | destruct b1, b2; simpl; try reflexivity. 27 | all: intros; congruence. 28 | Defined. 29 | 30 | Inductive hlist {A : Type} {F : A -> Type} : list A -> Type := 31 | | hnil : hlist [] 32 | | hcons {x : A} {xs : list A} : F x -> hlist xs -> hlist (x :: xs). 33 | 34 | Arguments hlist {_} _ & _. 35 | Arguments hnil {_} {_}. 36 | Arguments hcons {_} {_} {_} {_} & _ _. 37 | Arguments hlist_rect {_} {_} {_} & _ _ {_} _ /. 38 | 39 | Declare Scope hlist_scope. 40 | Bind Scope hlist_scope with hlist. 41 | Delimit Scope hlist_scope with hlist. 42 | Notation "[ ]" := hnil (format "[ ]") : hlist_scope. 43 | Notation "[ x ]" := (hcons _ x hnil) : hlist_scope. 44 | Notation "[ x ; y ; .. ; z ]" := (hcons x (hcons y .. (hcons z hnil) ..)) : hlist_scope. 45 | 46 | Fixpoint pointwise_elem_of {A : Type} {T : A -> Type} 47 | ss {struct ss} : 48 | (* (l : @hlist A T ss) 49 | (lps : @hlist A (fun s => propset (T s)) ss) *) 50 | @hlist A T ss -> 51 | @hlist A (fun s => propset (T s)) ss -> 52 | Prop. (* := *) 53 | Proof. 54 | refine (match ss with 55 | | [] => fun _ _ => True 56 | | s::ss => fun l l' => 57 | (match l in (@hlist _ _ l1) 58 | return (l1 = s::ss -> Prop) with 59 | | hnil => 60 | fun (H : [] = s :: ss) => False_rect Prop ltac:(discriminate H) 61 | | @hcons _ _ a l0 x xs => 62 | fun (H : a :: l0 = s::ss) => 63 | (match l' in (@hlist _ _ l1') 64 | return l1' = s::ss -> Prop with 65 | | hnil => fun (H0 : [] = s :: ss) => False_rect Prop ltac:(discriminate H0) 66 | | @hcons _ _ a' l0' y ys => 67 | fun (H0 : a' :: l0' = s :: ss) => 68 | x ∈ y /\ pointwise_elem_of _ _ ss _ _ 69 | end 70 | ) eq_refl 71 | end) eq_refl 72 | end). 73 | * injection H. injection H0. intros. rewrite H4. rewrite H2. 74 | typeclasses eauto. 75 | * injection H. intros. rewrite H1 in xs. exact xs. 76 | * injection H0. intros. rewrite H1 in ys. exact ys. 77 | Defined. 78 | 79 | Definition test1 : hlist (bool_rect _ nat bool) [true; false] := [1; true]%hlist. 80 | Definition test2 : hlist (propset ∘ bool_rect _ nat bool) [true; false] := [{[1]}; {[true]}]%hlist. 81 | Goal pointwise_elem_of _ test1 test2. 82 | Proof. 83 | simpl. set_solver. 84 | Qed. 85 | 86 | 87 | Inductive InTy {A : Type} : A -> list A -> Type := 88 | | In_nil {x} {xs} : InTy x (x :: xs) 89 | | In_cons {x y} {xs} : InTy y xs -> InTy y (x :: xs) 90 | . 91 | 92 | Definition cons_eq_inv {A : Type} {x y : A} {xs ys : list A} 93 | (H : x :: xs = y :: ys) : x = y /\ xs = ys := 94 | conj (f_equal (list_rect _ x (λ a _ _, a)) H) 95 | (f_equal (list_rect _ xs (λ _ a _, a)) H). 96 | 97 | Fixpoint InTy_app {A : Type} {s : A} {ex ex' ex'' : list A} 98 | (pf : InTy s (ex ++ ex'')) : InTy s (ex ++ ex' ++ ex''). 99 | Proof. 100 | dependent destruction pf. 101 | - destruct ex; simpl in *. 102 | + induction ex'; simpl. 103 | * rewrite <- x. left. 104 | * right. exact IHex'. 105 | + apply cons_eq_inv in x as [-> ->]. 106 | left. 107 | - destruct ex; simpl in *. 108 | + induction ex'; simpl. 109 | * rewrite <- x. 110 | right. exact pf. 111 | * right. exact IHex'. 112 | + apply cons_eq_inv in x as [-> ->]. 113 | right. apply InTy_app. exact pf. 114 | Defined. 115 | 116 | Arguments InTy_app {_} {_} {_} {_} {_} !_. 117 | 118 | Definition app_comm_cons_defined 119 | : ∀ (A : Type) (x y : list A) (a : A), 120 | a :: x ++ y = (a :: x) ++ y. 121 | Proof. 122 | intros. simpl. 123 | reflexivity. 124 | Defined. 125 | 126 | Ltac invt H := inversion H; subst; clear H. 127 | 128 | Lemma JMeq_eq_rect {U : Type} {P : U → Type} {p q : U} {x : P p} {y : P q} (H : p = q) : JMeq x y -> eq_rect p P x q H = y. 129 | Proof. 130 | intros. 131 | apply JMeq_eq_dep, eq_dep_eq_sigT, eq_sigT_sig_eq in H0 as []. 132 | rewrite (Eqdep.EqdepTheory.UIP _ _ _ H x0). 133 | all: assumption. 134 | Defined. 135 | 136 | 137 | Create HintDb kore. 138 | Hint Unfold AntiSymm : kore. 139 | Hint Constructors PartialOrder : kore. 140 | Hint Extern 5 (EqDecision _) => unfold EqDecision, Decision; decide equality : kore. 141 | Hint Unfold eq_rect_r : kore. 142 | Hint Rewrite -> Eqdep.EqdepTheory.eq_rect_eq : kore. 143 | Hint Rewrite <- Eqdep.EqdepTheory.eq_rect_eq : kore. 144 | Hint Unfold Equality.block solution_left : kore. 145 | Hint Extern 5 (?x ∈ ⊤) => simple apply elem_of_top' : kore. 146 | Hint Unfold Equality.block solution_left : kore. 147 | -------------------------------------------------------------------------------- /kore/src/Freshness.v: -------------------------------------------------------------------------------- 1 | From Kore Require Export Syntax. 2 | 3 | Section Freshness. 4 | 5 | Context {Σ : Signature}. 6 | 7 | Fixpoint free_evars {ex mu s} 8 | (φ : Pattern ex mu s) 9 | (sTarget : sort) {struct φ} : gset (evar sTarget) := 10 | match φ with 11 | | @kore_fevar _ _ _ var_sort x => 12 | (* var_sort = s in this case *) 13 | match decide (sTarget = var_sort) with 14 | | left H => {[eq_rect_r evar x H]} 15 | | right _ => ∅ 16 | end 17 | | kore_imp φ1 φ2 | kore_iff φ1 φ2 18 | | kore_and φ1 φ2 | kore_or φ1 φ2 19 | | kore_equals _ φ1 φ2 | kore_in _ φ1 φ2 20 | => free_evars φ1 sTarget ∪ free_evars φ2 sTarget 21 | | kore_app σ args 22 | => hlist_rect ∅ (fun _ _ x xs rest => free_evars x sTarget ∪ rest) args 23 | | kore_exists _ φ | kore_forall _ φ 24 | | kore_mu φ | kore_nu φ 25 | | kore_not φ | kore_ceil _ φ | kore_floor _ φ 26 | => free_evars φ sTarget 27 | | kore_bevar _ | kore_fsvar _ | kore_bsvar _ 28 | | kore_bot _ | kore_top _ => ∅ 29 | end. 30 | 31 | Fixpoint free_svars {ex mu s} 32 | (φ : Pattern ex mu s) 33 | (sTarget : sort) {struct φ} : gset (svar sTarget) := 34 | match φ with 35 | | @kore_fsvar _ _ _ var_sort X => 36 | (* var_sort = s in this case *) 37 | match decide (sTarget = var_sort) with 38 | | left H => {[eq_rect_r svar X H]} 39 | | right _ => ∅ 40 | end 41 | | kore_imp φ1 φ2 | kore_iff φ1 φ2 42 | | kore_and φ1 φ2 | kore_or φ1 φ2 43 | | kore_equals _ φ1 φ2 | kore_in _ φ1 φ2 44 | => free_svars φ1 sTarget ∪ free_svars φ2 sTarget 45 | | kore_app σ args 46 | => hlist_rect ∅ (fun _ _ x xs rest => free_svars x sTarget ∪ rest) args 47 | | kore_exists _ φ | kore_forall _ φ 48 | | kore_mu φ | kore_nu φ 49 | | kore_not φ | kore_ceil _ φ | kore_floor _ φ 50 | => free_svars φ sTarget 51 | | kore_bevar _ | kore_fevar _ | kore_bsvar _ 52 | | kore_bot _ | kore_top _ => ∅ 53 | end. 54 | 55 | Definition fresh_evar {s} {ex mu} 56 | (sTarget : sort) (φ : Pattern s ex mu) : 57 | evar sTarget := 58 | fresh (elements (free_evars φ sTarget)). 59 | Definition fresh_svar {s} {ex mu} 60 | (sTarget : sort) (φ : Pattern s ex mu) : 61 | svar sTarget := 62 | fresh (elements (free_svars φ sTarget)). 63 | 64 | End Freshness. 65 | -------------------------------------------------------------------------------- /kore/src/Semantics.v: -------------------------------------------------------------------------------- 1 | From Equations Require Import Equations. 2 | From Kore Require Export Substitution 3 | Freshness 4 | Basics. 5 | Require Import Coq.Program.Equality. 6 | 7 | 8 | 9 | Section Semantics. 10 | Context {Σ : Signature}. 11 | 12 | Record Model := { 13 | carrier :> sort -> Set; 14 | app (σ : symbol) : 15 | @hlist _ carrier (arg_sorts σ) -> propset (carrier (ret_sort σ)); 16 | inhabited (s : sort) : Inhabited (carrier s) 17 | }. 18 | 19 | Section with_model. 20 | 21 | Context {M : Model}. 22 | Record Valuation : Type := { 23 | evar_valuation {s : sort} (x : evar s) : carrier M s; 24 | svar_valuation {s : sort} (X : svar s) : propset (carrier M s) ; 25 | }. 26 | 27 | Definition app_ext 28 | (σ : symbol) 29 | (args : @hlist _ (fun s => propset (carrier M s)) (arg_sorts σ)) 30 | : propset (carrier M (ret_sort σ)) := 31 | PropSet ( 32 | fun e => exists (l : @hlist _ (carrier M) (arg_sorts σ)), 33 | pointwise_elem_of _ l args /\ e ∈ app M σ l 34 | ). 35 | 36 | 37 | Definition update_evar_val {s} (ev : evar s) (x : carrier M s) (val : Valuation) : Valuation. 38 | Proof. 39 | unshelve esplit. 40 | intros s' ev'. 41 | destruct (decide (s = s')). 42 | destruct (decide (eq_rect s evar ev _ e = ev')). 43 | exact (eq_rect s M x _ e). 44 | 1,2:exact (evar_valuation val ev'). 45 | exact (@svar_valuation val). 46 | Defined. 47 | 48 | Definition update_svar_val {s} (sv : svar s) (X : propset (carrier M s)) (val : Valuation) : Valuation. 49 | Proof. 50 | unshelve esplit. 51 | exact (@evar_valuation val). 52 | intros s' sv'. 53 | destruct (decide (s = s')). 54 | * destruct (decide (eq_rect s svar sv _ e = sv')). 55 | - rewrite e in X. exact X. 56 | - exact (svar_valuation val sv'). 57 | * exact (svar_valuation val sv'). 58 | Defined. 59 | 60 | Let OS s := PropsetOrderedSet (carrier M s). 61 | Let L s := PowersetLattice (carrier M s). 62 | 63 | Equations? eval {ex mu} {s} (ρ : Valuation) (φ : Pattern ex mu s) : propset (carrier M s) by wf (pat_size φ) := 64 | eval ρ (kore_bevar _) := empty ; 65 | eval ρ (kore_fevar x) := {[evar_valuation ρ x]} ; 66 | eval ρ (kore_bsvar _) := empty ; 67 | eval ρ (kore_fsvar X) := svar_valuation ρ X ; 68 | 69 | eval ρ (kore_app σ l) := app_ext σ _ (*@hlist_rect _ _ (λ l _, hlist (propset ∘ M) l) hnil (λ _ _ a _ b, hcons (eval ρ a) b) _ l*) ; 70 | 71 | eval ρ kore_bot := empty ; 72 | eval ρ kore_top := ⊤ ; 73 | eval ρ (kore_not φ) := ⊤ ∖ (eval ρ φ) ; 74 | eval ρ (kore_and φ1 φ2) := (eval ρ φ1) ∩ (eval ρ φ2) ; 75 | eval ρ (kore_or φ1 φ2) := (eval ρ φ1) ∪ (eval ρ φ2) ; 76 | eval ρ (kore_imp φ1 φ2) := (⊤ ∖ (eval ρ φ1)) ∪ (eval ρ φ2) ; 77 | eval ρ (kore_iff φ1 φ2) := (⊤ ∖ eval ρ φ1 ∪ eval ρ φ2) ∩ 78 | (⊤ ∖ eval ρ φ2 ∪ eval ρ φ1) ; 79 | 80 | eval ρ (kore_exists s' φ) := (* ⊤ ≫= λ X, let o := fresh_evar s' φ in eval (update_evar_val o X ρ) (bevar_subst [] φ (kore_fevar o)) *) 81 | let x := fresh_evar s' φ in 82 | propset_fa_union (λ c, 83 | eval (update_evar_val x c ρ) 84 | (bevar_subst [] (kore_fevar x) φ)) ; 85 | eval ρ (kore_forall s' φ) := 86 | let x := fresh_evar s' φ in 87 | propset_fa_intersection (λ c, 88 | eval (update_evar_val x c ρ) 89 | (bevar_subst [] (kore_fevar x) φ)) ; 90 | 91 | (*@LeastFixpointOf _ OS L 92 | (fun S => 93 | let ρ' := (update_svar_val X S ρ) in 94 | eval ρ' (ϕ'^{svar: 0 ↦ X}) 95 | )*) 96 | 97 | eval ρ (kore_mu φ) := 98 | let X := fresh_svar s φ in 99 | @LeastFixpointOf _ (OS s) (L s) (fun S => 100 | eval (update_svar_val X S ρ) 101 | (bsvar_subst [] (kore_fsvar X) φ) 102 | ) 103 | ; 104 | eval ρ (kore_nu φ) := 105 | let X := fresh_svar s φ in 106 | @GreatestFixpointOf _ (OS s) (L s) (fun S => 107 | eval (update_svar_val X S ρ) 108 | (bsvar_subst [] (kore_fsvar X) φ) 109 | ); 110 | 111 | eval ρ (kore_ceil φ) := PropSet (λ _, ∃ c, c ∈ eval ρ φ) ; 112 | eval ρ (kore_floor φ) := PropSet (λ _, ∀ c, c ∈ eval ρ φ) ; 113 | eval ρ (kore_equals φ1 φ2) := PropSet (λ _, (eval ρ φ1) = (eval ρ φ2)) ; 114 | eval ρ (kore_in φ1 φ2) := PropSet (λ _, (eval ρ φ1) ⊆ (eval ρ φ2)) ; 115 | . 116 | Proof. 117 | 1: { 118 | simpl in *. 119 | induction l. 120 | * exact hnil. 121 | * apply hcons. 122 | - apply (eval _ _ _ ρ f). lia. 123 | - apply IHl. intros. 124 | apply (eval x0 x1 x2 x3 x4). lia. 125 | } 126 | all: try by simpl; lia. 127 | 1-2: rewrite (bevar_subst_size [] ex mu s s' φ x); constructor. 128 | 1-2: rewrite (bsvar_subst_size ex [] mu s s φ X); constructor. 129 | Defined. 130 | 131 | Definition satM {ex mu s} (φ : Pattern ex mu s) := 132 | forall ρ, eval ρ φ ≡ ⊤. 133 | 134 | Definition satT (Γ : Theory) := 135 | forall p, p ∈ Γ -> @satM _ _ (projT1 p) (projT2 p). 136 | 137 | Import PropExtensionality. 138 | #[export] 139 | Instance propset_leibniz_equiv A : LeibnizEquiv (propset A). 140 | Proof. 141 | intros x y H. unfold equiv in H. unfold set_equiv_instance in H. 142 | destruct x,y. 143 | apply f_equal. apply functional_extensionality. 144 | intros x. apply propositional_extensionality. 145 | specialize (H x). destruct H as [H1 H2]. 146 | split; auto. 147 | Qed. 148 | 149 | (* Fixpoint HForall {J} {A : J -> Type} 150 | (P : ∀ j, A j -> Prop) 151 | {js : list J} (v : @hlist J A js) {struct v} : Prop := 152 | match v with 153 | | hnil => True 154 | | hcons x xs => P _ x ∧ HForall P xs 155 | end. 156 | 157 | Fixpoint HBiForall {J1 J2} {A1 : J1 -> Type} {A2 : J2 -> Type} 158 | (P : ∀ j1 j2, A1 j1 -> A2 j2 -> Prop) 159 | {js1 : list J1} 160 | {js2 : list J2} 161 | (v1 : @hlist J1 A1 js1) (v2 : @hlist J2 A2 js2) 162 | {struct v1} : Prop := 163 | match v1, v2 with 164 | | hnil, hnil => True 165 | | hcons x xs, hcons y ys => P _ _ x y ∧ HBiForall P xs ys 166 | | _, _ => False 167 | end. 168 | 169 | Fixpoint hmap {J} {A B : J -> Type} 170 | (f : ∀ j, A j -> B j) 171 | {js : list J} (v : @hlist J A js) : @hlist J B js := 172 | match v with 173 | | hnil => hnil 174 | | hcons x xs => hcons (f _ x) (hmap f xs) 175 | end. *) 176 | 177 | End with_model. 178 | End Semantics. -------------------------------------------------------------------------------- /kore/src/Signature.v: -------------------------------------------------------------------------------- 1 | From Coq Require Export ssreflect ssrfun ssrbool String. 2 | From stdpp Require Export 3 | base 4 | countable 5 | infinite. 6 | 7 | 8 | Set Default Proof Mode "Classic". 9 | 10 | Class Sorts := { 11 | sort : Set; 12 | sort_eqdec :: EqDecision sort; 13 | sort_countable :: Countable sort; 14 | (* subsort : relation sort; 15 | subsort_po :: PartialOrder subsort; *) 16 | }. 17 | 18 | (* Class Variables {Ss : Sorts} := { 19 | evar : Set; 20 | svar : Set; 21 | evar_eqdec :: EqDecision evar; 22 | evar_countable :: Countable evar; 23 | (* evar_infinite :: Infinite evar; *) 24 | svar_eqdec :: EqDecision svar; 25 | svar_countable :: Countable svar; 26 | (* svar_infinite :: Infinite svar; *) 27 | 28 | evar_sort : evar -> sort; 29 | svar_sort : svar -> sort; 30 | 31 | evar_infinite s :: 32 | Infinite {x : evar & decide (evar_sort x = s)}; 33 | svar_infinite s :: 34 | Infinite {x : svar & decide (svar_sort x = s)} 35 | }. *) 36 | 37 | Class Variables {Ss : Sorts} := { 38 | evar : sort -> Set; 39 | svar : sort -> Set; 40 | evar_eqdec :: forall s, EqDecision (evar s); 41 | evar_countable :: forall s, Countable (evar s); 42 | evar_infinite :: forall s, Infinite (evar s); 43 | svar_eqdec :: forall s, EqDecision (svar s); 44 | svar_countable :: forall s, Countable (svar s); 45 | svar_infinite :: forall s, Infinite (svar s); 46 | }. 47 | 48 | Class Symbols {Ss : Sorts} := { 49 | symbol : Set; 50 | sym_eqdec :: EqDecision symbol; 51 | sym_countable :: Countable symbol; 52 | arg_sorts : symbol -> list sort ; 53 | ret_sort : symbol -> sort ; 54 | }. 55 | 56 | Class Signature := { 57 | sorts :: Sorts ; 58 | variables :: Variables; 59 | symbols :: Symbols; 60 | }. 61 | 62 | Module StringVariables. 63 | Program Instance StringVariables {Ss : Sorts} : Variables := {| 64 | evar := fun _ => string; 65 | svar := fun _ => string; 66 | |}. 67 | Fail Next Obligation. 68 | 69 | End StringVariables. 70 | -------------------------------------------------------------------------------- /koreimport-test/k/test.k: -------------------------------------------------------------------------------- 1 | module TEST 2 | 3 | imports private BASIC-K 4 | 5 | syntax Color ::= Yellow() | Blue() 6 | syntax Fruit ::= Banana() | Blueberry() 7 | syntax Color ::= colorOf(Fruit) [function] 8 | 9 | syntax Taste ::= Good() | Bad() 10 | | tasteOf(Fruit) [function] 11 | 12 | rule colorOf(Banana()) => Yellow() 13 | rule colorOf(Blueberry()) => Blue() 14 | 15 | rule tasteOf(Banana()) => Bad() [simplification] 16 | rule tasteOf(Blueberry()) => Good() 17 | rule tasteOf(Blueberry()) => Bad() 18 | 19 | syntax MyBool ::= "myNotBool" KItem "alma" KItem "cica" [function, total] 20 | | "myTrue" 21 | | "myFalse" 22 | 23 | rule myNotBool myTrue alma myTrue cica => myFalse 24 | rule myNotBool _ alma _ cica => myTrue 25 | 26 | endmodule 27 | -------------------------------------------------------------------------------- /koreimport/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "koreimport" 3 | version = "0.1.0" 4 | description = "An importer from Kore to ml-in-coq" 5 | 6 | authors = [ 7 | {name = "Jan Tušil", email = "jenda.tusil@gmail.com"}, 8 | ] 9 | 10 | [build-system] 11 | requires = ["setuptools"] 12 | build-backend = "setuptools.build_meta" 13 | 14 | [project.scripts] 15 | koreimport = "koreimport.__main__:main" 16 | 17 | [tool.pytest.ini_options] 18 | addopts = [ 19 | "--import-mode=importlib", 20 | ] 21 | pythonpath = ["src"] 22 | log_cli = true 23 | log_cli_format = "%(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)" 24 | log_cli_date_format = "%Y-%m-%d %H:%M:%S" 25 | -------------------------------------------------------------------------------- /matching-logic-doc/Makefile: -------------------------------------------------------------------------------- 1 | PATH_TO_COMPILED_LIBRARY ?= ../matching-logic 2 | DOCDIR ?= /usr/share 3 | 4 | default: coqdoc 5 | #default: snippets coqdoc alectryon 6 | 7 | 8 | coqdoc: doc/coqdoc 9 | 10 | doc/coqdoc: 11 | mkdir -p doc/coqdoc 12 | find $(PATH_TO_COMPILED_LIBRARY) -name \*.v \ 13 | | xargs coqdoc --utf8 --parse-comments --no-index --lib-name "File" -toc -html -gallina --external https://plv.mpi-sws.org/coqdoc/stdpp/ stdpp \ 14 | -d doc/coqdoc 15 | 16 | 17 | install-coqdoc: doc/coqdoc 18 | install -d $(DOCDIR)/$(INSTALLCOQDOCROOT)/doc/coqdoc/ 19 | $(HIDE)for i in doc/coqdoc/*; do \ 20 | dest="$(DOCDIR)/$(INSTALLCOQDOCROOT)/$$i";\ 21 | install -m 0644 "$$i" "$$dest";\ 22 | echo INSTALL "$$i" "$$dest";\ 23 | done 24 | 25 | alectryon: doc/alectryon 26 | 27 | doc/alectryon: 28 | mkdir -p doc/alectryon 29 | find $(PATH_TO_COMPILED_LIBRARY) -name \*.v \ 30 | | parallel -j+0 --joblog paralel.log --halt-on-error 2 --ungroup -v -- ./run_alectryon.sh "$(PATH_TO_COMPILED_LIBRARY)" 31 | 32 | snippets: doc/snippets 33 | 34 | doc/snippets: 35 | mkdir -p doc/snippets 36 | # python ./movies/extract_snippets.py --output-dir doc/snippets -R $(PATH_TO_COMPILED_LIBRARY) MatchingLogic $(PATH_TO_COMPILED_LIBRARY)/Pattern.v 37 | find $(PATH_TO_COMPILED_LIBRARY) -name \*.v \ 38 | | parallel -j+0 --joblog paralel.log --halt-on-error 2 --ungroup -v -- \ 39 | python ./movies/extract_snippets.py --output-dir doc/snippets -R $(PATH_TO_COMPILED_LIBRARY) MatchingLogic 40 | 41 | install-snippets: doc/snippets 42 | install -d $(DOCDIR)/$(INSTALLCOQDOCROOT)/doc/snippets 43 | $(HIDE)for i in doc/snippets/*; do \ 44 | dest="$(DOCDIR)/$(INSTALLCOQDOCROOT)/$$i";\ 45 | install -d "$$i" "$$dest";\ 46 | echo INSTALL "$$i" "$$dest";\ 47 | done 48 | $(HIDE)for i in doc/snippets/*/*; do \ 49 | dest="$(DOCDIR)/$(INSTALLCOQDOCROOT)/$$i";\ 50 | install -m 0644 "$$i" "$$dest";\ 51 | echo INSTALL "$$i" "$$dest";\ 52 | done 53 | 54 | install-alectryon: doc/alectryon 55 | install -d $(DOCDIR)/$(INSTALLCOQDOCROOT)/doc/alectryon/ 56 | $(HIDE)for i in doc/alectryon/*; do \ 57 | dest="$(DOCDIR)/$(INSTALLCOQDOCROOT)/$$i";\ 58 | install -m 0644 "$$i" "$$dest";\ 59 | echo INSTALL "$$i" "$$dest";\ 60 | done 61 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/Makefile: -------------------------------------------------------------------------------- 1 | export coq_root := ../../theories 2 | export snippets_root := ./snippets 3 | assets_root := $(snippets_root)/assets 4 | 5 | include config.mk 6 | 7 | default: all 8 | 9 | targets.mk: gen_targets.py 10 | @$(PYTHON) gen_targets.py "$(coq_root)" "$(snippets_root)" > "$@" 11 | 12 | include targets.mk 13 | 14 | .PHONY: all clean 15 | 16 | all: $(targets) 17 | @$(PYTHON) ./driver.py --frontend coq --backend assets --output-directory $(assets_root) - 18 | 19 | clean: 20 | rm -fr $(snippets_root) 21 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/Readme.md: -------------------------------------------------------------------------------- 1 | # Snippets coq+rst 2 | 3 | The script `extract_snippets.py` extract snippets block in coq+rst files.\ 4 | This script has been tested with Python 3.7 or above and uses [Alectryon](https://github.com/cpitclaudel/alectryon), 5 | to transform "coq+rst" to "latex" file. 6 | 7 | ## Requirements 8 | 9 | This script requires Alectryon 1.4. 10 | 11 | To get it, you may run `pip install -r requirements.txt` or 12 | `nix-shell` (at the root of the project). 13 | 14 | 15 | 16 | ## Snippet Block 17 | A snippet blocs is a block formed by this template: 18 | ```coq 19 | (* begin snippet NAME *) 20 | ... 21 | (* end snippet NAME *) 22 | ``` 23 | 24 | ## Script 25 | 26 | The script take coq file, extract snippets blocks, and make directory with name of coq file. 27 | Make latex files with name of snippets, in directory. 28 | Now you can include your snippet file in your main latex file (using `\input{foo/snippet1}` in LaTeX). 29 | 30 | ## Usage 31 | ```shell 32 | $ python extract_snippets.py foo.v 33 | $ ls -l foo/ 34 | snippet1.tex snippet2.tex 35 | ``` 36 | 37 | For more informations do `python extract_snippets -h` 38 | 39 | 40 | ## Makefile 41 | Command `make file.v` extracts `.v` found in `theories/oridinals` and makes a latex file. \ 42 | And extract snippets and in directory snippets. 43 | 44 | ## Other 45 | Based on [coq-community/hydra-batless](https://github.com/coq-community/hydra-battles/tree/bef8539a16e6f3c022e429640be4a99e2abc3d56) 46 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/config.mk: -------------------------------------------------------------------------------- 1 | PYTHON ?= python3 2 | 3 | coq_flags := \ 4 | -R $(coq_root)/ordinals hydras \ 5 | -R $(coq_root)/additions additions \ 6 | -R $(coq_root)/gaia gaia_hydras 7 | 8 | alectryon_flags := \ 9 | --frontend coq --backend snippets-hydras $(coq_flags) 10 | 11 | driver := $(dir $(lastword $(MAKEFILE_LIST)))/driver.py 12 | 13 | alectryon = \ 14 | $(PYTHON) $(driver) $(alectryon_flags) --output-directory "$@" 15 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/driver.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import re 3 | from collections import namedtuple 4 | from itertools import zip_longest, groupby 5 | from pathlib import Path 6 | 7 | from alectryon import cli, transforms 8 | from alectryon.latex import ASSETS 9 | 10 | def pair(*iterable): 11 | iters = [iter(iterable)] * 2 12 | return zip_longest(*iters, fillvalue=None) 13 | 14 | Snippet = namedtuple("Snippet", "name io_annots s") 15 | 16 | SNIPPET_DELIM_RE = re.compile(r""" 17 | [(][*]\s* 18 | (?Pbegin|end)\s+ snippet\s+ (?P[^ ]+) 19 | (?:[:][:]\s+ (?P.*?))? 20 | \s*[*][)] 21 | """, re.VERBOSE) 22 | 23 | SNIPPET_IO_FLAGS_RE = re.compile(r""" 24 | (?:\n\s*)? # As if flags were at end of last non-empty line 25 | [(][*][|]\s* 26 | (?:..\s+ coq::\s+ (.*?))? 27 | \s*[|]?[*][)] 28 | """, re.VERBOSE) 29 | 30 | class NoSnippets(Exception): 31 | pass 32 | 33 | def check_snippet_boundaries(before, after): 34 | assert before 35 | if not after: 36 | MSG = "Missing final ``(* end snippet {} *)`` delimiter" 37 | raise ValueError(MSG.format(before.group("before_name"))) 38 | if before.group("kind") != "begin": 39 | raise ValueError("Unexpected delimiter ``{}``".format(before.group())) 40 | if after.group("kind") != "end": 41 | raise ValueError("Unexpected delimiter ``{}``".format(before.group())) 42 | if before.group("name") != after.group("name"): 43 | MSG = "Mismatched delimiters: (* begin snippet {} *) and (* end snippet {} *)" 44 | raise ValueError(MSG.format(before.group("name"), after.group("name"))) 45 | 46 | def split_snippet(name, io_flags, contents): 47 | for substr, subsnippet in pair(io_flags, *SNIPPET_IO_FLAGS_RE.split(contents)): 48 | io_annots = transforms.read_all_io_flags(substr or "") 49 | yield Snippet(name, io_annots, subsnippet) 50 | 51 | def parse_coq_snippets(coq, ctx): 52 | end, chunks = 0, [] 53 | for before, after in pair(*SNIPPET_DELIM_RE.finditer(coq)): 54 | check_snippet_boundaries(before, after) 55 | if before.start() > end: 56 | chunks.append(coq[end:before.start()]) 57 | name, io_flags = before.group("name", "io_flags") 58 | chunks.extend(split_snippet(name, io_flags, coq[before.end():after.start()])) 59 | end = after.end() 60 | if not chunks: 61 | raise NoSnippets() 62 | if end < len(coq): 63 | chunks.append(coq[end:]) 64 | ctx["chunks"] = chunks 65 | return [(c.s if isinstance(c, Snippet) else c) for c in chunks] 66 | 67 | def _prepare_snippets(annotated, chunks): 68 | for chunk, frs in zip(chunks, annotated): 69 | if isinstance(chunk, Snippet): 70 | frs = transforms.inherit_io_annots(frs, chunk.io_annots) 71 | yield chunk, list(frs) 72 | 73 | def prepare_snippets(annotated, chunks, ctx): 74 | ctx["snippets"], annotated = zip(*_prepare_snippets(annotated, chunks)) 75 | return annotated 76 | 77 | def drop_hidden(annotated, snippets): 78 | for snippet, frs in zip(snippets, annotated): 79 | yield [] if transforms.all_hidden(frs, snippet.io_annots) else frs 80 | 81 | def _group_subsnippets(annotated, snippets): 82 | for name, group in groupby(zip(snippets, annotated), lambda p: p[0].name): 83 | frs = transforms.coalesce_text(fr for _, frs in group for fr in frs) 84 | yield name, list(frs) 85 | 86 | def group_subsnippets(annotated, snippets, ctx): 87 | ctx["names"], annotated = zip(*_group_subsnippets(annotated, snippets)) 88 | return annotated 89 | 90 | def trim_annotated(annotated): 91 | for frs in annotated: 92 | yield transforms.strip_text(frs) 93 | 94 | def write_snippets(latex, names, fpath, output_directory): 95 | for name, ltx in zip(names, latex): 96 | target = (Path(output_directory) / name).with_suffix(".tex") 97 | print(">> {} → {}".format(fpath, target)) 98 | target.write_text(ltx.render()) 99 | 100 | def record_assets(v, assets): 101 | cli._record_assets(assets, ASSETS.PATH, ASSETS.ALECTRYON_STY + ASSETS.PYGMENTS_STY) 102 | return v 103 | 104 | cli.PIPELINES['coq']['snippets-hydras'] = ( 105 | cli.read_plain, parse_coq_snippets, cli.annotate_chunks, prepare_snippets, 106 | # Transforms applied twice: once to prepare comments for drop_hidden, once 107 | # to add comments and newlines to sentences after grouping subsnippets. 108 | cli.apply_transforms, drop_hidden, group_subsnippets, 109 | cli.apply_transforms, trim_annotated, cli.gen_latex_snippets, write_snippets 110 | ) 111 | 112 | cli.PIPELINES['coq']['assets'] = (record_assets, cli.copy_assets) 113 | 114 | if __name__ == '__main__': 115 | try: 116 | cli.main() 117 | except NoSnippets: 118 | pass 119 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from extract_snippets.cli import main 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | sys.exit(main()) 7 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/Extractor.py: -------------------------------------------------------------------------------- 1 | import re 2 | from typing import AnyStr, Iterable, List, Match 3 | 4 | from .Reader import Reader 5 | from .Snippet import Snippet 6 | from .snippetExceptions import \ 7 | SnippetAlreadyCloseException, \ 8 | SnippetAlreadyExistException, \ 9 | SnippetNotBeginException, \ 10 | SnippetNotEndWarning 11 | 12 | BEGIN_STATE = "begin" 13 | END_STATE = "end" 14 | STATES_GROUP = fr"({BEGIN_STATE}|{END_STATE})" 15 | NAME_GROUP = r"(\w+)" 16 | 17 | LATEX_TAG_PATTERN = re.compile(rf"\s*\\{STATES_GROUP}(\[.*\])?{{{NAME_GROUP}}}(.*)") # "\s*(\[.*])\\(begin|end){(\w+)}" 18 | SNIPPET_PATTERN = re.compile(rf".*\\PY{{c}}{{\(\*\~*{STATES_GROUP}\~+snippet\~+{NAME_GROUP}\~*\*\)}}") 19 | 20 | 21 | class SnippetExtractor: 22 | def __init__(self, reader: Reader): 23 | self.reader = reader 24 | self.__snippet_open = {} 25 | self.__snippet_close = [] 26 | self.stack_tag = [] 27 | 28 | @staticmethod 29 | def _list_names(snippets: Iterable[Snippet]) -> Iterable[str]: 30 | """ 31 | get list of name sinppets 32 | :param snippets: list of snipepts 33 | :return: itterable 34 | """ 35 | return map(lambda snippet: snippet.name, snippets) 36 | 37 | def _match_tag(self, match: Match[AnyStr], line_num: int) -> None: 38 | statement, _, tag, after = match.groups() 39 | if statement == BEGIN_STATE: 40 | self.stack_tag.append(tag) 41 | match = LATEX_TAG_PATTERN.match(after) 42 | if match is not None: 43 | self._match_tag(match, line_num) 44 | 45 | else: 46 | last_tag = self.stack_tag.pop() 47 | if last_tag != tag: 48 | raise Exception(f"tag '{tag}' close before '{last_tag}' at line {line_num}.") 49 | 50 | def _open_snippet(self, snippet_name: str, line_number: int) -> None: 51 | """ 52 | check if new snippet not already exist 53 | and open snippet 54 | 55 | :param snippet_name: name to check 56 | :param line_number: line number found this name 57 | :raise: SnippetAlreadyExistException if already open or close 58 | """ 59 | # check 60 | if snippet_name in self._list_names(self.__snippet_close) or \ 61 | snippet_name in self._list_names(self.__snippet_open.values()): 62 | raise SnippetAlreadyExistException(snippet_name, line_number) 63 | 64 | # add snippet in open dict 65 | self.__snippet_open[snippet_name] = Snippet(snippet_name, self.stack_tag) 66 | 67 | def _close_snippet(self, snippet_name: str, line_number: int) -> None: 68 | """ 69 | check if snippet not already closed or 70 | snippet close in open snippets 71 | and close snippet 72 | 73 | :param snippet_name: name to check 74 | :param line_number: line number found this name 75 | :raise: SnippetAlreadyCloseException if exist in close 76 | :raise: SnippetNotExistException if not in open 77 | """ 78 | # check 79 | if snippet_name in self._list_names(self.__snippet_close): 80 | raise SnippetAlreadyCloseException(snippet_name, line_number) 81 | 82 | elif snippet_name not in self._list_names(self.__snippet_open.values()): 83 | raise SnippetNotBeginException(snippet_name, line_number) 84 | 85 | # move snippet open dict to close list 86 | snippet = self.__snippet_open.pop(snippet_name) 87 | snippet.close(self.stack_tag) 88 | self.__snippet_close.append(snippet) 89 | 90 | def _match_snippet(self, match: Match[AnyStr], line_num: int): 91 | """ 92 | call if match snippet, to open or close snippet 93 | 94 | :param statement: 95 | :param snippet_name: 96 | :param line_num: 97 | :return: 98 | """ 99 | statement, snippet_name = match.groups() 100 | if statement == BEGIN_STATE: 101 | self._open_snippet(snippet_name, line_num) 102 | else: # end state 103 | self._close_snippet(snippet_name, line_num) 104 | 105 | def _add_snippets_open(self, line: str): 106 | for snippet in self.__snippet_open.values(): 107 | snippet.add_content(line) 108 | 109 | def extract(self) -> List[Snippet]: 110 | """ 111 | run extract snippets 112 | :return: snippets 113 | """ 114 | 115 | for num, line in self.reader: 116 | match = LATEX_TAG_PATTERN.match(line) 117 | if match is not None: 118 | self._match_tag(match, line_num=num) 119 | 120 | else: 121 | match = SNIPPET_PATTERN.match(line) 122 | if match is not None: 123 | self._match_snippet(match, line_num=num) 124 | continue 125 | 126 | self._add_snippets_open(line) 127 | 128 | # warning if all snippet not closed 129 | if self.__snippet_open: 130 | raise SnippetNotEndWarning(*self.__snippet_open.values()) 131 | 132 | return self.snippets 133 | 134 | @property 135 | def snippets(self): 136 | return self.__snippet_close 137 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/Reader.py: -------------------------------------------------------------------------------- 1 | from typing import Tuple 2 | from abc import abstractmethod 3 | 4 | 5 | class Reader: 6 | """ 7 | Read line by line 8 | """ 9 | 10 | @abstractmethod 11 | def __iter__(self) -> Tuple[int, str]: 12 | """ 13 | return tuple with line number and line 14 | :yield: 15 | """ 16 | pass 17 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/Snippet.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | from .docutils import LATEX_TAG_BEGIN_FORMAT, LATEX_TAG_END_FORMAT 4 | from .snippetExceptions import SnippetException 5 | 6 | 7 | class Snippet: 8 | BEGIN_TEMPLATE = LATEX_TAG_BEGIN_FORMAT 9 | END_TEMPLATE = LATEX_TAG_END_FORMAT 10 | INDENT = " " 11 | 12 | def __init__(self, name: str, tags=[]): 13 | self.__name = name 14 | self.content = "" 15 | self._add_tags(self.BEGIN_TEMPLATE, tags) 16 | self.open = True 17 | 18 | @property 19 | def name(self) -> str: 20 | """ 21 | name of snippet 22 | :return: str 23 | """ 24 | return self.__name 25 | 26 | def add_content(self, content_to_add: str) -> None: 27 | """ 28 | add new line to content 29 | 30 | :param content_to_add: content added 31 | :return: None 32 | """ 33 | if self.is_close(): 34 | raise SnippetException(f"Snippet {self.name} already closed.") 35 | self.content += content_to_add 36 | 37 | def _add_tags(self, template: str, tags: List[str], reverse: bool = False): 38 | indent_func = lambda i: self.INDENT * i 39 | if reverse: 40 | max_i = len(tags) - 1 41 | indent_func = lambda i: self.INDENT * (max_i - i) 42 | tags = reversed(tags) 43 | 44 | self.content += "\n".join(indent_func(i) + template.format(tag=tag) for i, tag in enumerate(tags)) + "\n" 45 | 46 | def close(self, tags: List[str]) -> None: 47 | """ 48 | close snippet 49 | """ 50 | self._add_tags(self.END_TEMPLATE, tags, reverse=True) 51 | self.open = False 52 | 53 | def is_close(self) -> bool: 54 | """ 55 | True if Snippet is closed 56 | :return: bool 57 | """ 58 | return not self.open 59 | 60 | def __str__(self) -> str: 61 | return self.content 62 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/harp-project/AML-Formalization/b1da1484bd73fd81dde4d331d5fbf64e55951d17/matching-logic-doc/movies/extract_snippets/__init__.py -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | from pathlib import Path 3 | 4 | 5 | def build_parser() -> argparse.ArgumentParser: 6 | """ 7 | build parser 8 | 9 | :return: Argument parser 10 | """ 11 | DESCRIPTION = "Extract snippet in coq file (.v) generate by alectryon." 12 | parser = argparse.ArgumentParser(DESCRIPTION) 13 | 14 | INPUT_FILES_HELP = "coq file '.v'" 15 | parser.add_argument("input", 16 | type=Path, 17 | help=INPUT_FILES_HELP) 18 | 19 | OUPUT_DIR_HELP = "output directory" 20 | parser.add_argument("-o", "--output-dir", 21 | default=Path("."), 22 | type=Path, 23 | help=OUPUT_DIR_HELP) 24 | 25 | DUMP_LATEX_HELP = "dump latex complete file (usefull to debug)" 26 | parser.add_argument("-d", "--dump-complete-latex", 27 | action="store_true", 28 | help=DUMP_LATEX_HELP) 29 | 30 | DUMP_LATEX_DIR_HELP = "directory to dump complete latex" \ 31 | "file (please active flag '--dump-complete-latex')" 32 | parser.add_argument("-D", "--dump-complete-latex-dir", 33 | type=Path, 34 | default=Path("."), 35 | help=DUMP_LATEX_DIR_HELP) 36 | 37 | # serapi (copy from alectryon.cli) 38 | SUBP_HELP = "Pass arguments to the SerAPI process" 39 | subp = parser.add_argument_group("Subprocess arguments", SUBP_HELP) 40 | 41 | SERTOP_ARGS_HELP = "Pass a single argument to SerAPI (e.g. -Q dir,lib)." 42 | subp.add_argument("--sertop-arg", dest="sertop_args", 43 | action="append", default=[], 44 | metavar="SERAPI_ARG", 45 | help=SERTOP_ARGS_HELP) 46 | 47 | I_HELP = "Pass -I DIR to the SerAPI subprocess." 48 | subp.add_argument("-I", "--ml-include-path", dest="coq_args_I", 49 | metavar="DIR", nargs=1, action="append", 50 | default=[], help=I_HELP) 51 | 52 | Q_HELP = "Pass -Q DIR COQDIR to the SerAPI subprocess." 53 | subp.add_argument("-Q", "--load-path", dest="coq_args_Q", 54 | metavar=("DIR", "COQDIR"), nargs=2, action="append", 55 | default=[], help=Q_HELP) 56 | 57 | R_HELP = "Pass -R DIR COQDIR to the SerAPI subprocess." 58 | subp.add_argument("-R", "--rec-load-path", dest="coq_args_R", 59 | metavar=("DIR", "COQDIR"), nargs=2, action="append", 60 | default=[], help=R_HELP) 61 | 62 | EXPECT_UNEXPECTED_HELP = "Ignore unexpected output from SerAPI" 63 | parser.add_argument("--expect-unexpected", action="store_true", 64 | default=False, help=EXPECT_UNEXPECTED_HELP) 65 | 66 | return parser 67 | 68 | 69 | def post_process_arguments(args: argparse.Namespace) -> argparse.Namespace: 70 | """ 71 | post process sertop arguments 72 | 73 | :param args: args parsed 74 | :return: new name space 75 | """ 76 | for dirpath in args.coq_args_I: 77 | args.sertop_args.extend(("-I", dirpath)) 78 | for pair in args.coq_args_R: 79 | args.sertop_args.extend(("-R", ",".join(pair))) 80 | for pair in args.coq_args_Q: 81 | args.sertop_args.extend(("-Q", ",".join(pair))) 82 | 83 | return args 84 | 85 | 86 | def parse_args() -> argparse.Namespace: 87 | """ 88 | parse argument 89 | 90 | :return: Namespace structure 91 | """ 92 | args = build_parser().parse_args() 93 | return post_process_arguments(args) 94 | 95 | 96 | EXTENSION_LATEX = ".tex" 97 | 98 | 99 | def get_path_latex(output_dir: Path, name: str): 100 | return output_dir / (name + EXTENSION_LATEX) 101 | 102 | 103 | def make_latex_file(content: str, path: Path): 104 | path.parent.mkdir(parents=True, exist_ok=True) 105 | with open(path, 'w') as file: 106 | file.write(content) 107 | 108 | 109 | def make_latex(input_file: Path, sertop_args): 110 | from .Extractor import SnippetExtractor 111 | from .docutils import CoqToLatexReader, register_docutils 112 | print(f"Convert '{input_file}' to latex.") 113 | register_docutils(sertop_args) 114 | reader = CoqToLatexReader(input_file) 115 | return SnippetExtractor(reader), reader 116 | 117 | 118 | def copy_asset(output_dir: Path, dir_name='assets'): 119 | from alectryon.cli import copy_assets 120 | from alectryon.latex import ASSETS 121 | from shutil import copy 122 | 123 | STY = ASSETS.ALECTRYON_STY + ASSETS.PYGMENTS_STY 124 | assets = [(ASSETS.PATH, asset) for asset in STY] 125 | 126 | output_dir = output_dir / dir_name 127 | output_dir.mkdir(exist_ok=True) 128 | 129 | copy_assets(None, assets, copy, output_dir) 130 | print(f"copy assets {STY} in {output_dir}") 131 | 132 | 133 | def main(): 134 | args = parse_args() 135 | input_name = args.input.stem 136 | output_dir = args.output_dir / input_name 137 | 138 | snippet_extractor, reader = make_latex(args.input, args.sertop_args) 139 | 140 | if reader.exit_code > 0: 141 | return reader.exit_code 142 | 143 | # dump latex to debug 144 | if args.dump_complete_latex: 145 | path_latex = get_path_latex(args.dump_complete_latex_dir, 146 | input_name) 147 | print(f"Make complete latex file {path_latex}.") 148 | make_latex_file(reader.content_latex, path_latex) 149 | 150 | # write snippets files 151 | print("Extract snippets.") 152 | snippets = snippet_extractor.extract() 153 | for snippet in snippets: 154 | path = get_path_latex(output_dir, snippet.name) 155 | print(f"extract snippet '{snippet.name}', dump file {path}.") 156 | make_latex_file(str(snippet), path) 157 | 158 | if snippets: 159 | copy_asset(args.output_dir) 160 | 161 | return 0 162 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/docutils.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from .Reader import Reader 4 | 5 | 6 | LATEX_TAG_BEGIN_FORMAT = "\\begin{{{tag}}}" 7 | LATEX_TAG_END_FORMAT = "\\end{{{tag}}}" 8 | 9 | def register_docutils(sertop_args): 10 | """ 11 | setup docutils 12 | :param sertop_args: sertop arguments to used 13 | :return: 14 | """ 15 | import alectryon.docutils 16 | alectryon.docutils.AlectryonTransform.SERTOP_ARGS = sertop_args 17 | alectryon.docutils.LONG_LINE_THRESHOLD = 88 18 | alectryon.docutils.setup() 19 | 20 | 21 | def coq_rst_to_latex(source: str) -> str: 22 | """ 23 | convert coq content to latex (please setup doctutils with register_docutils before) 24 | (function inspired by `_gen_docutils` in alectryon cli) 25 | :param source: source to convert 26 | :return: Exit code (int) and output (str). 27 | """ 28 | from docutils.core import publish_string 29 | from docutils.readers.standalone import Reader 30 | from alectryon.cli import _gen_docutils 31 | from alectryon.docutils import LuaLatexWriter, RSTCoqParser as Parser 32 | 33 | settings_overrides = { 34 | 'traceback': True, 35 | 'embed_stylesheet': False, 36 | 'stylesheet_path': None, 37 | 'stylesheet_dirs': [], 38 | 'alectryon_banner': False, 39 | 'alectryon_vernums': False, 40 | 'input_encoding': 'utf-8', 41 | 'output_encoding': 'utf-8', 42 | 'exit_status_level': 3, 43 | } 44 | 45 | output, _pub, exit_code = \ 46 | _gen_docutils(source, None, 47 | Parser, Reader, LuaLatexWriter, 48 | settings_overrides) 49 | 50 | return exit_code, output 51 | 52 | class CoqToLatexReader(Reader): 53 | DOCUMENT_BEGIN = LATEX_TAG_BEGIN_FORMAT.format(tag="document") 54 | DOCUMENT_END = LATEX_TAG_END_FORMAT.format(tag="document") 55 | 56 | def __init__(self, path_coq: Path): 57 | with open(path_coq, 'r') as file: 58 | self.content_coq = file.read() 59 | self.exit_code, self.content_latex = coq_rst_to_latex(self.content_coq) 60 | 61 | def __iter__(self): 62 | start = False 63 | for num, line in enumerate(self.content_latex.split('\n'), 1): 64 | if line == self.DOCUMENT_BEGIN: 65 | start = True 66 | elif line == self.DOCUMENT_END: 67 | return 68 | elif start: 69 | yield num, line + "\n" 70 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/extract_snippets/snippetExceptions.py: -------------------------------------------------------------------------------- 1 | from typing import Iterable 2 | 3 | 4 | 5 | class SnippetException(Exception): 6 | def __init__(self, prelude: str, line_number: int = None): 7 | if line_number is None: 8 | super().__init__(prelude) 9 | else: 10 | super().__init__(f"{prelude}, at line {line_number}.") 11 | 12 | 13 | class SnippetAlreadyExistException(SnippetException): 14 | """ 15 | Raise in snippet if 2 snippet with same name in file. 16 | """ 17 | 18 | def __init__(self, name_snippet: str, line_number: int): 19 | super().__init__(f"Snippet \"{name_snippet}\" already exist", line_number) 20 | 21 | 22 | class SnippetAlreadyCloseException(SnippetException): 23 | """ 24 | Raise if snippet is already close. 25 | """ 26 | 27 | def __init__(self, name_snippet: str, line_number: int): 28 | super().__init__(f"Snippet \"{name_snippet}\" already close", line_number) 29 | 30 | 31 | class SnippetNotBeginException(SnippetException): 32 | """ 33 | Raise if snippet not exist. 34 | """ 35 | 36 | def __init__(self, name_snippet: str, line_number: int): 37 | super().__init__(f"Snippet \"{name_snippet}\" not begin (cannot be closed)", line_number) 38 | 39 | 40 | class SnippetNotEndWarning(Warning): 41 | """ 42 | Raise if snippet is have not end. 43 | """ 44 | 45 | def __init__(self, *snippets: Iterable['Snippet']): 46 | names = ",".join(snippet.name for snippet in snippets) 47 | super().__init__(f"Snippets \"{names}\" never close") 48 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/gen_targets.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | from os import getenv 3 | from pathlib import Path 4 | 5 | RULE = """ 6 | {}: $(coq_root)/{} 7 | $(alectryon) "$<" 8 | @touch "$@" 9 | """ 10 | 11 | targets = [] 12 | root = Path(getenv("coq_root")) 13 | 14 | for coqfile in root.glob('**/*.v'): 15 | relpath = coqfile.relative_to(root) 16 | target = "$(snippets_root)/{}/".format(relpath.stem) 17 | targets.append(target) 18 | print(RULE.format(target, relpath)) 19 | 20 | print("targets := {}".format(" ".join(str(t) for t in targets))) 21 | -------------------------------------------------------------------------------- /matching-logic-doc/movies/requirements.txt: -------------------------------------------------------------------------------- 1 | alectryon >=1.4.0 2 | -------------------------------------------------------------------------------- /matching-logic-doc/run_alectryon.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | path_to_compiled_library="$1" 4 | source_filename="$2" 5 | 6 | stripped_filename="${source_filename#${path_to_compiled_library}}" 7 | base_out_dir="doc/alectryon/" 8 | out_dir="$base_out_dir/$(dirname "$stripped_filename")" 9 | 10 | 11 | set -x 12 | mkdir -p "$out_dir" 13 | alectryon -R "$path_to_compiled_library" MatchingLogic \ 14 | --traceback \ 15 | --frontend coq \ 16 | --backend webpage \ 17 | --output-directory "$base_out_dir" \ 18 | --copy-assets none \ 19 | --output "$base_out_dir/$stripped_filename.html" \ 20 | "$source_filename" 21 | 22 | -------------------------------------------------------------------------------- /matching-logic/Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | install: Makefile.coq 5 | @+$(MAKE) -f Makefile.coq install 6 | 7 | clean: Makefile.coq 8 | @+$(MAKE) -f Makefile.coq cleanall 9 | @rm -f Makefile.coq Makefile.coq.conf 10 | 11 | Makefile.coq: _CoqProject 12 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 13 | 14 | force _CoqProject Makefile: ; 15 | 16 | %: Makefile.coq force 17 | @+$(MAKE) -f Makefile.coq $@ 18 | 19 | .PHONY: all clean force install 20 | -------------------------------------------------------------------------------- /matching-logic/README.md: -------------------------------------------------------------------------------- 1 | # A Coq Formalization of Matching logic 2 | 3 | This library contains an embedding of matching logic in the Coq proof system, using the locally-nameless representation. 4 | 5 | [Generated html files of the latest version.](https://harp-project.github.io/AML-Formalization/branch/master/coqdoc/ toc.html) 6 | 7 | ## Structure of the source files 8 | 9 | All Coq source files are in the directory `src/`. 10 | The structure is as follows: 11 | 12 | First, we have some general utilities. 13 | - [`Utils/`](src/Utils/) - A collection of generally useful definitions and lemmas, independent of matching logic: 14 | - [`Lattice.v`](src/Utils/Lattice.v) - formalization of complete lattices and Knaster-Tarski theorem. 15 | - [`stdpp_ext.v`](src/Utils/stdpp_ext.v) - an extension to the stdpp library. 16 | - [`extralibrary.v`](src/Utils/extralibrary.v) - generally useful lemmas and tactics 17 | 18 | Second, we have things related to matching logic syntax. 19 | - [`Signature.v`](src/Signature.v) - type classes representing matching logic signatures 20 | - [`StringSignature.v`](src/StringSignature.v) - a particular, string-based, implementation of a signature 21 | - [`Pattern.v`](src/Pattern.v) - matching logic patterns and their well-formedness constraints 22 | - [`Freshness.v`](src/Freshness.v) - fresh variable generation and related lemmas and tactics 23 | - [`Substitution.v`](src/Substitution.v) - all kinds of substitutions and related lemmas 24 | - [`IndexManipulation.v`](src/IndexManipulation.v) - operations and theorems about manipulating dangling de Bruijn indices 25 | - [`ApplicationContext.v`](src/ApplicationContext.v) - application contexts (contexts consisting only of applications) 26 | - [`PatternContext.v`](src/PatternContext.v) - generic, pattern-based contexts 27 | - [`SyntacticConstruct.v`](src/SyntacticConstruct.v) - type classes for extending the syntax and defining syntactic sugar 28 | - [`NamedAxioms.v`](src/NamedAxioms.v) a way how to give (parameterized) names to axioms of matching logic theories 29 | - [`SyntaxLemmas/`](src/SyntaxLemmas/) - various lemmas about syntax that require reasoning about more then one component: 30 | - [`ApplicationCtxSubstitution.v`](src/SyntaxLemmas/ApplicationCtxSubstitution.v) - lemmas combining application contexts and substitution 31 | - [`FreshnessApplicationCtx.v`](src/SyntaxLemmas/FreshnessApplicationCtx.v) - lemmas combining application contexts and freshness 32 | - [`FreshnessSubstitution.v`](src/SyntaxLemmas/FreshnessSubstitution.v) - lemmas combining freshness and substitutions 33 | - [`PatternCtxApplicationCtx.v`](src/SyntaxLemmas/PatternCtxApplicationCtx.v) - lemmas about conversion between generic pattern contexts and application contexts 34 | - [`Syntax.v`](src/Syntax.v) - remaining stuff about syntax 35 | - [`DerivedOperators_Syntax.v`](src/DerivedOperators_Syntax.v) - syntax of basic derived operators (e.g., `and`, `nu`, ...) 36 | - [`wftactics.v`](src/wftactics.v) - tactics for reasoning about well-formedness of patterns, and simplifying patterns 37 | 38 | Third, we have things related to matching logic semantics. 39 | - [`Semantics.v`](src/Semantics.v) - definitions of models and semantics 40 | - [`DerivedOperators_Semantics.v`](src/DerivedOperators_Semantics.v) - semantics of derived operators 41 | - [`PrePredicate.v`](src/PrePredicate.v) - helper definitions and lemmas for reasoning about predicate patterns 42 | - [`monotonic.v`](src/monotonic.v) - a proof that well-formed patterns give rise to monotonic functions; important for `mu` 43 | - [`FixpointReasoning.v`](src/FixpointReasoning.v) - additional content on reasoning about the semantics of fixpoint patterns 44 | - [`ModelIsomorphism.v`](src/ModelIsomorphism.v) - definition of model isomorphisms; proof that model isomorphism preserves the semantics of patterns 45 | 46 | The entire syntax and semantics of the logic can be used by importing [`Logic.v`](src/Logic.v), which exports the previous modules. 47 | 48 | Fourth, we have things related to matching logic proof system. 49 | - [`ProofSystem.v`](src/ProofSystem.v) - the definition of the proof system and its basic properties 50 | - [`ProofSystemSoundness.v`](src/ProofSystemSoundness.v) - soundness of the proof system, connecting it with the semantics 51 | - [`BasicProofSystemLemmas.v`](src/BasicProofSystemLemmas.v) - proofs using the proofsystem that are independent of the proof mode 52 | - [`ProofInfo.v`](src/ProofInfo.v) - includes theorems for reasoning about static proof information 53 | 54 | Fifth, we have a number of theorems proved with the proof system and the _Coq proof mode for matching logic_. 55 | - [`ProofMode/`](src/ProofMode/) 56 | - [`Basics.v`](src/ProofMode/Basics.v) - describes the notations of the matching logic proof mode 57 | - [`Propositional.v`](src/ProofMode/Propositional.v) - includes theorems about the validity of propositional patterns 58 | - [`Firstorder.v`](src/ProofMode/Firstorder.v) - includes theorems about the validity of first-order patterns 59 | - [`FixPoint.v`](src/ProofMode/FixPoint.v) - includes theorems about the validity of fixpoint patterns 60 | - [`Reshaper.v`](src/ProofMode/Reshaper.v) - includes theorems about the reordering of implications 61 | - [`Misc.v`](src/ProofMode/Misc.v) - includes theorems about the validity of other kinds of patterns 62 | - [`MLPM.v`](src/ProofMode/MLPM.v) - collects the utilities of the proof mode 63 | 64 | Sixth, we have matching logic theories. 65 | - [`Theories/`](src/Theories/) 66 | - [`Definedness_Syntax.v`](src/Theories/Definedness_Syntax.v) - theory of definedness, totality, equality, inclusion, membership - syntax and axioms 67 | - [`Definedness_Semantics.v`](src/Theories/Definedness_Semantics.v) - lemmas about semantics of the above 68 | - [`Definedness_ProofSystem.v`](src/Theories/Definedness_ProofSystem.v) - proofs using the matching logic proof system about definedness and related notions 69 | - [`Sorts_Syntax.v`](src/Theories/Sorts_Syntax.v) - definition of syntax for sorts and many-sorted functions and related notions 70 | - [`Sorts_Semantics.v`](src/Theories/Sorts_Semantics.v) - the semantics of sorts, many-sorted functions, and related notions 71 | - [`Sorts_ProofSystem.v`](src/Theories/Sorts_ProofSystem.v) - proof using the matching logic proof system about sorts 72 | - [`Nat_Syntax.v`](src/Theories/Nat_Syntax.v) - the theory of natural numbers 73 | - [`Nat_ProofSystem.v`](src/Theories/Nat_ProofSystem.v) - proofs about the theory of natural numbers 74 | - [`ModelExtension.v`](src/Theories/ModelExtension.v) - definition of the "open fragment" of matching logic; semantics of formulas from this fragment is preserved when extending the model with new elements 75 | 76 | We note, that there is ongoing work on formalizing an algorithm of unification which we include in [Unification.v](src/Experimental/Unification.v). 77 | 78 | -------------------------------------------------------------------------------- /matching-logic/_CoqProject: -------------------------------------------------------------------------------- 1 | -R src MatchingLogic 2 | 3 | src/Utils/extralibrary.v 4 | src/Utils/stdpp_ext.v 5 | src/Utils/Lattice.v 6 | src/Utils/Surj.v 7 | 8 | src/Signature.v 9 | src/Pattern.v 10 | src/Substitution.v 11 | src/Freshness.v 12 | src/IndexManipulation.v 13 | src/DerivedOperators_Syntax.v 14 | src/ApplicationContext.v 15 | src/PatternContext.v 16 | 17 | src/SyntacticConstruct.v 18 | src/SyntaxLemmas/FreshnessSubstitution.v 19 | src/SyntaxLemmas/PatternCtxApplicationCtx.v 20 | src/SyntaxLemmas/FreshnessApplicationCtx.v 21 | src/SyntaxLemmas/ApplicationCtxSubstitution.v 22 | src/wftactics.v 23 | src/Syntax.v 24 | src/NamedAxioms.v 25 | 26 | src/Semantics.v 27 | src/monotonic.v 28 | src/ModelIsomorphism.v 29 | src/PrePredicate.v 30 | src/DerivedOperators_Semantics.v 31 | 32 | src/ProofSystem.v 33 | src/ProofSystemSoundness.v 34 | src/FixpointReasoning.v 35 | src/StringSignature.v 36 | src/ProofInfo.v 37 | src/Logic.v 38 | 39 | src/FreshnessManager.v 40 | 41 | src/BasicProofSystemLemmas.v 42 | src/ProofMode/Basics.v 43 | src/ProofMode/Propositional.v 44 | src/ProofMode/Firstorder.v 45 | src/ProofMode/FixPoint.v 46 | src/ProofMode/Reshaper.v 47 | src/ProofMode/Misc.v 48 | src/ProofMode/MLPM.v 49 | 50 | 51 | src/Theories/Definedness_Syntax.v 52 | src/Theories/Definedness_Semantics.v 53 | src/Theories/Definedness_ProofSystem.v 54 | 55 | src/Theories/DeductionTheorem.v 56 | src/Theories/FOEquality_ProofSystem.v 57 | src/Theories/Subseteq_ProofSystem.v 58 | 59 | src/Theories/Sorts_Syntax.v 60 | src/Theories/Sorts_Semantics.v 61 | src/Theories/Sorts_ProofSystem.v 62 | 63 | src/Theories/Nat_Syntax.v 64 | 65 | src/Theories/SumSort_Syntax.v 66 | 67 | src/Theories/Bool_Syntax.v 68 | src/Theories/Bool_Semantics.v 69 | src/Theories/Bool_ProofSystem.v 70 | 71 | src/Theories/ProductSort.v 72 | src/Theories/ProductSort_ProofSystem.v 73 | src/Theories/ProductSortWithLookup.v 74 | src/Theories/RecursiveSymbol.v 75 | 76 | src/Theories/ContextualImplication.v 77 | 78 | src/Theories/ModelExtension.v 79 | src/Theories/DefaultModels.v 80 | 81 | src/Tests/TEST_LocallyNameless.v 82 | src/Tests/TEST_proofmode_example.v 83 | src/Tests/TEST_proofmode_proof_size.v 84 | src/Tests/TEST_ProofMode_relative_completeness.v 85 | 86 | 87 | src/Evaluation/tutorial.v 88 | src/Evaluation/Propositional.v 89 | src/Evaluation/Rewrite.v 90 | src/Evaluation/Firstorder.v 91 | src/Evaluation/Revert_size.v 92 | src/Evaluation/Complex.v 93 | src/Evaluation/Extractor.v 94 | 95 | src/OPML/OpmlSignature.v 96 | src/OPML/OpmlPattern.v 97 | src/OPML/OpmlModel.v 98 | src/OPML/OpmlAmlRelSpec.v 99 | src/OPML/OpmlExamples.v 100 | src/OPML/GenericModel.v 101 | src/OPML/KPreludeSignatures.v 102 | 103 | src/Experimental/Nat_ProofSystem.v 104 | src/Experimental/SumSort_ProofSystem.v 105 | src/Experimental/ProofModePattern.v 106 | src/Experimental/Unification.v 107 | 108 | -------------------------------------------------------------------------------- /matching-logic/default.nix: -------------------------------------------------------------------------------- 1 | (import ( 2 | fetchTarball { 3 | url = "https://github.com/edolstra/flake-compat/archive/12c64ca55c1014cdc1b16ed5a804aa8576601ff2.tar.gz"; 4 | sha256 = "0jm6nzb83wa6ai17ly9fzpqc40wg1viib8klq8lby54agpl213w5"; } 5 | ) { 6 | src = ../.; 7 | }).defaultNix 8 | -------------------------------------------------------------------------------- /matching-logic/dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.5) 2 | (using coq 0.2) 3 | (name coq-matching-logic) 4 | -------------------------------------------------------------------------------- /matching-logic/evaluator.hs: -------------------------------------------------------------------------------- 1 | import Test 2 | 3 | toInt :: Nat -> Integer 4 | toInt O = 0 5 | toInt (S x) = 1 + toInt x 6 | 7 | instance Show Nat where 8 | show x = show $ toInt x 9 | 10 | propositional_proof_sizes = [ 11 | ("Hilbert proof", proof_prop_low), 12 | ("Low-level proof mode proof", proof_prop_pm1), 13 | ("High-level proof mode proof", proof_prop_pm2) 14 | ] 15 | 16 | rewrite_proof_sizes = [ 17 | ("Framing-based proof",proof_rew_low), 18 | ("Congruence lemma-based proof", proof_rew_pm1), 19 | ("Iterated congruence lemma-based proof", proof_rew_low3), 20 | ("mlRewriteIff lemma-based proof", proof_rew_low4), 21 | ("mlRewrite-based proof", proof_rew_pm2), 22 | ("mlRewrite-based proof opposite", proof_rew_pm3) 23 | ] 24 | 25 | fol_proof_sizes = [ 26 | ("Hilbert proof", proof_fol_low), 27 | ("Proof using only FOL proof mode", proof_fol_pm1), 28 | ("Proof mode proof", proof_fol_pm2) 29 | ] 30 | 31 | revert_proof_sizes = [ 32 | ("Derived revert",proof_derived_rev_small), 33 | ("Induction-based revert",proof_pm_rev_small), 34 | ("Derived revert with hypotheses",proof_derived_rev_big), 35 | ("Induction-based revert with hypotheses",proof_pm_rev_big) 36 | ] 37 | 38 | complex_proof_sizes = [ 39 | ("Hilbert proof", proof_complex_low), 40 | ("Proof mode proof", proof_complex_pm) 41 | ] 42 | 43 | main :: IO () 44 | main = do 45 | putStrLn ("Propositional proof: " ++ show propositional_proof_sizes) 46 | putStrLn ("Rewrite-based proof: " ++ show rewrite_proof_sizes) 47 | putStrLn ("First-order proof: " ++ show fol_proof_sizes) 48 | putStrLn ("Revert size checker proofs: " ++ show revert_proof_sizes) 49 | putStrLn ("Complex proofs: " ++ show complex_proof_sizes) -------------------------------------------------------------------------------- /matching-logic/shell.nix: -------------------------------------------------------------------------------- 1 | (import ( 2 | fetchTarball { 3 | url = "https://github.com/edolstra/flake-compat/archive/12c64ca55c1014cdc1b16ed5a804aa8576601ff2.tar.gz"; 4 | sha256 = "0jm6nzb83wa6ai17ly9fzpqc40wg1viib8klq8lby54agpl213w5"; } 5 | ) { 6 | src = ../.; 7 | }).shellNix 8 | -------------------------------------------------------------------------------- /matching-logic/src/ApplicationContext.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Pattern. 2 | 3 | Section with_signature. 4 | Context {Σ : Signature}. 5 | 6 | (* TODO make Set ? *) 7 | Inductive Application_context : Type := 8 | | box 9 | | ctx_app_l (cc : Application_context) (p : Pattern) (Prf : well_formed p) 10 | | ctx_app_r (p : Pattern) (cc : Application_context) (Prf : well_formed p) 11 | . 12 | 13 | Fixpoint AC_free_evars (AC : Application_context) : EVarSet := 14 | match AC with 15 | | box => ∅ 16 | | @ctx_app_l cc p _ => free_evars p ∪ AC_free_evars cc 17 | | @ctx_app_r p cc _ => free_evars p ∪ AC_free_evars cc 18 | end. 19 | 20 | Fixpoint subst_ctx (C : Application_context) (p : Pattern) 21 | : Pattern := 22 | match C with 23 | | box => p 24 | | @ctx_app_l C' p' prf => patt_app (subst_ctx C' p) p' 25 | | @ctx_app_r p' C' prf => patt_app p' (subst_ctx C' p) 26 | end. 27 | 28 | (* TODO rewrite using wc_sctx *) 29 | Lemma wf_sctx (C : Application_context) (A : Pattern) : 30 | well_formed A = true -> well_formed (subst_ctx C A) = true. 31 | Proof. 32 | intros H. 33 | unfold well_formed in H. 34 | apply andb_true_iff in H. destruct H as [Hwfp Hwfc]. 35 | unfold well_formed_closed in Hwfc. 36 | induction C; simpl. 37 | - unfold well_formed. rewrite Hwfp. unfold well_formed_closed. rewrite Hwfc. reflexivity. 38 | - unfold well_formed. simpl. 39 | unfold well_formed in IHC. apply andb_true_iff in IHC. destruct IHC as [IHC1 IHC2]. 40 | rewrite IHC1. simpl. 41 | unfold well_formed in Prf. apply andb_true_iff in Prf. destruct Prf as [Prf1 Prf2]. 42 | rewrite Prf1. simpl. 43 | unfold well_formed_closed in *. simpl. 44 | naive_bsolver. 45 | - unfold well_formed,well_formed_closed in *. simpl in *. 46 | naive_bsolver. 47 | Qed. 48 | 49 | Lemma wp_sctx (C : Application_context) (A : Pattern) : 50 | well_formed_positive A = true -> well_formed_positive (subst_ctx C A) = true. 51 | Proof. 52 | intros H. 53 | induction C. 54 | - auto. 55 | - simpl. rewrite IHC. simpl. 56 | unfold well_formed in Prf. apply andb_true_iff in Prf. destruct Prf. exact H0. 57 | - simpl. unfold well_formed in Prf. apply andb_true_iff in Prf. 58 | destruct Prf. rewrite H0. rewrite IHC. reflexivity. 59 | Qed. 60 | 61 | Lemma wcex_sctx (C : Application_context) (A : Pattern) idx1 : 62 | well_formed_closed_ex_aux A idx1 = true -> well_formed_closed_ex_aux (subst_ctx C A) idx1 = true. 63 | Proof. 64 | intros H. 65 | induction C. 66 | - auto. 67 | - simpl. rewrite IHC. simpl. 68 | unfold well_formed,well_formed_closed in *. 69 | destruct_andb! Prf. 70 | eapply well_formed_closed_ex_aux_ind. 2: eassumption. lia. 71 | - simpl. rewrite IHC. 72 | unfold well_formed,well_formed_closed in *. 73 | destruct_andb! Prf. apply andb_true_iff; split. 2: reflexivity. 74 | eapply well_formed_closed_ex_aux_ind. 2: eassumption. lia. 75 | Qed. 76 | 77 | Lemma wcmu_sctx (C : Application_context) (A : Pattern) idx1 : 78 | well_formed_closed_mu_aux A idx1 = true -> well_formed_closed_mu_aux (subst_ctx C A) idx1 = true. 79 | Proof. 80 | intros H. 81 | induction C. 82 | - auto. 83 | - simpl. rewrite IHC. simpl. 84 | unfold well_formed,well_formed_closed in *. 85 | destruct_andb! Prf. 86 | eapply well_formed_closed_mu_aux_ind. 2: eassumption. lia. 87 | - simpl. rewrite IHC. 88 | unfold well_formed,well_formed_closed in *. 89 | destruct_andb! Prf. apply andb_true_iff; split. 2: reflexivity. 90 | eapply well_formed_closed_mu_aux_ind. 2: eassumption. lia. 91 | Qed. 92 | 93 | Fixpoint free_evars_ctx (C : Application_context) 94 | : (EVarSet) := 95 | match C with 96 | | box => empty 97 | | @ctx_app_l cc p prf => union (free_evars_ctx cc) (free_evars p) 98 | | @ctx_app_r p cc prf => union (free_evars p) (free_evars_ctx cc) 99 | end. 100 | 101 | 102 | Definition ApplicationContext2Pattern (boxvar : evar) (AC : Application_context) := 103 | subst_ctx AC (patt_free_evar boxvar). 104 | 105 | Lemma ApplicationContext2Pattern_one_occ (AC : Application_context) (boxvar : evar): 106 | boxvar ∉ free_evars_ctx AC -> 107 | count_evar_occurrences boxvar (ApplicationContext2Pattern boxvar AC) = 1. 108 | Proof. 109 | intros H. 110 | induction AC; simpl. 111 | - destruct (decide (boxvar = boxvar)). reflexivity. contradiction. 112 | - simpl in H. apply not_elem_of_union in H. 113 | rewrite IHAC. 114 | { exact (proj1 H). } 115 | simpl in H. 116 | rewrite (proj1 (count_evar_occurrences_0 boxvar p)). 2: lia. 117 | exact (proj2 H). 118 | - simpl in H. apply not_elem_of_union in H. 119 | rewrite IHAC. 120 | { exact (proj2 H). } 121 | simpl in H. 122 | rewrite (proj1 (count_evar_occurrences_0 boxvar p)). 2: lia. 123 | exact (proj1 H). 124 | Qed. 125 | 126 | End with_signature. 127 | 128 | Module Notations. 129 | 130 | Notation "□" := box. 131 | Notation "p '$ₗ' C" := (@ctx_app_l _ p C _) (at level 65). 132 | Notation "C '$ᵣ' p" := (@ctx_app_r _ C p _) (at level 65). 133 | Notation "C .[ □ ↦ p ]" := (subst_ctx C p) 134 | (at level 2, format "C .[ □ ↦ p ]"). 135 | 136 | End Notations. 137 | 138 | Lemma free_evars_subst_ctx {Σ : Signature} AC ϕ: 139 | free_evars (subst_ctx AC ϕ) = AC_free_evars AC ∪ free_evars ϕ. 140 | Proof. 141 | induction AC; simpl. 142 | - set_solver. 143 | - rewrite IHAC. clear. set_solver. 144 | - rewrite IHAC. clear. set_solver. 145 | Qed. 146 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/Extractor.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Import Logic ProofSystem. 2 | From MatchingLogic.Evaluation Require Import 3 | Firstorder 4 | Complex 5 | Propositional 6 | Rewrite 7 | Revert_size. 8 | 9 | Extraction Language Haskell. 10 | 11 | From Coq Require Extraction. 12 | Require Import ExtrHaskellBasic. 13 | Require Import ExtrHaskellString. 14 | (* Require Import ExtrHaskellZInteger. 15 | Require Import ExtrHaskellNatNum. 16 | Require Import ExtrHaskellNatInt. *) 17 | 18 | Fixpoint proof_size {Σ : Signature} {φ : Pattern} {Γ} 19 | (pf : ML_proof_system Γ φ) : nat := 20 | match pf with 21 | | ML_Modus_ponens _ phi1 phi2 x x0 => 1 + proof_size x + proof_size x0 22 | | ML_Ex_gen _ phi1 phi2 x x0 x1 x2 x3 => 1 + proof_size x2 23 | | ML_Framing_left _ phi1 phi2 psi x x0 => 1 + proof_size x0 24 | | ML_Framing_right _ phi1 phi2 psi x x0 => 1 + proof_size x0 25 | | ML_Svar_subst _ phi psi X x x0 x1 => 1 + proof_size x1 26 | | ML_Knaster_tarski _ phi psi x x0 => 1 + proof_size x0 27 | | ML_Existence _ => 1 28 | | _ => 1 29 | end. 30 | 31 | Definition proof_size_info {Σ : Signature} {φ Γ i} (pf : derives_using Γ φ i) : nat := 32 | match pf with 33 | | exist _ x x0 => proof_size x 34 | end. 35 | 36 | Definition proof_prop_low : nat := proof_size_info proof1_low. 37 | Definition proof_prop_pm1 : nat := proof_size_info proof1_pm. 38 | Definition proof_prop_pm2 : nat := proof_size_info proof1_pm2. 39 | 40 | Definition proof_rew_low : nat := proof_size_info proof2_low. 41 | Definition proof_rew_pm1 : nat := proof_size_info proof2_pm. 42 | Definition proof_rew_pm2 : nat := proof_size_info proof2_pm2. 43 | Definition proof_rew_pm3 : nat := proof_size_info proof2_pm3. 44 | Definition proof_rew_low3 : nat := proof_size_info proof2_low3. 45 | Definition proof_rew_low4 : nat := proof_size_info proof2_low4. 46 | 47 | 48 | Definition proof_fol_low : nat := proof_size_info proof3_low. 49 | Definition proof_fol_pm1 : nat := proof_size_info proof3_fol_pm. 50 | Definition proof_fol_pm2 : nat := proof_size_info proof3_pm. 51 | 52 | Definition proof_derived_rev_small : nat := proof_size_info private_test_revert_1. 53 | Definition proof_pm_rev_small : nat := proof_size_info private_test_revert_2. 54 | Definition proof_derived_rev_big : nat := proof_size_info private_test_revert_3. 55 | Definition proof_pm_rev_big : nat := proof_size_info private_test_revert_4. 56 | 57 | Definition proof_complex_low : nat := proof_size_info proof_running_low. 58 | Definition proof_complex_pm : nat := proof_size_info proof_running_pm. 59 | 60 | Extraction "Test.hs" proof_prop_low proof_prop_pm1 proof_prop_pm2 61 | proof_rew_low proof_rew_pm1 proof_rew_pm2 proof_rew_pm3 62 | proof_rew_low3 proof_rew_low4 63 | proof_fol_low proof_fol_pm1 proof_fol_pm2 64 | proof_derived_rev_small proof_pm_rev_small 65 | proof_derived_rev_big proof_pm_rev_big 66 | proof_complex_low proof_complex_pm. 67 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/Firstorder.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Import Theories.Definedness_Syntax 2 | ProofMode.MLPM. 3 | 4 | Import MatchingLogic.Logic.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Definition Example3 : Type := 9 | forall (Σ : Signature) (Γ : Theory) (A B : Pattern), 10 | well_formed (ex, A) = true -> 11 | well_formed (ex, B) = true -> 12 | Γ ⊢ (ex, A and B) ---> ex, A 13 | . 14 | 15 | Lemma ex3_low : Example3. 16 | Proof. 17 | unfold Example3. 18 | intros Σ Γ A B WFA WFB. 19 | (* inline proof of ex_quan_monotone *) 20 | assert (forall A B x, well_formed (ex, A) -> well_formed (ex, B) -> x ∉ free_evars A -> x ∉ free_evars B -> 21 | Γ ⊢ (evar_open x 0 A) ---> (evar_open x 0 B) -> Γ ⊢ (ex, A) ---> ex, B) as H. { 22 | intros. 23 | apply strip_exists_quantify_l with (x := x). 24 | { exact H1. } 25 | { shelve. } 26 | apply Ex_gen. 1-2: shelve. 27 | eapply syllogism_meta. 1-3: shelve. exact H3. 28 | epose proof (Htmp := Ex_quan Γ B0 x _). 29 | cbn in Htmp. 30 | eapply useGenericReasoning in Htmp. 31 | apply Htmp. 32 | shelve. 33 | } 34 | mlFreshEvar as x. 35 | apply (H (A and B) A x). 36 | 1-4: shelve. 37 | mlSimpl. 38 | epose proof (pf_conj_elim_l Γ (A^{evar:0↦x}) (B^{evar:0↦x}) _ _) as H0. 39 | eapply useGenericReasoning in H0. exact H0. shelve. 40 | Unshelve. 41 | (* 9 well_formed goals *) 42 | 1,4-7,9-10,13-14: solve [wf_auto2]. 43 | (* 3 variable membership goals *) 44 | 2: cbn; solve_free_evars 1. 4: fm_solve. 3: fm_solve. 45 | (* 3 ProofInfoLe goals *) 46 | 1-3: try_solve_pile. 47 | Defined. 48 | 49 | 50 | (** Proof using only FOL proof mode *) 51 | Lemma ex3_fol_pm : Example3. 52 | Proof. 53 | unfold Example3. 54 | intros Σ Γ A B WFA WFB. 55 | mlIntro "H". 56 | mlDestructEx "H" as x. 57 | mlSimpl. 58 | mlExists x. 59 | fromMLGoal. 60 | epose proof (pf_conj_elim_l Γ (A^{evar:0↦x}) _ _ _) as H0. 61 | eapply useGenericReasoning in H0. 62 | { exact H0. } 63 | { shelve. } 64 | Unshelve. 65 | (* 2 well_formedness *) 66 | 1-2: wf_auto2. 67 | (* 1 ProofInfoLe *) 68 | try_solve_pile. 69 | Defined. 70 | 71 | (** Proof using proof mode *) 72 | Lemma ex3_pm : Example3. 73 | Proof. 74 | unfold Example3. 75 | intros Σ Γ A B wfA wfB. 76 | mlIntro "H". 77 | mlDestructEx "H" as x. 78 | mlSimpl. 79 | mlDestructAnd "H" as "H0" "H1". 80 | mlExists x. 81 | mlAssumption. 82 | Defined. 83 | 84 | Lemma ex3_coq {T : Type} A B: 85 | (exists (x : T), A x /\ B x) -> exists x, A x. 86 | Proof. 87 | intros H. 88 | destruct H as [x H]. 89 | destruct H as [H0 H1]. 90 | exists x. 91 | assumption. 92 | Qed. 93 | 94 | Section compute. 95 | 96 | Inductive Symbols := 97 | | sym_import_definedness (d : Definedness_Syntax.Symbols) 98 | | Zero | Succ (* constructors for Nats *) 99 | | TT | FF 100 | | even 101 | . 102 | 103 | Instance Symbols_eqdec : EqDecision Symbols. 104 | Proof. solve_decision. Defined. 105 | 106 | #[local] 107 | Program Instance Symbols_fin : Finite Symbols := 108 | {| 109 | enum := [Zero; Succ; TT ; FF; even; 110 | sym_import_definedness Definedness_Syntax.def_sym] ; 111 | |}. 112 | Next Obligation. 113 | repeat constructor; set_solver. 114 | Qed. 115 | Next Obligation. 116 | destruct x; try set_solver. 117 | destruct d; set_solver. 118 | Qed. 119 | 120 | Instance signature : Signature := 121 | {| variables := StringMLVariables ; 122 | ml_symbols := {| 123 | symbols := Symbols ; 124 | |} 125 | |}. 126 | 127 | Instance definedness_syntax : Definedness_Syntax.Syntax := 128 | {| 129 | Definedness_Syntax.sym_inj := sym_import_definedness; 130 | |}. 131 | 132 | Open Scope string_scope. 133 | Let X0 := patt_free_evar "X0". 134 | Let X := patt_free_evar "X". 135 | Let sym_even := patt_sym even. 136 | Let sym_succ := patt_sym Succ. 137 | Let sym_zero := patt_sym Zero. 138 | Let sym_tt := patt_sym TT. 139 | Let sym_ff := patt_sym FF. 140 | (* axioms *) 141 | Definition defined : Pattern := Definedness_Syntax.axiom AxDefinedness. 142 | 143 | Definition A : Pattern := 144 | sym_zero. 145 | Definition B : Pattern := 146 | patt_app sym_succ sym_zero. 147 | 148 | Definition proof3_low := ex3_low signature ∅ A B ltac:(reflexivity) ltac:(reflexivity). 149 | Definition proof3_fol_pm := ex3_fol_pm signature ∅ A B ltac:(reflexivity) ltac:(reflexivity). 150 | Definition proof3_pm := ex3_pm signature ∅ A B ltac:(reflexivity) ltac:(reflexivity). 151 | 152 | End compute. 153 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/Propositional.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Import Theories.Definedness_Syntax 2 | ProofMode.MLPM. 3 | 4 | Import MatchingLogic.Logic.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | (** Low-level proof, using only the proof system *) 9 | Lemma ex1_low : forall {Σ : Signature} (Γ : Theory) (A B : Pattern), 10 | well_formed A = true -> 11 | well_formed B = true -> 12 | Γ ⊢i (A ---> B ---> (A and B)) 13 | using BasicReasoning. 14 | Proof. 15 | intros Σ Γ A B WFA WFB. 16 | epose proof (tB := (A_impl_A Γ B _)). 17 | epose proof (t1 := MP (P2 Γ (!(!A) ---> !B) A ⊥ _ _ _) (P1 _ _ B _ _)). 18 | epose proof (t2 := MP (reorder_meta _ _ _ (P4 Γ (!A) B _ _)) (P1 _ _ B _ _)). 19 | epose proof (t3'' := MP (P1 Γ A (!(!A) ---> !B) _ _) (P1 _ _ B _ _)). 20 | epose proof (t4 := MP tB (MP t2 (P2 Γ B B _ _ _ _))). 21 | epose proof (t5'' := 22 | MP t4 23 | (MP t1 24 | (P2 Γ B ((!(!A) ---> !B) ---> !A) 25 | (((!(!A) ---> !B) ---> A) ---> !(!(!A) ---> !B)) _ _ _))). 26 | epose proof (tA := (P1 Γ A B) _ _). 27 | epose proof (tB' := MP tB (P1 _ (B ---> B) A _ _)). 28 | epose proof (t3' := MP t3'' (P2 _ B A ((!(!A) ---> !B) ---> A) _ _ _)). 29 | epose proof (t3 := MP t3' (P1 _ ((B ---> A) ---> B ---> (! (! A) ---> ! B) ---> A) A _ _)). 30 | epose proof (t5' := MP t5'' 31 | (P2 _ B ((!(!A) ---> !B) ---> A) (!(!(!A) ---> !B)) _ _ _)). 32 | epose proof (t5 := MP t5' 33 | (P1 _ ((B ---> (! (! A) ---> ! B) ---> A) ---> B ---> ! (! (! A) ---> ! B)) 34 | A _ _)). 35 | epose proof (t6 := MP tA 36 | (MP t3 37 | (P2 _ A (B ---> A) (B ---> (!(!A) ---> !B) ---> A) _ _ _))). 38 | epose proof (t7 := MP t6 39 | (MP t5 40 | (P2 _ A (B ---> (!(!A) ---> !B) ---> A) (B ---> !(!(!A) ---> !B)) _ _ _))). 41 | apply t7. 42 | Unshelve. 43 | (* 43 well-formedness goals *) 44 | 1-43: wf_auto2. 45 | Defined. 46 | 47 | (** Proof using proof mode *) 48 | Lemma ex1_pm : forall {Σ : Signature} (Γ : Theory) (A B : Pattern), 49 | well_formed A = true -> 50 | well_formed B = true -> 51 | Γ ⊢i (A ---> B ---> (A and B)) 52 | using BasicReasoning. 53 | Proof. 54 | intros Σ Γ A B WFA WFB. 55 | unfold patt_and, patt_or, patt_not. 56 | mlIntro "Ha". mlIntro "Hb". mlIntro "H". 57 | mlAssert ("H0" : B). { wf_auto2. } { mlAssumption. } 58 | mlRevertLast. 59 | mlApply "H". 60 | mlIntro "H0". mlApply "H0". mlAssumption. 61 | Defined. 62 | 63 | Lemma ex1_coq (A B : Prop) : 64 | A -> B -> A /\ B. 65 | Proof. 66 | intros H H0. 67 | split; assumption. 68 | Qed. 69 | 70 | Lemma ex1_pm2 : forall {Σ : Signature} (Γ : Theory) (A B : Pattern), 71 | well_formed A = true -> 72 | well_formed B = true -> 73 | Γ ⊢i (A ---> B ---> (A and B)) 74 | using BasicReasoning. 75 | Proof. 76 | intros Σ Γ A B WFA WFB. 77 | do 2 mlIntro; mlSplitAnd; mlAssumption. 78 | Defined. 79 | 80 | Section compute. 81 | 82 | Inductive Symbols := 83 | | sym_import_definedness (d : Definedness_Syntax.Symbols) 84 | | Zero | Succ (* constructors for Nats *) 85 | | TT | FF 86 | | even 87 | . 88 | 89 | Instance Symbols_eqdec : EqDecision Symbols. 90 | Proof. solve_decision. Defined. 91 | 92 | #[local] 93 | Program Instance Symbols_fin : Finite Symbols := 94 | {| 95 | enum := [Zero; Succ; TT ; FF; even; 96 | sym_import_definedness Definedness_Syntax.def_sym] ; 97 | |}. 98 | Next Obligation. 99 | repeat constructor; set_solver. 100 | Qed. 101 | Next Obligation. 102 | destruct x; try set_solver. 103 | destruct d; set_solver. 104 | Qed. 105 | 106 | Instance signature : Signature := 107 | {| variables := StringMLVariables ; 108 | ml_symbols := {| 109 | symbols := Symbols ; 110 | |} 111 | |}. 112 | 113 | Instance definedness_syntax : Definedness_Syntax.Syntax := 114 | {| 115 | Definedness_Syntax.sym_inj := sym_import_definedness; 116 | |}. 117 | 118 | Open Scope string_scope. 119 | Let X0 := patt_free_evar "X0". 120 | Let X := patt_free_evar "X". 121 | Let sym_even := patt_sym even. 122 | Let sym_succ := patt_sym Succ. 123 | Let sym_zero := patt_sym Zero. 124 | Let sym_tt := patt_sym TT. 125 | Let sym_ff := patt_sym FF. 126 | (* axioms *) 127 | Definition defined : Pattern := Definedness_Syntax.axiom AxDefinedness. 128 | 129 | Definition A : Pattern := 130 | sym_zero. 131 | Definition B : Pattern := 132 | patt_app sym_succ sym_zero. 133 | 134 | Definition proof1_low := ex1_low ∅ A B ltac:(wf_auto2) ltac:(wf_auto2). 135 | Definition proof1_pm := ex1_pm ∅ A B ltac:(wf_auto2) ltac:(wf_auto2). 136 | Definition proof1_pm2 := ex1_pm2 ∅ A B ltac:(wf_auto2) ltac:(wf_auto2). 137 | (* 138 | Compute proof_size_info (ex1_low ∅ A B ltac:(wf_auto2) ltac:(wf_auto2)). 139 | Compute proof_size_info (ex1_pm ∅ A B ltac:(wf_auto2) ltac:(wf_auto2)). *) 140 | 141 | End compute. 142 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/README.md: -------------------------------------------------------------------------------- 1 | # Proof mode evaluation 2 | 3 | This folder contains a number of example theorems proved using the proof mode or the Hilbert-system. To evaluate proof sizes, the extracted Haskell code needs to be executed (see `evaluator.hs` in the main directory). For the Haskell compilation, the following imports need to be added into the generated `Test.hs` (due to a bug in the Haskell extraction process of Coq): 4 | 5 | ``` 6 | import qualified Data.Bits 7 | import qualified Data.Char 8 | ``` 9 | 10 | To check proof sizes, compile `evaluator.hs` in the main directory, with the option `-XNoPolyKinds`. The individual functions in that file refer to the different proof sizes for the proofs in this directory. 11 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/Revert_size.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Import Theories.Definedness_Syntax 2 | ProofMode.MLPM. 3 | 4 | Import MatchingLogic.Logic.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Local Lemma Private_revert_forall_iter {Σ : Signature} (Γ : Theory) : 9 | forall (l : list Pattern) (ϕ : Pattern) x, 10 | Pattern.wf l -> 11 | well_formed ϕ -> 12 | Γ ⊢i foldr patt_imp (all , ϕ^{{evar: x ↦ 0}}) l ---> foldr patt_imp ϕ l 13 | using BasicReasoning. 14 | Proof. 15 | intros l ϕ x Wfl Wfϕ. apply prf_weaken_conclusion_iter_meta. 1-3: wf_auto2. 16 | mlIntro "H". 17 | mlSpecialize "H" with x. 18 | rewrite evar_open_evar_quantify. wf_auto2. 19 | mlAssumption. 20 | Qed. 21 | 22 | Section compute. 23 | Inductive Symbols := 24 | | sym_import_definedness (d : Definedness_Syntax.Symbols) 25 | | Zero | Succ (* constructors for Nats *) 26 | | TT | FF 27 | | even 28 | . 29 | 30 | Instance Symbols_eqdec : EqDecision Symbols. 31 | Proof. solve_decision. Defined. 32 | 33 | #[local] 34 | Program Instance Symbols_fin : Finite Symbols := 35 | {| 36 | enum := [Zero; Succ; TT ; FF; even; 37 | sym_import_definedness Definedness_Syntax.def_sym] ; 38 | |}. 39 | Next Obligation. 40 | repeat constructor; set_solver. 41 | Qed. 42 | Next Obligation. 43 | destruct x; try set_solver. 44 | destruct d; set_solver. 45 | Qed. 46 | 47 | Instance signature : Signature := 48 | {| variables := StringMLVariables ; 49 | ml_symbols := {| 50 | symbols := Symbols ; 51 | |} 52 | |}. 53 | 54 | Instance definedness_syntax : Definedness_Syntax.Syntax := 55 | {| 56 | Definedness_Syntax.sym_inj := sym_import_definedness; 57 | |}. 58 | 59 | Open Scope string_scope. 60 | Let X0 := patt_free_evar "X0". 61 | Let X := patt_free_evar "X". 62 | Let sym_even := patt_sym even. 63 | Let sym_succ := patt_sym Succ. 64 | Let sym_zero := patt_sym Zero. 65 | Let sym_tt := patt_sym TT. 66 | Let sym_ff := patt_sym FF. 67 | (* axioms *) 68 | Definition defined : Pattern := Definedness_Syntax.axiom AxDefinedness. 69 | 70 | Definition A : Pattern := 71 | sym_zero. 72 | Definition B : Pattern := 73 | patt_app sym_succ sym_zero. 74 | 75 | Definition private_test_revert_1 := 76 | (Private_revert_forall_iter ∅ [] patt_bott (fresh_evar patt_bott) 77 | ltac:(wf_auto2) ltac:(wf_auto2)). 78 | Definition private_test_revert_2 := 79 | (revert_forall_iter ∅ [] patt_bott (fresh_evar patt_bott) 80 | ltac:(wf_auto2) ltac:(wf_auto2)). 81 | Definition private_test_revert_3 := 82 | (Private_revert_forall_iter ∅ [A;B;A;B;A;B] patt_bott (fresh_evar patt_bott) 83 | ltac:(wf_auto2) ltac:(wf_auto2)). 84 | Definition private_test_revert_4 := 85 | (revert_forall_iter ∅ [A;B;A;B;A;B] patt_bott (fresh_evar patt_bott) 86 | ltac:(wf_auto2) ltac:(wf_auto2)). 87 | 88 | (* 89 | Compute proof_size_info (ex1_low ∅ A B ltac:(wf_auto2) ltac:(wf_auto2)). 90 | Compute proof_size_info (ex1_pm ∅ A B ltac:(wf_auto2) ltac:(wf_auto2)). *) 91 | 92 | End compute. 93 | 94 | -------------------------------------------------------------------------------- /matching-logic/src/Evaluation/tutorial.v: -------------------------------------------------------------------------------- 1 | 2 | (* What follows is a minimal example of how to use the ProofMode. *) 3 | 4 | From MatchingLogic Require Import ProofMode.MLPM 5 | Definedness_ProofSystem. 6 | 7 | Import MatchingLogic.Logic.Notations 8 | MatchingLogic.Theories.Definedness_Syntax.Notations. 9 | 10 | Set Default Proof Mode "Classic". 11 | 12 | Open Scope string_scope. 13 | Open Scope list_scope. 14 | 15 | Section tutorial. 16 | 17 | Context {Σ : Signature} 18 | {Γ : Theory} 19 | (ϕ : Pattern) 20 | (wfϕ : well_formed ϕ). 21 | 22 | (* Below we prove that in matching logic, ϕ -> ϕ for any pattern ϕ. *) 23 | Example phi_implies_phi : 24 | Γ ⊢ ϕ ---> ϕ. 25 | Proof. 26 | mlIntro "H". 27 | mlExact "H". 28 | Qed. 29 | 30 | (* We can also work with conjunction and disjunction. *) 31 | 32 | Context (ϕ₁ : Pattern) 33 | (wfϕ₁ : well_formed ϕ₁) 34 | (ϕ₂ : Pattern) 35 | (wfϕ₂ : well_formed ϕ₂). 36 | 37 | Example and_or : 38 | Γ ⊢ ϕ₁ and ϕ₂ ---> ϕ₁ or ϕ₂ 39 | . 40 | Proof. 41 | mlIntro "H". 42 | (* we have tactics like: 43 | * [mlDestructAnd] 44 | * [mlDestructOr] 45 | * [mlLeft] 46 | * [mlRight] 47 | * [mlSplitAnd] 48 | which work similarly to their Coq counterparts 49 | *) 50 | 51 | mlDestructAnd "H" as "H1" "H2". 52 | mlLeft. 53 | mlExact "H1". 54 | Qed. 55 | 56 | Context (ϕ₃ : Pattern) 57 | (wfϕ₃ : well_formed ϕ₃) 58 | (ϕ₄ : Pattern) 59 | (wfϕ₄ : well_formed ϕ₄). 60 | 61 | Example use_rewrite : 62 | Γ ⊢ ϕ₁ <---> ϕ₂ -> 63 | (* The [⋅] operator is an application. *) 64 | Γ ⊢ (ϕ₃ ⋅ ϕ₁ ⋅ ϕ₄) <---> (ϕ₃ ⋅ ϕ₂ ⋅ ϕ₄) 65 | . 66 | Proof. 67 | intros H. 68 | (* Notice that now we have a meta-level assumption [H]. *) 69 | 70 | (* We can use [H] to rewrite the first occurrence of [ϕ₁] to [ϕ₂]. *) 71 | mlRewrite H at 1. 72 | (* Now the goal is provable by propositional reasoning. *) 73 | mlSplitAnd. 74 | * mlIntro "H". mlExact "H". 75 | * mlIntro "H". mlExact "H". 76 | Qed. 77 | 78 | (* We can also use definedness and equality. 79 | To do so, we have to assume that the signature contains a definedness symbol, 80 | and the theory a definedness axiom. 81 | Otherwise, the signature and axiom can be arbitrary. 82 | *) 83 | 84 | (* Obviously, without the definedness symbol, we cannot use equality. *) 85 | Fail Example use_rewriteBy : 86 | Γ ⊢ (ϕ₁ ⋅ ϕ₄ =ml ϕ₂ ⋅ ϕ₄ ) ---> (ϕ₁ =ml ϕ₂) ---> ((ϕ₃ ⋅ ϕ₁ ⋅ ϕ₄) <---> (ϕ₃ ⋅ ϕ₂ ⋅ ϕ₄)) 87 | . 88 | 89 | (* The typeclass [Definedness_Syntax.Syntax] ensures the presence of the definedness symbol 90 | in the (implicit) signature Σ. 91 | *) 92 | Context {syntax : Definedness_Syntax.Syntax}. 93 | 94 | Example use_rewriteBy : 95 | Γ ⊢ (ϕ₁ ⋅ ϕ₄ =ml ϕ₂ ⋅ ϕ₄) ---> (ϕ₁ =ml ϕ₂) ---> ((ϕ₃ ⋅ (ϕ₁ ⋅ ϕ₄)) <---> (ϕ₃ ⋅ (ϕ₂ ⋅ ϕ₄))) 96 | . 97 | Proof. 98 | mlIntro "H1". mlIntro "H2". 99 | 100 | (* We can rewrite using an equality from the local context. *) 101 | mlRewriteBy "H1" at 1. 102 | { 103 | (* There is an obligation we do not know how to solve. What does that mean? *) 104 | unfold theory, named_axioms, NamedAxioms.theory_of_NamedAxioms, axiom. simpl. 105 | (* We are missing a Definedness axiom. *) 106 | admit. 107 | } 108 | Abort. 109 | 110 | Context {HΓ : Definedness_Syntax.theory ⊆ Γ}. 111 | 112 | Example use_rewriteBy : 113 | Γ ⊢ (ϕ₁ ⋅ ϕ₄ =ml ϕ₂ ⋅ ϕ₄ ) ---> (ϕ₁ =ml ϕ₂) ---> ((ϕ₃ ⋅ (ϕ₁ ⋅ ϕ₄)) <---> (ϕ₃ ⋅ (ϕ₂ ⋅ ϕ₄))) 114 | . 115 | Proof. 116 | mlIntro "H1". mlIntro "H2". 117 | 118 | (* We can rewrite using an equality from the local context. *) 119 | mlRewriteBy "H1" at 1. 120 | (* Now the obligation was solved automatically *) 121 | 122 | mlSplitAnd; mlIntro "H"; mlExact "H". 123 | Defined. 124 | 125 | 126 | (* 127 | We now demonstrate how to use local hypotheses that are implications. 128 | *) 129 | Example use_mlApply : 130 | Γ ⊢ (ϕ₁ ---> ϕ₂ ⋅ ϕ₃) ---> (ϕ₂ ⋅ ϕ₃ ---> ϕ₃) ---> (ϕ₁ ---> ϕ₃). 131 | Proof. 132 | mlIntro "H1". mlIntro "H2". mlIntro "H3". 133 | (* replace the goal with the premise of "H2", since the goal is exactly 134 | the conclusion of "H2" *) 135 | mlApply "H2". 136 | (* Alternatively: replace "H3" with the conclusion of "H1", since "H3" is 137 | the premise of "H1". *) 138 | (* mlApply "H1" in "H3". *) 139 | 140 | mlApply "H1". 141 | mlExact "H3". 142 | Defined. 143 | 144 | Context (ψ : Pattern) 145 | (wfψ : well_formed (ex, ψ)). 146 | 147 | (* 148 | What if we have a matching logic implication in a Coq hypothesis 149 | or in a lemma? There is `mlApplyMeta` for that. 150 | *) 151 | Example use_mlApplyMeta : 152 | Γ ⊢ ϕ₁ ---> ((ex, ψ) ⋅ ϕ₂) ---> ϕ₃ ---> (ex, (ψ ⋅ ϕ₂)). 153 | Proof. 154 | mlIntro "H1". mlIntro "H2". mlIntro "H3". 155 | 156 | Check Prop_ex_left. 157 | (* 158 | Prop_ex_left 159 | : ∀ (Γ : Theory) (ϕ ψ : Pattern), 160 | well_formed (ex , ϕ) 161 | → well_formed ψ 162 | → Γ ⊢i (ex , ϕ) ⋅ ψ ---> (ex , ϕ ⋅ ψ) using BasicReasoning 163 | *) 164 | mlApplyMeta Prop_ex_left. 165 | (* Did you notice that [mlApplyMeta] automatically instantiated 166 | all the preconditions of the lemma? 167 | That is, without some magic happening on the background, 168 | one would need to manualy specify them, 169 | and solve the well-formedness subgoals. 170 | *) 171 | mlExact "H2". 172 | Defined. 173 | 174 | End tutorial. 175 | -------------------------------------------------------------------------------- /matching-logic/src/Experimental/Kore_ProofSystem.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic.Experimental Require Export Kore. 2 | 3 | Import MatchingLogic.Logic.Notations. 4 | Import MatchingLogic.Theories.Definedness_Syntax.Notations. 5 | Import MatchingLogic.Theories.Sorts_Syntax.Notations. 6 | Import MatchingLogic.Theories.Nat_Syntax.Notations. 7 | Import MatchingLogic.Experimental.Kore.Notations. 8 | 9 | Set Default Proof Mode "Classic". 10 | 11 | (* For the well-formedness tactics, we forbid simplifications *) 12 | Arguments well_formed_positive : simpl never. 13 | Arguments well_formed_closed_mu_aux : simpl never. 14 | Arguments well_formed_closed_ex_aux : simpl never. 15 | 16 | Section DerivedRules. 17 | 18 | Context {Σ : Signature} 19 | {syntax : Kore.Syntax} 20 | (Γ: Theory) 21 | (HΓ : KoreTheory ⊆ Γ). 22 | 23 | Theorem kore_equals_trans s s₂ φ₁ φ₂ φ₃: 24 | well_formed s -> 25 | well_formed s₂ -> 26 | well_formed φ₁ -> 27 | well_formed φ₂ -> 28 | well_formed φ₃ -> 29 | Γ ⊢ φ₁ =ml(s, s₂) φ₂ ---> φ₂ =ml(s, s₂) φ₃ ---> 30 | φ₁ =ml(s, s₂) φ₃. 31 | Proof. 32 | intros. 33 | mlIntro "H". 34 | mlIntro "H0". 35 | mlApplyMeta equals_equiv_1 in "H". 2: assumption. 36 | mlApplyMeta equals_equiv_1 in "H0". 2: assumption. 37 | mlDestructAnd "H" as "H_1" "H_2". 38 | mlDestructAnd "H0" as "H0_1" "H0_2". 39 | mlApplyMeta equals_equiv_2. 2: assumption. 40 | mlSplitAnd. 2: mlAssumption. 41 | mlRewriteBy "H_1" at 1. 1: unfold KoreTheory in HΓ; set_solver. 42 | mlAssumption. 43 | Defined. 44 | 45 | 46 | End DerivedRules. -------------------------------------------------------------------------------- /matching-logic/src/Experimental/Test.v: -------------------------------------------------------------------------------- 1 | (* TODO I probably don't need half of these *) 2 | 3 | From Equations Require Import Equations. 4 | From Coq Require Import ssreflect ssrfun ssrbool. 5 | 6 | Require Import Logic.Classical_Prop Coq.Logic.FunctionalExtensionality. 7 | 8 | From stdpp 9 | Require Import 10 | base 11 | decidable 12 | propset 13 | fin_maps 14 | fin_sets 15 | . 16 | 17 | From MatchingLogic 18 | Require Import 19 | Utils.extralibrary 20 | Utils.stdpp_ext 21 | Pattern 22 | Syntax 23 | Semantics 24 | DerivedOperators_Syntax 25 | DerivedOperators_Semantics 26 | PrePredicate 27 | monotonic 28 | Theories.Definedness_Syntax 29 | Theories.Definedness_Semantics 30 | Theories.Sorts_Syntax 31 | Theories.Sorts_Semantics 32 | Theories.DefaultModels 33 | . 34 | 35 | 36 | Import MatchingLogic.Logic.Notations. 37 | Import MatchingLogic.Semantics.Notations. 38 | 39 | Open Scope ml_scope. 40 | 41 | Section helpers. 42 | Context 43 | {Σ₁ Σ₂ : Signature} 44 | (M₁ : @Model Σ₁) 45 | (M₂ : @Model Σ₂) 46 | . 47 | 48 | (* Add extra context arguments here *) 49 | Record ModelCombiners := { 50 | oneToTwo : Domain M₁ -> Domain M₂ -> propset (Domain M₁ + Domain M₂)%type; 51 | twoToOne : Domain M₂ -> Domain M₁ -> propset (Domain M₁ + Domain M₂)%type; 52 | (* Ignore these for now, come back when you reached 53 | * the long comment later *) 54 | (* oneToOneOverride : Domain M₁ -> Domain M₁ -> option (propset (Domain M₁ M₂)); *) 55 | (* twoToTwoOverride : Domain M₂ -> Domain M₂ -> option (propset (Domain M₁ M₂)); *) 56 | }. 57 | End helpers. 58 | 59 | Section test. 60 | Context 61 | {Σ₁ Σ₂ : Signature} 62 | (M₁ : @Model Σ₁) 63 | (M₂ : @Model Σ₂) 64 | (mc : ModelCombiners M₁ M₂) 65 | . 66 | 67 | Instance Σext : Signature := { 68 | (* TODO this definitely needs to change *) 69 | variables := StringMLVariables; 70 | ml_symbols := {| 71 | symbols := @symbols (@ml_symbols Σ₁) + @symbols (@ml_symbols Σ₂) 72 | |} 73 | }. 74 | 75 | Program Definition Mext : @Model Σext := {| 76 | Domain := (Domain M₁ + Domain M₂)%type; 77 | Domain_inhabited := sum_inhabited_l (Domain_inhabited M₁); 78 | |}. 79 | Next Obligation. 80 | destruct mc. 81 | intros [] []. 82 | exact (inl <$> app_interp M₁ d d0). 83 | exact (oneToTwo0 d d0). 84 | exact (twoToOne0 d d0). 85 | exact (inr <$> app_interp M₂ d d0). 86 | Defined. 87 | Next Obligation. 88 | intros []. 89 | exact (inl <$> sym_interp M₁ s). 90 | exact (inr <$> sym_interp M₂ s). 91 | Defined. 92 | End test. 93 | 94 | Section natbool. 95 | Definition NatBoolModel := Mext BoolModel NatModel {| 96 | (* Not sure if this is necessarily correct. 97 | * 0 andThen True might arise and should not be empty set. 98 | * Then again, our andThen is not standard, this is probably 99 | * the same issue we have with definedness later. *) 100 | oneToTwo _ _ := ∅; (* $ *) 101 | twoToOne _ _ := ∅; (* $ *) 102 | |}. 103 | 104 | Instance PlainDefinedness_Σ : Signature := { 105 | variables := StringMLVariables; 106 | ml_symbols := {| symbols := unit |}; 107 | }. 108 | 109 | Definition PlainDefinedness : @Model PlainDefinedness_Σ := {| 110 | Domain := unit; 111 | app_interp _ _ := ⊤; 112 | sym_interp _ := singleton (); 113 | |}. 114 | 115 | Definition DefinedNatBoolModel := Mext NatBoolModel PlainDefinedness {| 116 | oneToTwo _ _ := ∅; (* $ def *) 117 | twoToOne _ _ := ⊤; (* def $ *) 118 | |}. 119 | 120 | (* These get complicated, let Coq figure it out for us *) 121 | Definition get_signature {Σ : Signature} (m : @Model Σ) : Signature := Σ. 122 | 123 | Instance def_syntax : @Definedness_Syntax.Syntax (get_signature DefinedNatBoolModel) := { 124 | inj _ := inr (); 125 | }. 126 | 127 | Goal DefinedNatBoolModel ⊨ᵀ Definedness_Syntax.theory. 128 | Proof. 129 | unfold theory, named_axioms, theory_of_NamedAxioms. simpl. 130 | unfold satisfies_theory. intros. apply elem_of_PropSet in H. 131 | destruct H, x. subst. cbn. unfold satisfies_model. intros. 132 | unfold patt_defined, p_x, ev_x. simp eval. 133 | unfold app_ext. simpl. unshelve eapply leibniz_equiv. 134 | exact (@propset_leibniz_equiv _ DefinedNatBoolModel). 135 | eapply set_equiv. intros. split; intros. set_solver. 136 | rewrite elem_of_PropSet. 137 | exists (inr ()), (evar_valuation ρ (evar_fresh [])). 138 | split. set_solver. split. set_solver. 139 | case_match. set_solver. 140 | (* This condition is unsolvable. It comes from 141 | * Mext def -> obligation 1 -> case 4 and 142 | * PlainDefinedness def -> app_interp. 143 | * These definitions both seen sensible on their own. 144 | * Use the second models app_interp if both elements are 145 | * from the second model, then wrap it in inr. Also 146 | * def $ def is full set (right?). However, when we combine 147 | * these, we get something wrong. I suspect this is because 148 | * def $ def needs to be full set even AFTER gluing the models, 149 | * and not inr <$> full set. We could take as extra params in 150 | * ModelCombiners two functions that specifiy these special 151 | * behaviours, maybe even functions returning options, 152 | * so we retain the default behaviour of delegating to 153 | * the sets underlying app_interp. This raises two questions: 154 | * - Are there any other cases where this is needed or is this 155 | * special to definedness? Should definedness be treated as 156 | * special and we don't need this change elsewhere? 157 | * ∙ PB: Yes, potentially generic datatypes would raise this issue too. 158 | For example, lists, maps, sets. Depending on the element's sort 159 | you might need to extend the behaviour of list/set/etc. symbols. 160 | * - If we override the models original app_interp, do we not 161 | * lose any reasoning we did about the original one? Is there 162 | * a way to retain the proofs and allow special behaviour? 163 | * ∙ PB: This is a main question. I think, you can only retain the original 164 | behaviour, if you override (or rather, extend) the behaviour in a 165 | correct way. For example, in case of definedness, you extend its 166 | interpretation in M₂ to full. 167 | *) 168 | Abort. 169 | End natbool. 170 | 171 | Section transformers. 172 | (* TODO *) 173 | End transformers. 174 | -------------------------------------------------------------------------------- /matching-logic/src/Logic.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Syntax 2 | IndexManipulation 3 | Semantics 4 | StringSignature 5 | wftactics 6 | DerivedOperators_Syntax 7 | DerivedOperators_Semantics 8 | NamedAxioms 9 | ProofInfo. 10 | 11 | Module Notations. 12 | Export MatchingLogic.Syntax.Notations 13 | MatchingLogic.Substitution.Notations 14 | MatchingLogic.DerivedOperators_Syntax.Notations 15 | MatchingLogic.ApplicationContext.Notations 16 | MatchingLogic.ProofInfo.Notations 17 | MatchingLogic.Semantics.Notations. 18 | Export Pattern.BoundVarSugar. 19 | End Notations. 20 | 21 | Open Scope string_scope. 22 | Open Scope ml_scope. 23 | Open Scope list_scope. 24 | -------------------------------------------------------------------------------- /matching-logic/src/NamedAxioms.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Pattern. 2 | 3 | (* TODO: set? *) 4 | (* TODO: well-formedness *) 5 | Record NamedAxioms {Σ : Signature} := 6 | { 7 | NAName : Type; 8 | NAAxiom : NAName -> Pattern ; 9 | NAwf : forall (name : NAName), well_formed (NAAxiom name) ; 10 | }. 11 | 12 | 13 | Definition theory_of_NamedAxioms {Σ : Signature} (NAs : NamedAxioms) : Theory := 14 | PropSet (fun p => exists (n : NAName NAs), p = NAAxiom _ n). 15 | 16 | 17 | (* TODO: do we want to make this a type class? *) 18 | Record NamedAxiomsIncluded {Σ : Signature} (NA₁ NA₂ : NamedAxioms) := 19 | { NAIinj : NAName NA₁ -> NAName NA₂; 20 | NAIax : forall (n : NAName NA₁), NAAxiom _ n = NAAxiom _ (NAIinj n); 21 | }. 22 | 23 | Lemma NamedAxiomsIncluded_impl_TheoryIncluded {Σ : Signature} NA₁ NA₂: 24 | NamedAxiomsIncluded NA₁ NA₂ -> 25 | (theory_of_NamedAxioms NA₁) ⊆ (theory_of_NamedAxioms NA₂). 26 | Proof. 27 | intros [inj ax]. 28 | unfold theory_of_NamedAxioms. 29 | rewrite -> elem_of_subseteq. 30 | intros ϕ H. 31 | rewrite -> elem_of_PropSet. rewrite -> elem_of_PropSet in H. 32 | destruct H as [n Hn]. subst ϕ. 33 | eexists. auto. 34 | Qed. 35 | 36 | Program Definition NamedAxiomsIncluded_refl {Σ : Signature} NA : NamedAxiomsIncluded NA NA := 37 | {| NAIinj := λ n, n; |}. 38 | Next Obligation. auto. Qed. 39 | (* TODO make it a stdpp preorder *) 40 | 41 | Program Definition NamedAxiomsIncluded_compose {Σ : Signature} NA₁ NA₂ NA₃ : 42 | NamedAxiomsIncluded NA₁ NA₂ -> 43 | NamedAxiomsIncluded NA₂ NA₃ -> 44 | NamedAxiomsIncluded NA₁ NA₃ := 45 | λ HI₁ HI₂, {| NAIinj := λ n, NAIinj _ _ HI₂ (NAIinj _ _ HI₁ n); |}. 46 | Next Obligation. 47 | intros Σ NA₁ NA₂ NA₃ [inj₁ ax₁] [inj₂ ax₂] n. 48 | simpl. 49 | rewrite -ax₂. 50 | rewrite -ax₁. 51 | auto. 52 | Qed. 53 | -------------------------------------------------------------------------------- /matching-logic/src/OPML/KPreludeSignatures.v: -------------------------------------------------------------------------------- 1 | 2 | From stdpp Require Export finite strings. 3 | (* This is unset by stdpp. We need to set it again.*) 4 | Set Transparent Obligations. 5 | 6 | From MatchingLogic.OPML Require Export OpmlSignature. 7 | 8 | #[global] 9 | Instance eq_partial_order (A : Type) : PartialOrder (@eq A). 10 | Proof. 11 | repeat split. 12 | { 13 | intros x y z Hxy Hyz. 14 | subst. reflexivity. 15 | } 16 | { 17 | intros x y Hxy Hyx. 18 | subst. reflexivity. 19 | } 20 | Qed. 21 | 22 | Definition Identity_relation (A : Type) : relation A := fun x y => x = y. 23 | 24 | #[global] 25 | Instance Identity_relation_partial_order (A : Type) : PartialOrder (Identity_relation A). 26 | Proof. 27 | repeat split. 28 | { 29 | intros x y z Hxy Hyz. 30 | inversion Hxy; inversion Hyz; subst; assumption. 31 | } 32 | { 33 | intros x y Hxy Hyx. 34 | inversion Hxy; inversion Hyx; subst; assumption. 35 | } 36 | Qed. 37 | 38 | 39 | Module bool_syntax. 40 | 41 | Inductive Sorts_t : Set := 42 | | SortBool 43 | . 44 | 45 | #[global] 46 | Instance Sorts_eqdec : EqDecision Sorts_t. 47 | Proof. solve_decision. Defined. 48 | 49 | #[global] 50 | Program Instance Sorts_finite : Finite Sorts_t := {| 51 | enum := [SortBool] ; 52 | |}. 53 | Next Obligation. compute_done. Qed. 54 | Next Obligation. destruct x; compute_done. Qed. 55 | Fail Next Obligation. 56 | 57 | Program Definition Sorts : OPMLSorts := {| 58 | opml_sort := Sorts_t ; 59 | opml_subsort := eq ; 60 | |}. 61 | Fail Next Obligation. 62 | 63 | Inductive Symbols_t : Set := 64 | | btrue 65 | | bfalse 66 | . 67 | 68 | #[global] 69 | Instance Symbols_t_eqdec : EqDecision Symbols_t. 70 | Proof. solve_decision. Defined. 71 | 72 | #[global] 73 | Program Instance Symbols_t_finite : Finite Symbols_t := {| 74 | enum := [btrue;bfalse] 75 | |}. 76 | Next Obligation. compute_done. Qed. 77 | Next Obligation. destruct x; compute_done. Qed. 78 | Fail Next Obligation. 79 | 80 | Definition Vars : @OPMLVariables Sorts := {| 81 | opml_evar := fun s => string; 82 | opml_svar := fun s => string; 83 | |}. 84 | Fail Next Obligation. 85 | 86 | Definition Symbols_t_arg_sorts (s : Symbols_t) : list (@opml_sort Sorts) := 87 | match s with 88 | | btrue => [] 89 | | bfalse => [] 90 | end 91 | . 92 | 93 | Definition Symbols_t_return_sort (s : Symbols_t) : @opml_sort Sorts := 94 | match s with 95 | | btrue => SortBool 96 | | bfalse => SortBool 97 | end 98 | . 99 | 100 | Definition Symbols : @OPMLSymbols Sorts := {| 101 | opml_symbol := Symbols_t ; 102 | opml_arg_sorts := Symbols_t_arg_sorts ; 103 | opml_ret_sort := Symbols_t_return_sort ; 104 | |}. 105 | 106 | #[global] 107 | Instance Σ : OPMLSignature := {| 108 | opml_sorts := Sorts ; 109 | opml_variables := Vars ; 110 | opml_symbols := Symbols ; 111 | |}. 112 | 113 | End bool_syntax. 114 | 115 | Module bool_common. 116 | 117 | Inductive Symbols_t : Set := 118 | | notBool 119 | | andBool 120 | | andThenBool 121 | | xorBool 122 | | orBool 123 | | orElseBool 124 | | impliesBool 125 | | equalsBool 126 | | notEqualsBool 127 | . 128 | 129 | #[global] 130 | Instance Symbols_t_eqdec : EqDecision Symbols_t. 131 | Proof. solve_decision. Defined. 132 | 133 | #[global] 134 | Program Instance Symbols_t_finite : Finite Symbols_t := {| 135 | enum := [notBool;andBool;andThenBool;xorBool;orBool;orElseBool;impliesBool;equalsBool;notEqualsBool] 136 | |}. 137 | Next Obligation. compute_done. Qed. 138 | Next Obligation. destruct x; compute_done. Qed. 139 | Fail Next Obligation. 140 | 141 | Definition extension_of_bool 142 | : @OPMLSignatureExtension 143 | (@opml_sorts bool_syntax.Σ) 144 | (@opml_variables bool_syntax.Σ) 145 | := {| 146 | ose_new_sort := Empty_set ; 147 | ose_new_sort_eqdec := _ ; 148 | ose_new_sort_countable := _ ; 149 | ose_new_subsort := Identity_relation Empty_set ; 150 | ose_new_subsort_po := _ ; 151 | ose_new_evar := fun _ => string ; 152 | ose_new_evar_eqdec := fun _ => _ ; 153 | ose_new_evar_countable := fun _ => _ ; 154 | ose_new_svar := fun _ => string ; 155 | ose_new_svar_eqdec := fun _ => _ ; 156 | ose_new_svar_countable := fun _ => _ ; 157 | ose_new_symbol := Symbols_t ; 158 | ose_new_sym_eqdec := _ ; 159 | ose_new_sym_countable := _ ; 160 | ose_new_arg_sorts := fun s => 161 | match s return list (Empty_set + bool_syntax.Sorts_t) with 162 | | notBool => [inr bool_syntax.SortBool] 163 | | andBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 164 | | andThenBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 165 | | xorBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 166 | | orBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 167 | | orElseBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 168 | | impliesBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 169 | | equalsBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 170 | | notEqualsBool => [inr bool_syntax.SortBool;inr bool_syntax.SortBool] 171 | end; 172 | ose_new_ret_sort := fun s => 173 | match s with 174 | | notBool => inr bool_syntax.SortBool 175 | | andBool => inr bool_syntax.SortBool 176 | | andThenBool => inr bool_syntax.SortBool 177 | | xorBool => inr bool_syntax.SortBool 178 | | orBool => inr bool_syntax.SortBool 179 | | orElseBool => inr bool_syntax.SortBool 180 | | impliesBool => inr bool_syntax.SortBool 181 | | equalsBool => inr bool_syntax.SortBool 182 | | notEqualsBool => inr bool_syntax.SortBool 183 | end; 184 | |}. 185 | 186 | Definition Σ : OPMLSignature := opml_signature_extend bool_syntax.Σ extension_of_bool. 187 | 188 | Definition bool_syntax_to_this : OPMLSignatureMorphism bool_syntax.Σ Σ 189 | := opml_signature_extend_morphism bool_syntax.Σ extension_of_bool 190 | . 191 | 192 | End bool_common. 193 | 194 | -------------------------------------------------------------------------------- /matching-logic/src/OPML/OpmlAmlRelSpec.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export ModelIsomorphism. 2 | From MatchingLogic.OPML Require Export OpmlSignature OpmlModel. 3 | 4 | Record OpmlAmlSigRel 5 | {Σo : OPMLSignature} {Σa : Signature} := { 6 | 7 | oasr_sym : opml_symbol -> symbols ; 8 | oasr_sym_inj : Inj (=) (=) oasr_sym ; 9 | 10 | oasr_no_junk : symbols; 11 | oasr_no_junk_distinct : 12 | forall s, oasr_sym s <> oasr_no_junk ; 13 | 14 | }. 15 | 16 | Record OpmlAmlModRel 17 | {Σo : OPMLSignature} 18 | {Σa : Signature} 19 | (Mo : OPMLModel) 20 | (Ma : Model) 21 | := { 22 | 23 | oamr_sig : OpmlAmlSigRel ; 24 | 25 | oamr_ele : 26 | om_unified_carrier Mo -> Domain Ma ; 27 | 28 | oamr_ele_inj : Inj (=) (=) oamr_ele ; 29 | 30 | (* The 'no_junk' symbol is interpreted as all the 'original' (OPML) model elements. *) 31 | oamr_no_junk : 32 | forall (ma : Domain Ma), 33 | ((ma ∈ (sym_interp Ma (oasr_no_junk oamr_sig))) 34 | <-> exists (mo : om_unified_carrier Mo), 35 | ma = oamr_ele mo 36 | ) 37 | ; 38 | }. 39 | 40 | Lemma oamr_no_junk_fmap 41 | {Σo : OPMLSignature} 42 | {Σa : Signature} 43 | (Mo : OPMLModel) 44 | (Ma : Model) 45 | (r : OpmlAmlModRel Mo Ma) 46 | : 47 | ((oamr_ele Mo Ma r) <$> (@propset_top (om_unified_carrier Mo))) ≡ (sym_interp Ma (oasr_no_junk (oamr_sig Mo Ma r))) 48 | . 49 | Proof. 50 | rewrite set_equiv. 51 | intros x. 52 | rewrite elem_of_fmap. 53 | rewrite oamr_no_junk. 54 | set_solver. 55 | Qed. 56 | 57 | Definition OpmlAmlModRel_preserves_isom 58 | {Σo : OPMLSignature} 59 | {Σa : Signature} 60 | (Mo : OPMLModel) 61 | (Ma : Model) 62 | (r : OpmlAmlModRel Mo Ma) 63 | := 64 | forall Mo' Ma', 65 | OPMLModelIsomorphism Mo Mo' -> 66 | @ModelIsomorphism _ Ma Ma' -> 67 | OpmlAmlModRel Mo' Ma' 68 | . 69 | 70 | 71 | -------------------------------------------------------------------------------- /matching-logic/src/OPML/OpmlModel.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic.Utils Require Export Surj. 2 | From MatchingLogic.OPML Require Export OpmlSignature. 3 | From stdpp Require Export propset. 4 | 5 | Polymorphic Cumulative 6 | Record OPMLModel {Σ : OPMLSignature} := { 7 | om_unified_carrier : 8 | Type ; 9 | 10 | om_carrier : 11 | opml_sort -> propset om_unified_carrier ; 12 | 13 | om_carrier_no_junk : 14 | forall (m : om_unified_carrier), 15 | exists (s : opml_sort), 16 | m ∈ om_carrier s ; 17 | 18 | om_subsort_1 : 19 | forall 20 | (from to : opml_sort) 21 | (subsort : opml_subsort from to), 22 | om_carrier from ⊆ om_carrier to ; 23 | 24 | (* not sure if the following is needed: *) 25 | (* 26 | om_subsort_2 : 27 | forall 28 | (from to : opml_sort) 29 | (not_subsort : not (opml_subsort from to)), 30 | om_carrier from ## om_carrier to ; 31 | *) 32 | 33 | om_app : 34 | opml_symbol -> 35 | list om_unified_carrier -> 36 | propset om_unified_carrier ; 37 | 38 | om_app_wellsorted : 39 | forall 40 | (sym : opml_symbol) 41 | (args : list om_unified_carrier) 42 | (args_ws : forall i arg sort, 43 | args !! i = Some arg -> 44 | (opml_arg_sorts sym) !! i = Some sort -> 45 | arg ∈ om_carrier sort 46 | ), 47 | (om_app sym args) ⊆ (om_carrier (opml_ret_sort sym)) ; 48 | }. 49 | 50 | Record OPMLModelIsomorphism {Σ : OPMLSignature} (M1 M2 : OPMLModel) := { 51 | omi_f : (om_unified_carrier M1) -> (om_unified_carrier M2) ; 52 | omi_inj :: Inj (=) (=) omi_f ; 53 | omi_surj :: Surj' (=) omi_f ; 54 | omi_app : 55 | ∀ (s : opml_symbol) (args : list (om_unified_carrier M1)), 56 | omi_f <$> (@om_app Σ M1 s args) ≡ @om_app Σ M2 s (omi_f <$> args) ; 57 | }. 58 | -------------------------------------------------------------------------------- /matching-logic/src/OPML/OpmlPattern.v: -------------------------------------------------------------------------------- 1 | (* From Coq Require Import ssreflect ssrfun ssrbool. *) 2 | From MatchingLogic.OPML Require Export OpmlSignature. 3 | From stdpp Require Export base list list_numbers. 4 | (* This is unset by stdpp. We need to set it again.*) 5 | Set Transparent Obligations. 6 | 7 | Set Default Proof Mode "Classic". 8 | 9 | (* De Bruijn indices for element and set variables*) 10 | Record Edbi := { edbi_n : nat; }. 11 | Record Sdbi := { sdbi_n : nat; }. 12 | 13 | Inductive OPMLPattern {Σ : OPMLSignature} := 14 | | op_upcast 15 | (from to : opml_sort) 16 | (subsort : opml_subsort from to) 17 | (φ : OPMLPattern) 18 | | op_bot (s : opml_sort) 19 | | op_bevar (dbi : Edbi) 20 | | op_bsvar (dbi : Sdbi) 21 | | op_fevar (s : opml_sort) (x : opml_evar s) 22 | | op_fsvar (s : opml_sort) (X : opml_svar s) 23 | | op_imp (φ1 φ2 : OPMLPattern) 24 | | op_app (s : opml_symbol) (args : list OPMLPattern) 25 | | op_ex (s : opml_sort) (φ : OPMLPattern) 26 | | op_mu (s : opml_sort) (φ : OPMLPattern) 27 | . 28 | 29 | Fixpoint OPMLPattern_size 30 | {Σ : OPMLSignature} 31 | (φ : OPMLPattern) 32 | : nat := 33 | match φ with 34 | | op_bot _ => 1 35 | | op_bevar _ => 1 36 | | op_bsvar _ => 1 37 | | op_fevar _ _ => 1 38 | | op_fsvar _ _ => 1 39 | | op_imp φ1 φ2 => 1 + OPMLPattern_size φ1 + OPMLPattern_size φ2 40 | | op_upcast _ _ _ φ' => 1 + OPMLPattern_size φ' 41 | | op_ex _ φ' => 1 + OPMLPattern_size φ' 42 | | op_mu _ φ' => 1 + OPMLPattern_size φ' 43 | | op_app s args => 1 + sum_list_with OPMLPattern_size args 44 | end. 45 | 46 | (* A better induction principle for OPMLPattern *) 47 | Lemma OPMLPattern_deep_ind 48 | {Σ : OPMLSignature} 49 | (P : OPMLPattern -> Prop) 50 | (Hupcast : 51 | forall 52 | (from to : opml_sort) 53 | (subsort : opml_subsort from to) 54 | (φ : OPMLPattern), 55 | P φ -> 56 | P (op_upcast from to subsort φ) 57 | ) 58 | (Hbot : 59 | forall s : opml_sort, 60 | P (op_bot s) 61 | ) 62 | (Hbe : 63 | forall dbi : Edbi, 64 | P (op_bevar dbi) 65 | ) 66 | (Hbs : 67 | forall dbi : Sdbi, 68 | P (op_bsvar dbi) 69 | ) 70 | (Hfe : 71 | forall 72 | (s : opml_sort) 73 | (x : opml_evar s), 74 | P (op_fevar s x) 75 | ) 76 | (Hfs : 77 | forall 78 | (s : opml_sort) 79 | (X : opml_svar s), 80 | P (op_fsvar s X) 81 | ) 82 | (Himp : 83 | forall 84 | φ1 : OPMLPattern, 85 | P φ1 -> 86 | forall 87 | φ2 : OPMLPattern, 88 | P φ2 -> P (op_imp φ1 φ2) 89 | ) 90 | (Happ : 91 | forall 92 | (s : opml_symbol) 93 | (args : list OPMLPattern), 94 | (forall φ'', φ'' ∈ args -> P φ'') -> 95 | P (op_app s args) 96 | ) 97 | (Hex : 98 | forall 99 | (s : opml_sort) 100 | (φ : OPMLPattern), 101 | P φ -> 102 | P (op_ex s φ) 103 | ) 104 | (Hmu : 105 | forall 106 | (s : opml_sort) 107 | (φ : OPMLPattern), 108 | P φ -> 109 | P (op_mu s φ) 110 | ): 111 | forall φ' : OPMLPattern, 112 | P φ' 113 | . 114 | Proof. 115 | intros φ'. 116 | remember (OPMLPattern_size φ') as sz. 117 | assert (Hsz: OPMLPattern_size φ' <= sz) by lia. 118 | clear Heqsz. 119 | revert φ' Hsz. 120 | induction sz; 121 | intros φ' Hsz. 122 | { 123 | destruct φ'; cbn in Hsz; exfalso; lia. 124 | } 125 | destruct φ'; cbn in Hsz. 126 | { apply Hupcast. apply IHsz. lia. } 127 | { apply Hbot. } 128 | { apply Hbe. } 129 | { apply Hbs. } 130 | { apply Hfe. } 131 | { apply Hfs. } 132 | { apply Himp; apply IHsz; lia. } 133 | { 134 | apply Happ. 135 | intros φ'' Hϕ''. 136 | apply IHsz. 137 | cut (OPMLPattern_size φ'' <= sum_list_with OPMLPattern_size args). 138 | { intros H. lia. } 139 | apply sum_list_with_in. 140 | exact Hϕ''. 141 | } 142 | { apply Hex. apply IHsz. lia. } 143 | { apply Hmu. apply IHsz. lia. } 144 | Qed. -------------------------------------------------------------------------------- /matching-logic/src/PatternContext.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Substitution. 2 | 3 | Import MatchingLogic.Substitution.Notations. 4 | 5 | Section with_signature. 6 | Context {Σ : Signature}. 7 | 8 | Record PatternCtx : Type := 9 | { pcEvar : evar ; 10 | pcPattern : Pattern; 11 | }. 12 | 13 | Definition is_linear_context (C : PatternCtx) := count_evar_occurrences (pcEvar C) (pcPattern C) = 1. 14 | 15 | Definition PC_wf C := well_formed (pcPattern C). 16 | 17 | Open Scope ml_scope. 18 | Definition emplace (ctx : PatternCtx) (p : Pattern) : Pattern := 19 | (pcPattern ctx)^[[evar: (pcEvar ctx) ↦ p]]. 20 | 21 | Definition is_positive_context (C : PatternCtx) := ~~ evar_has_negative_occurrence (pcEvar C) (pcPattern C). 22 | 23 | Definition is_negative_context (C : PatternCtx) := ~~ evar_has_positive_occurrence (pcEvar C) (pcPattern C). 24 | 25 | End with_signature. 26 | 27 | Module Notations. 28 | Notation "C [ p ]" := (emplace C p) (at level 90) : ml_scope. 29 | End Notations. 30 | -------------------------------------------------------------------------------- /matching-logic/src/ProofMode/FixPoint.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export FreshnessManager. 2 | From MatchingLogic.ProofMode Require Export Firstorder. 3 | 4 | Import MatchingLogic.Logic.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | 9 | Lemma mu_monotone_quantify {Σ : Signature} Γ ϕ₁ ϕ₂ X (i : ProofInfo): 10 | ProofInfoLe ( (ExGen := ∅, SVSubst := {[X]}, KT := true, AKT := ~~ bound_svar_is_banned_under_mus ϕ₁^{{svar:X↦0}} 0 0)) i -> 11 | svar_has_negative_occurrence X ϕ₁ = false -> 12 | svar_has_negative_occurrence X ϕ₂ = false -> 13 | Γ ⊢i ϕ₁ ---> ϕ₂ using i-> 14 | Γ ⊢i (patt_mu (ϕ₁^{{svar: X ↦ 0}})) ---> (patt_mu (ϕ₂^{{svar: X ↦ 0}})) 15 | using i. 16 | Proof. 17 | intros pile nonegϕ₁ nonegϕ₂ Himp. 18 | pose proof (wfϕ12 := proved_impl_wf _ _ (proj1_sig Himp)). 19 | assert(wfϕ₁ : well_formed ϕ₁) by wf_auto2. 20 | assert(wfϕ₂ : well_formed ϕ₂) by wf_auto2. 21 | 22 | apply Knaster_tarski. 23 | { try_solve_pile. } 24 | { 25 | wf_auto2. 26 | } 27 | 28 | pose proof (Htmp := @Svar_subst Σ Γ (ϕ₁ ---> ϕ₂) (mu, ϕ₂^{{svar: X ↦ 0}}) X i). 29 | ospecialize* Htmp. 30 | { try_solve_pile. } 31 | { wf_auto2. } 32 | { exact Himp. } 33 | unfold free_svar_subst in Htmp. 34 | simpl in Htmp. 35 | fold free_svar_subst in Htmp. 36 | 37 | pose proof (Hpf := Pre_fixp Γ (ϕ₂^{{svar: X ↦ 0}})). 38 | simpl in Hpf. 39 | 40 | unshelve (eapply (cast_proof' Γ _ _) in Hpf). 41 | 3: { 42 | erewrite bound_to_free_set_variable_subst. 43 | 5: { apply svar_quantify_not_free. } 44 | 4: { wf_auto2. } 45 | 3: { wf_auto2. } 46 | 2: lia. 47 | reflexivity. 48 | } 49 | 50 | 2: abstract (wf_auto2). 51 | 52 | eapply (cast_proof' Γ) in Hpf. 53 | 2: { wf_auto2. } 54 | 55 | 56 | assert(well_formed_positive (ϕ₂^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) = true). 57 | { wf_auto2. } 58 | 59 | assert(well_formed_closed_mu_aux (ϕ₂^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) 0 = true). { wf_auto2. } 60 | 61 | assert(well_formed_closed_ex_aux (ϕ₂^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) 0 = true). { wf_auto2. } 62 | 63 | assert(well_formed_positive (ϕ₁^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) = true). 64 | { wf_auto2. } 65 | 66 | assert(well_formed_closed_mu_aux (ϕ₁^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) 0 = true). { wf_auto2. } 67 | 68 | assert(well_formed_closed_ex_aux (ϕ₁^[[svar: X ↦ mu , ϕ₂^{{svar: X ↦ 0}}]]) 0 = true). { wf_auto2. } 69 | 70 | apply useBasicReasoning with (i := i) in Hpf. 71 | rewrite svar_open_svar_quantify in Hpf. wf_auto2. 72 | epose proof (Hsi := syllogism_meta _ _ _ Htmp Hpf). 73 | simpl. 74 | 75 | eapply (@cast_proof' Σ Γ). 76 | 1: { 77 | erewrite bound_to_free_set_variable_subst with (X := X). 78 | 5: { apply svar_quantify_not_free. } 79 | 4: { wf_auto2. } 80 | 3: { wf_auto2. } 81 | 2: lia. 82 | reflexivity. 83 | } 84 | 85 | eapply (cast_proof' Γ). 86 | 1: { wf_auto2. } 87 | rewrite svar_open_svar_quantify. wf_auto2. 88 | apply Hsi. 89 | Unshelve. 90 | all: abstract(wf_auto2). 91 | Defined. 92 | 93 | Lemma mu_monotone {Σ : Signature} Γ ϕ₁ ϕ₂ X (i : ProofInfo): 94 | ProofInfoLe ( (ExGen := ∅, SVSubst := {[X]}, KT := true, AKT := ~~ bound_svar_is_banned_under_mus ϕ₁ 0 0)) i -> 95 | well_formed (patt_mu ϕ₁) -> 96 | well_formed (patt_mu ϕ₂) -> 97 | X ∉ free_svars ϕ₁ ∪ free_svars ϕ₂ -> 98 | Γ ⊢i ϕ₁^{svar:0↦X} ---> ϕ₂^{svar:0↦X} using i-> 99 | Γ ⊢i (patt_mu ϕ₁) ---> (patt_mu ϕ₂) 100 | using i. 101 | Proof. 102 | intros. 103 | apply mu_monotone_quantify with (X := X) in H3. 104 | * rewrite svar_quantify_svar_open in H3. set_solver. wf_auto2. 105 | rewrite svar_quantify_svar_open in H3. set_solver. wf_auto2. 106 | assumption. 107 | * rewrite svar_quantify_svar_open. set_solver. wf_auto2. assumption. 108 | * apply positive_negative_occurrence_db_named. 109 | wf_auto2. 110 | wf_auto2. 111 | unfold svar_is_fresh_in. set_solver. 112 | * apply positive_negative_occurrence_db_named. 113 | wf_auto2. 114 | wf_auto2. 115 | unfold svar_is_fresh_in. set_solver. 116 | Defined. 117 | 118 | Lemma mu_iff_quantify {Σ : Signature} Γ ϕ₁ ϕ₂ X (i : ProofInfo): 119 | ProofInfoLe ( (ExGen := ∅, SVSubst := {[X]}, KT := true, AKT := true)) i -> 120 | svar_has_negative_occurrence X ϕ₁ = false -> 121 | svar_has_negative_occurrence X ϕ₂ = false -> 122 | Γ ⊢i ϕ₁ <---> ϕ₂ using i-> 123 | Γ ⊢i (patt_mu (ϕ₁^{{svar: X ↦ 0}})) <---> (patt_mu (ϕ₂^{{svar: X ↦ 0}})) 124 | using i. 125 | Proof. 126 | intros. 127 | 128 | apply pf_iff_split. 129 | { wf_auto2. } 130 | { wf_auto2. } 131 | { 132 | apply mu_monotone_quantify; try assumption. 133 | { try_solve_pile. } 134 | { 135 | apply pf_iff_proj1 in H2. 136 | { exact H2. } 137 | { wf_auto2. } 138 | { wf_auto2. } 139 | } 140 | } 141 | { 142 | apply mu_monotone_quantify; try assumption. 143 | { try_solve_pile. } 144 | { 145 | apply pf_iff_proj2 in H2. 146 | { exact H2. } 147 | { wf_auto2. } 148 | { wf_auto2. } 149 | } 150 | } 151 | Defined. 152 | 153 | Lemma move_mu_under_implication 154 | {Σ : Signature} 155 | Γ φ ψ : 156 | well_formed φ -> 157 | well_formed (mu , ψ) -> 158 | Γ ⊢i φ ---> (mu , ψ) ---> mu , (φ ---> ψ) using 159 | (ExGen := ∅, 160 | SVSubst := ∅, 161 | KT := true, 162 | AKT := ~~ bound_svar_is_banned_under_mus ψ 0 0). 163 | Proof. 164 | intros. 165 | assert (no_positive_occurrence_db_b 0 φ). { 166 | (* TODO: wf_auto2 breaks without this assert later! *) 167 | wf_auto2. 168 | } 169 | do 2 mlIntro. 170 | mlApplyMeta (Knaster_tarski Γ ψ (mu, φ ---> ψ)) in "1". 171 | 2: { 172 | toMLGoal. { 173 | wf_auto2. 174 | } 175 | mlIntro; mlApplyMeta Pre_fixp. simpl. 176 | mlIntro. mlAssumption. 177 | } 178 | mlAssumption. 179 | Defined. 180 | -------------------------------------------------------------------------------- /matching-logic/src/ProofMode/MLPM.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic.ProofMode Require Export Basics 2 | Propositional 3 | Firstorder 4 | FixPoint 5 | Reshaper 6 | Misc. 7 | 8 | (** Importing this file opens the necessary scope for the proof mode to work 9 | properly! *) 10 | Open Scope ml_scope. 11 | Open Scope string_scope. 12 | Open Scope list_scope. 13 | 14 | Export MatchingLogic.Logic.Notations. 15 | 16 | Set Default Proof Mode "Classic". 17 | -------------------------------------------------------------------------------- /matching-logic/src/ProofSystem.v: -------------------------------------------------------------------------------- 1 | From Ltac2 Require Import Ltac2. 2 | From MatchingLogic Require Export Syntax 3 | DerivedOperators_Syntax. 4 | 5 | Import MatchingLogic.Syntax.Notations. 6 | Import MatchingLogic.Substitution.Notations. 7 | Import MatchingLogic.DerivedOperators_Syntax.Notations. 8 | 9 | Set Default Proof Mode "Classic". 10 | 11 | Section ml_proof_system. 12 | Open Scope ml_scope. 13 | 14 | Context {Σ : Signature}. 15 | 16 | (* Proof system for AML ref. snapshot: Section 3 *) 17 | 18 | Reserved Notation "theory ⊢H pattern" (at level 76). 19 | Inductive ML_proof_system (theory : Theory) : 20 | Pattern -> Set := 21 | 22 | (* Hypothesis *) 23 | | ML_hypothesis (axiom : Pattern) : 24 | well_formed axiom -> 25 | (axiom ∈ theory) -> theory ⊢H axiom 26 | 27 | (* FOL reasoning *) 28 | (* Propositional tautology *) 29 | | ML_P1 (phi psi : Pattern) : 30 | well_formed phi -> well_formed psi -> 31 | theory ⊢H (phi ---> (psi ---> phi)) 32 | | ML_P2 (phi psi xi : Pattern) : 33 | well_formed phi -> well_formed psi -> well_formed xi -> 34 | theory ⊢H ((phi ---> (psi ---> xi)) ---> ((phi ---> psi) ---> (phi ---> xi))) 35 | | ML_P3 (phi : Pattern) : 36 | well_formed phi -> 37 | theory ⊢H (((phi ---> ⊥) ---> ⊥) ---> phi) 38 | 39 | (* Modus ponens *) 40 | | ML_Modus_ponens (phi1 phi2 : Pattern) : 41 | theory ⊢H phi1 -> 42 | theory ⊢H (phi1 ---> phi2) -> 43 | theory ⊢H phi2 44 | 45 | (* Existential quantifier *) 46 | | ML_Ex_quan (phi : Pattern) (y : evar) : 47 | well_formed (patt_exists phi) -> 48 | theory ⊢H (instantiate (patt_exists phi) (patt_free_evar y) ---> (patt_exists phi)) 49 | 50 | (* Existential generalization *) 51 | | ML_Ex_gen (phi1 phi2 : Pattern) (x : evar) : 52 | well_formed phi1 -> well_formed phi2 -> 53 | theory ⊢H (phi1 ---> phi2) -> 54 | x ∉ (free_evars phi2) -> 55 | theory ⊢H (exists_quantify x phi1 ---> phi2) 56 | 57 | (* Frame reasoning *) 58 | (* Propagation bottom *) 59 | | ML_Prop_bott_left (phi : Pattern) : 60 | well_formed phi -> 61 | theory ⊢H (⊥ ⋅ phi ---> ⊥) 62 | 63 | | ML_Prop_bott_right (phi : Pattern) : 64 | well_formed phi -> 65 | theory ⊢H (phi ⋅ ⊥ ---> ⊥) 66 | 67 | (* Propagation disjunction *) 68 | | ML_Prop_disj_left (phi1 phi2 psi : Pattern) : 69 | well_formed phi1 -> well_formed phi2 -> well_formed psi -> 70 | theory ⊢H (((phi1 or phi2) ⋅ psi) ---> ((phi1 ⋅ psi) or (phi2 ⋅ psi))) 71 | 72 | | ML_Prop_disj_right (phi1 phi2 psi : Pattern) : 73 | well_formed phi1 -> well_formed phi2 -> well_formed psi -> 74 | theory ⊢H ((psi ⋅ (phi1 or phi2)) ---> ((psi ⋅ phi1) or (psi ⋅ phi2))) 75 | 76 | (* Propagation exist *) 77 | | ML_Prop_ex_left (phi psi : Pattern) : 78 | well_formed (ex , phi) -> well_formed psi -> 79 | theory ⊢H (((ex , phi) ⋅ psi) ---> (ex , phi ⋅ psi)) 80 | 81 | | ML_Prop_ex_right (phi psi : Pattern) : 82 | well_formed (ex , phi) -> well_formed psi -> 83 | theory ⊢H ((psi ⋅ (ex , phi)) ---> (ex , psi ⋅ phi)) 84 | 85 | (* Framing *) 86 | | ML_Framing_left (phi1 phi2 psi : Pattern) : 87 | well_formed psi -> 88 | theory ⊢H (phi1 ---> phi2) -> 89 | theory ⊢H ((phi1 ⋅ psi) ---> (phi2 ⋅ psi)) 90 | 91 | | ML_Framing_right (phi1 phi2 psi : Pattern) : 92 | well_formed psi -> 93 | theory ⊢H (phi1 ---> phi2) -> 94 | theory ⊢H ((psi ⋅ phi1) ---> (psi ⋅ phi2)) 95 | 96 | (* Fixpoint reasoning *) 97 | (* Set Variable Substitution *) 98 | | ML_Svar_subst (phi psi : Pattern) (X : svar) : 99 | well_formed phi -> well_formed psi -> 100 | theory ⊢H phi -> theory ⊢H (phi^[[svar: X ↦ psi]]) 101 | 102 | (* Pre-Fixpoint *) 103 | | ML_Pre_fixp (phi : Pattern) : 104 | well_formed (patt_mu phi) -> 105 | theory ⊢H (instantiate (patt_mu phi) (patt_mu phi) ---> (patt_mu phi)) 106 | 107 | (* Knaster-Tarski *) 108 | | ML_Knaster_tarski (phi psi : Pattern) : 109 | well_formed (patt_mu phi) -> 110 | theory ⊢H ((instantiate (patt_mu phi) psi) ---> psi) -> 111 | theory ⊢H ((@patt_mu Σ phi) ---> psi) 112 | 113 | (* Technical rules *) 114 | (* Existence *) 115 | | ML_Existence : theory ⊢H (ex , patt_bound_evar 0) 116 | 117 | (* Singleton *) 118 | | ML_Singleton_ctx (C1 C2 : Application_context) (phi : Pattern) (x : evar) : 119 | well_formed phi -> 120 | theory ⊢H (! ((subst_ctx C1 (patt_free_evar x and phi)) and 121 | (subst_ctx C2 (patt_free_evar x and (! phi))))) 122 | 123 | where "theory ⊢H pattern" := (ML_proof_system theory pattern). 124 | 125 | Instance ML_proof_system_eqdec: forall gamma phi, EqDecision (ML_proof_system gamma phi). 126 | Proof. intros. intros x y. 127 | unfold Decision. Fail decide equality. 128 | Abort. 129 | 130 | Lemma proved_impl_wf Γ ϕ: 131 | Γ ⊢H ϕ -> well_formed ϕ. 132 | Proof. 133 | intros pf. 134 | induction pf; wf_auto2. 135 | Qed. 136 | 137 | Lemma cast_proof {Γ} {ϕ} {ψ} (e : ψ = ϕ) : ML_proof_system Γ ϕ -> ML_proof_system Γ ψ. 138 | Proof. intros H. rewrite <- e in H. exact H. Defined. 139 | 140 | Theorem Private_extend_theory (Γ Γ' : Theory) φ : 141 | Γ ⊆ Γ' -> 142 | Γ ⊢H φ -> 143 | Γ' ⊢H φ. 144 | Proof. 145 | intros H IH. revert Γ' H. induction IH; intros; try now constructor. 146 | * constructor. assumption. set_solver. 147 | * eapply ML_Modus_ponens; [apply IHIH1; assumption | apply IHIH2; assumption]. 148 | * apply ML_Ex_gen; try assumption. now apply IHIH. 149 | * apply ML_Framing_left. assumption. now apply IHIH. 150 | * apply ML_Framing_right. assumption. now apply IHIH. 151 | * apply ML_Svar_subst; try assumption. now apply IHIH. 152 | * apply ML_Knaster_tarski; try assumption. now apply IHIH. 153 | Defined. 154 | 155 | End ml_proof_system. 156 | 157 | Module Notations_private. 158 | 159 | Notation "theory ⊢H pattern" := (ML_proof_system theory pattern) (at level 95, no associativity). 160 | 161 | End Notations_private. 162 | -------------------------------------------------------------------------------- /matching-logic/src/Signature.v: -------------------------------------------------------------------------------- 1 | From Coq Require Export ssrbool. 2 | From Coq Require Export String. 3 | 4 | From stdpp Require Export countable infinite list finite. 5 | 6 | 7 | 8 | Class MLVariables := { 9 | evar : Set; 10 | svar : Set; 11 | evar_eqdec :: EqDecision evar; 12 | evar_countable :: Countable evar; 13 | evar_infinite :: Infinite evar; 14 | svar_eqdec :: EqDecision svar; 15 | svar_countable :: Countable svar; 16 | svar_infinite :: Infinite svar; 17 | 18 | string2evar : string -> evar ; 19 | string2evar_inj :: Inj (=) (=) string2evar ; 20 | string2svar : string -> svar ; 21 | string2svar_inj :: Inj (=) (=) string2svar ; 22 | 23 | }. 24 | 25 | Class MLSymbols := { 26 | symbols : Set; 27 | sym_eqdec :: EqDecision symbols; 28 | sym_countable :: Countable symbols; 29 | }. 30 | 31 | Class Signature := { 32 | variables :: MLVariables; 33 | ml_symbols :: MLSymbols; 34 | }. 35 | 36 | (* Later we will define signature morphisms in some file *) 37 | -------------------------------------------------------------------------------- /matching-logic/src/StringSignature.v: -------------------------------------------------------------------------------- 1 | Require Export MatchingLogic.Signature. 2 | 3 | Definition StringMLVariables : MLVariables := 4 | {| evar := string; 5 | svar := string; 6 | string2evar := @id string; 7 | string2svar := @id string; 8 | |}. 9 | -------------------------------------------------------------------------------- /matching-logic/src/SyntaxLemmas/ApplicationCtxSubstitution.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export ApplicationContext 2 | Substitution. 3 | 4 | Import MatchingLogic.Substitution.Notations. 5 | 6 | Section with_signature. 7 | Open Scope ml_scope. 8 | Context {Σ : Signature}. 9 | 10 | Lemma free_evar_subst_subst_ctx_independent AC ϕ Xfr1 Xfr2: 11 | Xfr1 ∉ free_evars_ctx AC -> 12 | Xfr2 ∉ free_evars_ctx AC -> 13 | (subst_ctx AC (patt_free_evar Xfr1))^[[evar: Xfr1 ↦ ϕ]] = 14 | (subst_ctx AC (patt_free_evar Xfr2))^[[evar: Xfr2 ↦ ϕ]]. 15 | Proof. 16 | intros HXfr1 HXfr2. 17 | induction AC. 18 | - simpl. 19 | destruct (decide (Xfr1 = Xfr1)), (decide (Xfr2 = Xfr2)); simpl; try contradiction. 20 | reflexivity. 21 | - simpl in HXfr1. simpl in HXfr2. 22 | ospecialize* IHAC. 23 | { set_solver. } 24 | { set_solver. } 25 | simpl. rewrite IHAC. 26 | rewrite [p^[[evar: Xfr1 ↦ ϕ]]]free_evar_subst_no_occurrence. 27 | { set_solver. } 28 | rewrite [p^[[evar: Xfr2 ↦ ϕ]]]free_evar_subst_no_occurrence. 29 | { set_solver. } 30 | reflexivity. 31 | - simpl in HXfr1. simpl in HXfr2. 32 | ospecialize* IHAC. 33 | { set_solver. } 34 | { set_solver. } 35 | simpl. rewrite IHAC. 36 | rewrite [p^[[evar: Xfr1 ↦ ϕ]]]free_evar_subst_no_occurrence. 37 | { set_solver. } 38 | rewrite [p^[[evar: Xfr2 ↦ ϕ]]]free_evar_subst_no_occurrence. 39 | { set_solver. } 40 | reflexivity. 41 | Qed. 42 | 43 | End with_signature. 44 | -------------------------------------------------------------------------------- /matching-logic/src/SyntaxLemmas/FreshnessApplicationCtx.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Substitution 2 | Freshness 3 | ApplicationContext. 4 | 5 | Import Substitution.Notations. 6 | 7 | Section lemmas. 8 | Context {Σ : Signature}. 9 | Open Scope ml_scope. 10 | 11 | Lemma evar_is_fresh_in_subst_ctx x AC p: 12 | evar_is_fresh_in x (subst_ctx AC p) 13 | <-> (evar_is_fresh_in x p /\ x ∉ AC_free_evars AC). 14 | Proof. 15 | induction AC. 16 | - simpl. split; set_solver. 17 | - simpl. split; intros H. 18 | + assert (Hfr1: evar_is_fresh_in x (subst_ctx AC p)). 19 | { eapply evar_is_fresh_in_richer. 2: apply H. cbn. set_solver. } 20 | assert (Hfr2: evar_is_fresh_in x p0). 21 | { eapply evar_is_fresh_in_richer. 2: apply H. cbn. set_solver. } 22 | rewrite -> IHAC in Hfr1. 23 | split; [apply Hfr1|]. 24 | clear -Hfr1 Hfr2. 25 | unfold evar_is_fresh_in in Hfr2. 26 | set_solver. 27 | + destruct H as [H1 H2]. 28 | rewrite -> evar_is_fresh_in_app. 29 | split. 30 | * rewrite -> IHAC. set_solver. 31 | * unfold evar_is_fresh_in. set_solver. 32 | - simpl. split; intros H. 33 | + assert (Hfr1: evar_is_fresh_in x (subst_ctx AC p)). 34 | { eapply evar_is_fresh_in_richer. 2: apply H. cbn. set_solver. } 35 | assert (Hfr2: evar_is_fresh_in x p0). 36 | { eapply evar_is_fresh_in_richer. 2: apply H. cbn. set_solver. } 37 | rewrite -> IHAC in Hfr1. 38 | split; [apply Hfr1|]. 39 | clear -Hfr1 Hfr2. 40 | unfold evar_is_fresh_in in Hfr2. 41 | set_solver. 42 | + destruct H as [H1 H2]. 43 | rewrite -> evar_is_fresh_in_app. 44 | split. 45 | * unfold evar_is_fresh_in. set_solver. 46 | * rewrite -> IHAC. set_solver. 47 | Qed. 48 | 49 | 50 | Lemma wf_ex_eq_sctx_eo AC x p: 51 | well_formed (patt_exists p) = true -> 52 | well_formed (patt_exists ((subst_ctx AC (p^{evar: 0 ↦ x}))^{{evar: x ↦ 0}})) = true. 53 | Proof. 54 | intros Hwf. 55 | unfold well_formed in Hwf. 56 | apply andb_prop in Hwf. 57 | destruct Hwf as [Hwfp Hwfc]. 58 | simpl in Hwfp. 59 | unfold well_formed. 60 | apply andb_true_intro. 61 | split. 62 | - simpl. apply evar_quantify_positive. 63 | apply wp_sctx. 64 | apply wfp_evar_open. 65 | apply Hwfp. 66 | - unfold well_formed_closed. 67 | simpl. 68 | unfold well_formed_closed in *. 69 | destruct_andb! Hwfc. 70 | apply andb_true_iff; split. 71 | + apply evar_quantify_closed_mu. apply wcmu_sctx. 72 | apply wfc_mu_aux_body_ex_imp1. simpl in *. assumption. 73 | + apply evar_quantify_closed_ex. apply wcex_sctx. 74 | apply wfc_ex_aux_body_ex_imp1. simpl in *. assumption. 75 | Qed. 76 | 77 | 78 | Lemma subst_ctx_bevar_subst AC p q n: 79 | subst_ctx AC (p^[evar: n ↦ q]) = (subst_ctx AC p)^[evar: n ↦ q]. 80 | Proof. 81 | induction AC. 82 | - reflexivity. 83 | - simpl. rewrite IHAC. clear IHAC. 84 | rewrite [p0^[evar: n ↦ q] ]bevar_subst_not_occur. 85 | 2: { reflexivity. } 86 | unfold well_formed,well_formed_closed in Prf. 87 | destruct_andb! Prf. 88 | auto. eapply well_formed_closed_ex_aux_ind. 2: exact H2. lia. 89 | - simpl. rewrite IHAC. clear IHAC. 90 | rewrite [p0^[evar: n ↦ q] ]bevar_subst_not_occur. 91 | 2: { reflexivity. } 92 | unfold well_formed,well_formed_closed in Prf. 93 | destruct_andb! Prf. 94 | auto. eapply well_formed_closed_ex_aux_ind. 2: exact H2. lia. 95 | Qed. 96 | 97 | End lemmas. -------------------------------------------------------------------------------- /matching-logic/src/Tests/TEST_ProofMode_relative_completeness.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Import Logic ProofMode.MLPM. 2 | 3 | Import 4 | MatchingLogic.Logic.Notations 5 | MatchingLogic.DerivedOperators_Syntax.Notations 6 | . 7 | 8 | Set Default Proof Mode "Classic". 9 | 10 | Section with_signature. 11 | 12 | Context {Σ : Signature}. 13 | 14 | Local Lemma P1_complete (Γ : Theory) (ϕ ψ : Pattern): 15 | well_formed ϕ -> well_formed ψ -> 16 | mkMLGoal _ Γ [] (ϕ ---> ψ ---> ϕ) BasicReasoning. 17 | Proof. 18 | intros. 19 | do 2 mlIntro. mlAssumption. 20 | Qed. 21 | 22 | Local Lemma P2_complete (Γ : Theory) (ϕ ψ ξ : Pattern): 23 | well_formed ϕ -> well_formed ψ -> well_formed ξ -> 24 | mkMLGoal _ Γ [] ((ϕ ---> ψ ---> ξ) ---> (ϕ ---> ψ) ---> ϕ ---> ξ) BasicReasoning. 25 | Proof. 26 | intros. 27 | do 3 mlIntro. 28 | mlApply "0". mlSplitAnd. 29 | * mlAssumption. 30 | * mlApply "1". mlAssumption. 31 | Qed. 32 | 33 | Local Lemma P3_complete Γ ϕ : 34 | well_formed ϕ -> 35 | mkMLGoal _ Γ [] (! ! ϕ ---> ϕ) BasicReasoning. 36 | Proof. 37 | intros. 38 | mlIntro. 39 | mlAssert ("H" : (ϕ or ! ϕ)). wf_auto2. 40 | { mlIntro. mlAssumption. } 41 | mlDestructOr "H". 42 | * mlAssumption. 43 | * mlExFalso. mlApply "0". mlAssumption. 44 | Qed. 45 | 46 | Local Lemma MP_complete Γ ϕ ψ i: 47 | well_formed ϕ -> well_formed ψ -> 48 | mkMLGoal _ Γ [] ϕ i -> mkMLGoal _ Γ [] (ϕ ---> ψ) i -> 49 | mkMLGoal _ Γ [] ψ i. 50 | Proof. 51 | intros. 52 | mlAssert ("H" : (ϕ and (ϕ ---> ψ))). wf_auto2. 53 | { mlSplitAnd; assumption. } 54 | mlDestructAnd "H". 55 | mlApply "1". mlAssumption. 56 | Qed. 57 | 58 | Local Lemma Ex_quan_complete (Γ : Theory) (ϕ : Pattern) (y : evar): 59 | well_formed (ex , ϕ) -> 60 | mkMLGoal _ Γ [] ((ex , ϕ)^[patt_free_evar y] ---> (ex , ϕ)) BasicReasoning. 61 | Proof. 62 | intros. mlIntro "H". 63 | unfold instantiate. 64 | mlExists y. mlAssumption. 65 | Qed. 66 | 67 | Local Lemma Ex_gen_complete (Γ : Theory) (ϕ₁ ϕ₂ : Pattern) (x : evar) (i : ProofInfo): 68 | well_formed ϕ₁ -> well_formed ϕ₂ -> 69 | ProofInfoLe (ExGen := {[x]}, SVSubst := ∅, KT := false, AKT := false) i -> 70 | x ∉ free_evars ϕ₂ -> 71 | mkMLGoal _ Γ [] (ϕ₁ ---> ϕ₂) i -> 72 | mkMLGoal _ Γ [] (exists_quantify x ϕ₁ ---> ϕ₂) i. 73 | Proof. 74 | unfold exists_quantify. intros. 75 | mlIntro "H0". 76 | mlDestructEx "H0" as x. 1-4: cbn; try set_solver. 77 | { apply evar_quantify_no_occurrence. } 78 | rewrite evar_open_evar_quantify. wf_auto2. 79 | mlRevertLast. assumption. 80 | Qed. 81 | 82 | End with_signature. 83 | -------------------------------------------------------------------------------- /matching-logic/src/Tests/TEST_proofmode_example.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic.Theories Require Import Definedness_Semantics 2 | Sorts_Syntax 3 | Definedness_ProofSystem. 4 | From MatchingLogic.Utils Require Import stdpp_ext. 5 | 6 | Import MatchingLogic.Logic.Notations. 7 | Import MatchingLogic.Theories.Definedness_Syntax.Notations. 8 | Import MatchingLogic.Semantics.Notations. 9 | Import MatchingLogic.DerivedOperators_Syntax.Notations. 10 | Set Default Proof Mode "Classic". 11 | 12 | Close Scope equations_scope. (* Because of [!] *) 13 | 14 | Lemma membership_var {Σ : Signature} {syntax : Syntax} : 15 | forall x y Γ, 16 | theory ⊆ Γ -> 17 | Γ ⊢ patt_free_evar y ∈ml patt_free_evar x ---> patt_free_evar y =ml patt_free_evar x. 18 | Proof. 19 | intros x y Γ HΓ. 20 | 21 | remember (patt_free_evar x) as pX. assert (well_formed pX) by (rewrite HeqpX;auto). 22 | remember (patt_free_evar y) as pY. assert (well_formed pY) by (rewrite HeqpY;auto). 23 | toMLGoal. wf_auto2. 24 | unfold patt_equal, patt_iff. 25 | pose proof (patt_total_and Γ (pY ---> pX) (pX ---> pY) HΓ 26 | ltac:(wf_auto2) ltac:(wf_auto2)) as H1. 27 | use AnyReasoning in H1. 28 | mlRewrite H1 at 1. 29 | mlIntro "H0". 30 | mlIntro "H1". 31 | mlDestructOr "H1" as "H1'" "H1'". 32 | * mlApply "H1'". 33 | mlClear "H1'". 34 | mlIntro "H2". 35 | pose proof (MH := nimpl_eq_and Γ pY pX 36 | ltac:(wf_auto2) ltac:(wf_auto2)). 37 | use AnyReasoning in MH. 38 | mlRevertLast. 39 | mlRewrite MH at 1. 40 | (* TODO: it is increadibly inconvienient to define concrete contexts *) 41 | unshelve (epose proof (MH1 := @Singleton_ctx _ Γ 42 | (⌈_⌉ $ᵣ □) 43 | (⌈_⌉ $ᵣ □) pX y ltac:(wf_auto2))). 1-2: wf_auto2. 44 | rewrite -HeqpY in MH1. 45 | use AnyReasoning in MH1. simpl in MH1. 46 | (* TODO: having mlExactMeta would help here *) 47 | mlIntro "H2". 48 | mlApplyMeta MH1. 49 | mlSplitAnd. 50 | ** mlExact "H0". 51 | ** mlExact "H2". 52 | * mlApply "H1'". 53 | mlClear "H1'". 54 | mlIntro "H2". 55 | pose proof (MH := nimpl_eq_and Γ pX pY 56 | ltac:(wf_auto2) ltac:(wf_auto2)). 57 | mlRevertLast. use AnyReasoning in MH. mlRewrite MH at 1. 58 | pose proof (MH1 := @patt_and_comm _ Γ pY pX ltac:(wf_auto2) ltac:(wf_auto2)). 59 | mlRevertLast. use AnyReasoning in MH1. 60 | unfold patt_in. 61 | mlRewrite MH1 at 1. 62 | unshelve (epose proof (@Singleton_ctx _ Γ 63 | (⌈_⌉ $ᵣ □) 64 | (⌈_⌉ $ᵣ □) pY x ltac:(wf_auto2)) as MH2). 1-2: wf_auto2. 65 | rewrite -HeqpX in MH2. 66 | use AnyReasoning in MH2. 67 | mlIntro "H1". mlIntro "H2". 68 | mlApplyMeta MH2. simpl. mlSplitAnd. mlExact "H1". mlExact "H2". 69 | Defined. 70 | -------------------------------------------------------------------------------- /matching-logic/src/Theories/Bool_Semantics.v: -------------------------------------------------------------------------------- 1 | From Coq Require Import Classes.Morphisms_Prop. 2 | From MatchingLogic Require Export Sorts_Semantics 3 | Bool_Syntax. 4 | Import MatchingLogic.Logic.Notations 5 | MatchingLogic.Theories.Definedness_Syntax.Notations 6 | MatchingLogic.Theories.Sorts_Syntax.Notations. 7 | 8 | Section with_model. 9 | Context 10 | {Σ : Signature} 11 | {syntax : Bool_Syntax.Syntax} 12 | {M : Model}. 13 | Open Scope ml_scope. 14 | 15 | Hypothesis M_satisfies_theory : M ⊨ᵀ Bool_Syntax.theory. 16 | 17 | End with_model. 18 | 19 | (* Section bool_model. 20 | 21 | Instance default_boolΣ : Signature := { 22 | variables := StringMLVariables; 23 | ml_symbols := Build_MLSymbols Symbols _ _; 24 | }. 25 | 26 | Instance default_bool_syntax : Bool_Syntax.Syntax := { 27 | inj := id; 28 | imported_sorts := 29 | }. 30 | 31 | End bool_model. *) -------------------------------------------------------------------------------- /matching-logic/src/Theories/Bool_Syntax.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_Syntax. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Inductive Symbols : Set := 9 | | sBool 10 | | sTrue 11 | | sFalse 12 | | sAnd 13 | | sNeg 14 | | sAndThen. 15 | 16 | Global Instance Symbols_eqdec : EqDecision Symbols. 17 | Proof. unfold EqDecision. intros x y. unfold Decision. destruct x; decide equality. (*solve_decision.*) Defined. 18 | 19 | #[global] 20 | Program Instance Symbols_finite : finite.Finite Symbols. 21 | Next Obligation. 22 | exact [sBool; sTrue; sFalse; sAnd; sNeg; sAndThen]. 23 | Defined. 24 | Next Obligation. 25 | unfold Symbols_finite_obligation_1. 26 | compute_done. 27 | Defined. 28 | Next Obligation. 29 | destruct x; compute_done. 30 | Defined. 31 | 32 | Global Instance Symbols_countable : countable.Countable Symbols. 33 | Proof. apply finite.finite_countable. Defined. 34 | 35 | Section bool_syntax. 36 | Context {Σ : Signature}. 37 | 38 | Class Syntax := 39 | { sym_inj : Symbols -> symbols; 40 | imported_sorts : Sorts_Syntax.Syntax; 41 | }. 42 | 43 | #[global] Existing Instance imported_definedness. 44 | #[global] Existing Instance imported_sorts. 45 | 46 | Context {self : Syntax}. 47 | 48 | Definition mlBool := patt_sym (sym_inj sBool). 49 | Definition mlTrue := patt_sym (sym_inj sTrue). 50 | Definition mlFalse := patt_sym (sym_inj sFalse). 51 | Definition mlsBAnd := patt_sym (sym_inj sAnd). 52 | Definition mlsBNeg := patt_sym (sym_inj sNeg). 53 | Definition mlsBAndThen := patt_sym (sym_inj sAndThen). 54 | 55 | Definition mlBAnd (φ1 φ2 : Pattern) : Pattern := 56 | mlsBAnd ⋅ φ1 ⋅ φ2. 57 | Definition mlBNeg (φ : Pattern) : Pattern := 58 | mlsBNeg ⋅ φ. 59 | Definition mlBAndThen ( φ1 φ2 : Pattern) : Pattern := 60 | mlsBAndThen ⋅ φ1 ⋅ φ2. 61 | 62 | End bool_syntax. 63 | 64 | Section bools. 65 | Context {Σ : Signature}. 66 | Context {self : Syntax}. 67 | Open Scope ml_scope. 68 | 69 | Obligation Tactic := idtac. 70 | 71 | #[global] 72 | Program Instance Unary_inhabitant_set : Unary mlBNeg := {}. 73 | Next Obligation. 74 | intros. repeat rewrite pm_correctness. reflexivity. 75 | Defined. 76 | Next Obligation. 77 | wf_auto2. 78 | Qed. 79 | Next Obligation. 80 | wf_auto2. 81 | Qed. 82 | Next Obligation. 83 | wf_auto2. 84 | Qed. 85 | 86 | #[global] 87 | Program Instance Binary_sorted_neg : Binary mlBAnd := {}. 88 | Next Obligation. 89 | intros. repeat rewrite pm_correctness. reflexivity. 90 | Defined. 91 | Next Obligation. 92 | intros. wf_auto2. 93 | Qed. 94 | Next Obligation. 95 | intros. wf_auto2. 96 | Qed. 97 | Next Obligation. 98 | intros. wf_auto2. 99 | Qed. 100 | 101 | #[global] 102 | Program Instance Binary_sorted_neg_1 : Binary mlBAndThen := {}. 103 | Next Obligation. 104 | intros. repeat rewrite pm_correctness. reflexivity. 105 | Defined. 106 | Next Obligation. 107 | intros. wf_auto2. 108 | Qed. 109 | Next Obligation. 110 | intros. wf_auto2. 111 | Qed. 112 | Next Obligation. 113 | intros. wf_auto2. 114 | Qed. 115 | 116 | End bools. 117 | 118 | Module Notations. 119 | Notation "phi '&&ml' psi" := (mlBAnd phi psi) (at level 40, left associativity) : ml_scope. 120 | Notation "'!b' phi" := (mlBNeg phi) (at level 60) : ml_scope. 121 | Notation "phi 'andThen' psi" := (mlBAndThen phi psi) (at level 40, left associativity) : ml_scope. 122 | End Notations. 123 | 124 | Section axioms. 125 | Import Notations. 126 | Open Scope ml_scope. 127 | Context 128 | {Σ : Signature} 129 | {syntax : Syntax}. 130 | 131 | Inductive AxiomName := 132 | | AxBoolSort 133 | | AxFunTrue 134 | | AxFunFalse 135 | | AxFunAnd 136 | | AxFunNeg 137 | | AxNoConfusion 138 | | AxInductiveDomain 139 | (* TODO: extend this with the DEFINITION axioms from "ML explained" *) 140 | | AxDefNegTrue 141 | | AxDefNegFalse 142 | | AxDefAndRightTrue 143 | | AxDefAndRightFalse 144 | | AxDefAndLeftTrue 145 | | AxDefAndLeftFalse 146 | (* extend to support andThen operator *) 147 | | AxDefAndThenRightTrue 148 | | AxDefAndThenRightFalse 149 | | AxDefAndThenLeftTrue 150 | | AxDefAndThenLeftFalse 151 | . 152 | 153 | Definition axiom (name : AxiomName) : Pattern := 154 | match name with 155 | | AxBoolSort => mlBool ∈ml ⟦Sorts⟧ 156 | | AxFunTrue => ex mlBool , mlTrue =ml b0 157 | | AxFunFalse => ex mlBool , mlFalse =ml b0 158 | | AxFunAnd => 159 | all mlBool , all mlBool , ex mlBool , b1 &&ml b2 =ml b0 160 | | AxFunNeg => all mlBool , ex mlBool , !b b1 =ml b0 161 | | AxNoConfusion => !(mlTrue =ml mlFalse) 162 | | AxInductiveDomain => ⟦ mlBool ⟧ =ml (mlTrue or mlFalse) 163 | 164 | | AxDefNegTrue => !b mlTrue =ml mlFalse 165 | | AxDefNegFalse => !b mlFalse =ml mlTrue 166 | | AxDefAndRightTrue => 167 | all mlBool, b0 &&ml mlTrue =ml b0 168 | | AxDefAndRightFalse => 169 | all mlBool, b0 &&ml mlFalse =ml mlFalse 170 | | AxDefAndLeftTrue => 171 | all mlBool, mlTrue &&ml b0 =ml b0 172 | | AxDefAndLeftFalse => 173 | all mlBool, mlFalse &&ml b0 =ml mlFalse 174 | 175 | | AxDefAndThenRightTrue => 176 | all mlBool, b0 andThen mlTrue =ml b0 177 | | AxDefAndThenRightFalse => 178 | all, b0 andThen mlFalse =ml mlFalse 179 | | AxDefAndThenLeftTrue => 180 | all mlBool, mlTrue andThen b0 =ml b0 181 | | AxDefAndThenLeftFalse => 182 | all, mlFalse andThen b0 =ml mlFalse 183 | 184 | end. 185 | 186 | Program Definition named_axioms : NamedAxioms := 187 | {| 188 | NAName := AxiomName; 189 | NAAxiom := axiom; 190 | |}. 191 | Next Obligation. 192 | destruct name; simpl; wf_auto2. 193 | Qed. 194 | 195 | Definition theory := Definedness_Syntax.theory ∪ 196 | theory_of_NamedAxioms named_axioms. 197 | 198 | 199 | End axioms. -------------------------------------------------------------------------------- /matching-logic/src/Theories/Nat_Syntax.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_Syntax. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Section nat_syntax. 9 | 10 | Context {Σ : Signature}. 11 | 12 | Inductive Symbols := sNat | sZero | sSucc | sAddNat. 13 | 14 | Global Instance Symbols_eqdec : EqDecision Symbols. 15 | Proof. unfold EqDecision. intros x y. unfold Decision. destruct x; decide equality. (*solve_decision.*) 16 | Defined. 17 | 18 | Class Syntax := 19 | { sym_inj : Symbols -> symbols; 20 | imported_sorts : Sorts_Syntax.Syntax; 21 | }. 22 | 23 | #[global] Existing Instance imported_sorts. 24 | 25 | Context {self : Syntax}. 26 | 27 | Definition Nat := patt_sym (sym_inj sNat). 28 | Definition Zero := patt_sym (sym_inj sZero). 29 | Definition Succ := patt_sym (sym_inj sSucc). 30 | Definition AddNat := patt_sym (sym_inj sAddNat). 31 | 32 | Definition mlAddNat (φ1 φ2 : Pattern) : Pattern := 33 | AddNat ⋅ φ1 ⋅ φ2 . 34 | 35 | End nat_syntax. 36 | 37 | Section nat. 38 | Context {Σ : Signature}. 39 | Context {self : Syntax}. 40 | Open Scope ml_scope. 41 | 42 | Obligation Tactic := idtac. 43 | 44 | #[global] 45 | Program Instance Binary_sorted_add : Binary mlAddNat := {}. 46 | Next Obligation. 47 | intros. repeat rewrite pm_correctness. reflexivity. 48 | Defined. 49 | Next Obligation. 50 | intros. wf_auto2. 51 | Qed. 52 | Next Obligation. 53 | intros. wf_auto2. 54 | Qed. 55 | Next Obligation. 56 | intros. wf_auto2. 57 | Qed. 58 | 59 | End nat. 60 | 61 | Module Notations. 62 | Notation "phi '+ml' psi" := (mlAddNat phi psi) (at level 40, left associativity) : ml_scope. 63 | End Notations. 64 | 65 | Section axioms. 66 | Import Notations. 67 | Context 68 | {Σ : Signature} 69 | {syntax : Syntax} 70 | . 71 | 72 | Inductive AxiomName := 73 | | AxNatSort 74 | | AxFun1 75 | | AxFun2 76 | | AxNoConfusion1 77 | | AxNoConfusion2 78 | | AxInductiveDomain 79 | (* extend the axioms in spec for addition operator *) 80 | | AxFunAdd 81 | | AxDefAddId 82 | | AxDefAdd. 83 | 84 | Definition axiom (name : AxiomName) : Pattern := 85 | match name with 86 | | AxNatSort => Nat ∈ml ⟦Sorts⟧ 87 | | AxFun1 => ex Nat , Zero =ml b0 88 | | AxFun2 => all Nat, ex Nat, Succ ⋅ b1 =ml b0 89 | | AxNoConfusion1 => all Nat, !(Zero =ml Succ ⋅ b0) 90 | | AxNoConfusion2 => all Nat, all Nat, (Succ ⋅ b1 =ml Succ ⋅ b0 ---> b1 =ml b0) 91 | | AxInductiveDomain => ⟦ Nat ⟧ =ml mu , Zero or Succ ⋅ B0 92 | (* extend to support addition operator*) 93 | | AxFunAdd => 94 | all Nat, all Nat, ex Nat, b1 +ml b2 =ml b0 95 | 96 | | AxDefAddId => 97 | all Nat, b0 +ml Zero =ml b0 98 | 99 | | AxDefAdd => 100 | all Nat, all Nat, b0 +ml (Succ ⋅ b1) =ml Succ ⋅ (b0 +ml b1) 101 | end. 102 | 103 | Program Definition named_axioms : NamedAxioms := 104 | {| 105 | NAName := AxiomName; 106 | NAAxiom := axiom; 107 | |}. 108 | Next Obligation. 109 | destruct name; simpl; wf_auto2. 110 | Qed. 111 | 112 | Definition theory := Definedness_Syntax.theory ∪ theory_of_NamedAxioms named_axioms. 113 | 114 | End axioms. 115 | -------------------------------------------------------------------------------- /matching-logic/src/Theories/ProductSort.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_Syntax. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Inductive Symbols {Σ : Signature} (s1 s2 : Pattern) := 9 | | ml_prod 10 | | ml_pair 11 | | ml_projL 12 | | ml_projR 13 | . 14 | 15 | #[global] 16 | Instance Symbols_eqdec {Σ : Signature} s1 s2 : EqDecision (Symbols s1 s2). 17 | Proof. solve_decision. Defined. 18 | 19 | Class Syntax {Σ : Signature} (s1 s2 : Pattern) := 20 | { 21 | imported_sorts : Sorts_Syntax.Syntax; 22 | inj: Symbols s1 s2 -> symbols; 23 | inj_inj: Inj (=) (=) inj; 24 | }. 25 | 26 | #[global] Existing Instance imported_sorts. 27 | #[global] Existing Instance inj_inj. 28 | 29 | Module Notations. 30 | 31 | Notation "'mlProd' '(' s1 ',' s2 ')'" 32 | := (patt_sym (inj (ml_prod s1 s2))) 33 | : ml_scope 34 | . 35 | 36 | Notation "'mlPair' '{' s1 ',' s2 '}' '(' phi1 ',' phi2 ')'" := 37 | (patt_app (patt_app (patt_sym (inj (ml_pair s1 s2))) phi1) phi2) 38 | : ml_scope 39 | . 40 | 41 | Notation "'(' phi1 '∷' s1 ',' phi2 '∷' s2 ')'" := 42 | (patt_app (patt_app (patt_sym (inj (ml_pair s1 s2))) phi1) phi2) 43 | : ml_scope 44 | . 45 | 46 | Notation "'(' phi ').mlProjL(' s1 ',' s2 ')'" := 47 | (patt_app (patt_sym (inj (ml_projL s1 s2))) phi) 48 | : ml_scope 49 | . 50 | 51 | Notation "'(' phi ').mlProjR(' s1 ',' s2 ')'" := 52 | (patt_app (patt_sym (inj (ml_projR s1 s2))) phi) 53 | : ml_scope 54 | . 55 | 56 | End Notations. 57 | 58 | Section axioms. 59 | Context 60 | {Σ : Signature} 61 | (s1 s2 : Pattern) 62 | (wfs1 : well_formed s1 = true) 63 | (wfs2 : well_formed s2 = true) 64 | {syntax : Syntax s1 s2} 65 | . 66 | Import Notations. 67 | Open Scope ml_scope. 68 | Delimit Scope ml_scope with ml. (* TODO move this somewhere else *) 69 | 70 | 71 | 72 | Inductive AxiomName := 73 | | AxProdSort 74 | | AxPair 75 | | AxProjLeft 76 | | AxProjRight 77 | | AxInj 78 | | InversePairProja1 79 | | InversePairProja2 80 | | InversePairProjb 81 | . 82 | 83 | Definition axiom (name : AxiomName) : Pattern := 84 | match name with 85 | | AxProdSort => 86 | s1 ∈ml Sorts and s2 ∈ml Sorts ---> mlProd(s1, s2) ∈ml Sorts 87 | | AxPair => 88 | patt_total_binary_function 89 | (patt_sym (inj (ml_pair s1 s2))) 90 | s1 91 | s2 92 | (patt_sym (inj (ml_prod s1 s2))) 93 | 94 | | AxProjLeft => 95 | all mlProd(s1,s2), ex s1, (b1).mlProjL( s1 , s2 ) =ml b0 96 | 97 | | AxProjRight => 98 | all mlProd(s1,s2), ex s2, (b1).mlProjR( s1 , s2 ) =ml b0 99 | 100 | | AxInj => 101 | all s1, all s1, all s2, all s2, 102 | patt_imp ( 103 | ( b3 ∷ s1 , b1 ∷ s2 ) =ml ( b2 ∷ s1 , b0 ∷ s2 )%ml 104 | ) ( 105 | patt_and ( 106 | b3 =ml b2 107 | ) ( 108 | b1 =ml b0 109 | ) 110 | ) 111 | 112 | | InversePairProja1 => 113 | all s1, all s2, (( b1 ∷ s1 , b0 ∷ s2 )).mlProjL( s1 , s2 ) =ml b1 114 | 115 | | InversePairProja2 => 116 | all s1, all s2, (( b1 ∷ s1 , b0 ∷ s2 )).mlProjL( s1 , s2 ) =ml b0 117 | 118 | | InversePairProjb => 119 | all mlProd(s1,s2), ( (b0).mlProjL( s1 , s2 ) ∷ s1 , (b0).mlProjR( s1 , s2 ) ∷ s2 ) =ml b0 120 | end. 121 | 122 | Program Definition named_axioms : NamedAxioms := 123 | {| NAName := AxiomName; 124 | NAAxiom := axiom; 125 | |}. 126 | Next Obligation. 127 | destruct name; simpl; wf_auto2. 128 | Qed. 129 | 130 | Definition theory := Definedness_Syntax.theory ∪ 131 | theory_of_NamedAxioms named_axioms. 132 | 133 | End axioms. -------------------------------------------------------------------------------- /matching-logic/src/Theories/ProductSortWithLookup.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export ProductSort. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations 5 | MatchingLogic.Theories.ProductSort.Notations. 6 | 7 | Set Default Proof Mode "Classic". 8 | 9 | 10 | Inductive Symbols {Σ : Signature} (s1 s2 : Pattern) := 11 | | ml_sym_lookup 12 | | ml_sym_product_symbols (s : ProductSort.Symbols s1 s2) 13 | . 14 | 15 | 16 | #[global] 17 | Instance Symbols_eqdec {Σ : Signature} s1 s2 : EqDecision (Symbols s1 s2). 18 | Proof. solve_decision. Defined. 19 | 20 | Class Syntax {Σ : Signature} (s1 s2 : Pattern) := 21 | { 22 | (* imported_product :: ProductSort.Syntax s1 s2; *) 23 | imported_sorts : Sorts_Syntax.Syntax ; 24 | sym_inj: Symbols s1 s2 -> symbols; 25 | sym_inj_inj: Inj (=) (=) sym_inj; 26 | }. 27 | 28 | (*#[global] Existing Instance imported_product.*) 29 | #[global] Existing Instance imported_sorts. 30 | #[global] Existing Instance sym_inj_inj. 31 | 32 | Section pswl. 33 | Context 34 | {Σ : Signature} 35 | (s1 s2 : Pattern) 36 | (wfs1 : well_formed s1 = true) 37 | (wfs2 : well_formed s2 = true) 38 | {syntax : Syntax s1 s2} 39 | . 40 | Import Notations. 41 | Open Scope ml_scope. 42 | Delimit Scope ml_scope with ml. (* TODO move this somewhere else *) 43 | 44 | (* Typelass resolution does not terminate on this input. 45 | TODO: figure out why. 46 | So I will just define the instance via ltac. 47 | *) 48 | (* 49 | #[global] 50 | Instance imported_product 51 | : (ProductSort.Syntax s1 s2) 52 | := {| 53 | ProductSort.imported_sorts := @imported_sorts Σ s1 s2 syntax; 54 | |}. 55 | *) 56 | #[global] 57 | Instance product_syntax 58 | : (ProductSort.Syntax s1 s2) 59 | . 60 | Proof. 61 | unshelve(econstructor). 62 | { 63 | intros s. 64 | exact (sym_inj (ml_sym_product_symbols s1 s2 s)). 65 | } 66 | { 67 | exact imported_sorts. 68 | } 69 | { 70 | abstract( 71 | intros x y Hxy; 72 | apply sym_inj_inj in Hxy; 73 | inversion Hxy; 74 | subst; reflexivity 75 | ). 76 | } 77 | Defined. 78 | 79 | Definition ml_lookup (ϕ k : Pattern) 80 | := patt_app (patt_app (patt_sym (sym_inj (ml_sym_lookup s1 s2))) ϕ) k 81 | . 82 | 83 | Inductive AxiomName := 84 | | AxKeyValue 85 | . 86 | 87 | Definition axiom (name : AxiomName) : Pattern := 88 | match name with 89 | | AxKeyValue => 90 | all s1, ( 91 | all s2, ( 92 | all s1, ( 93 | ml_lookup (mlPair { s1 , s2 } (b2 , b1)) b0 =ml (patt_and (b2 =ml b0) b1) 94 | ) 95 | ) 96 | ) 97 | end. 98 | 99 | Program Definition named_axioms : NamedAxioms := 100 | {| NAName := AxiomName; 101 | NAAxiom := axiom; 102 | |}. 103 | Next Obligation. 104 | destruct name; simpl; wf_auto2. 105 | Qed. 106 | 107 | Definition Γprodl := theory_of_NamedAxioms named_axioms. 108 | 109 | End pswl. -------------------------------------------------------------------------------- /matching-logic/src/Theories/ProductSort_ProofSystem.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_ProofSystem 2 | ProductSort. 3 | Import MatchingLogic.Logic.Notations 4 | MatchingLogic.Theories.Definedness_Syntax.Notations 5 | MatchingLogic.Theories.Sorts_Syntax.Notations 6 | MatchingLogic.Theories.ProductSort.Notations. 7 | 8 | Set Default Proof Mode "Classic". 9 | 10 | Open Scope list_scope. 11 | 12 | Section productsort. 13 | Context 14 | {Σ : Signature} 15 | (s1 s2 : Pattern) 16 | (wfs1 : well_formed s1 = true) 17 | (wfs2 : well_formed s2 = true) 18 | {syntax : ProductSort.Syntax s1 s2} 19 | . 20 | 21 | Lemma use_productsort_axiom ax Γ : 22 | ProductSort.theory s1 s2 wfs1 wfs2 ⊆ Γ -> 23 | Γ ⊢ axiom _ _ ax. 24 | Proof. 25 | intro HΓ. 26 | apply useBasicReasoning. 27 | apply hypothesis. 28 | { clear HΓ. destruct ax; wf_auto2. } 29 | { 30 | apply elem_of_weaken with (X := theory_of_NamedAxioms (named_axioms _ _ wfs1 wfs2 ) ). 31 | { 32 | unfold theory_of_NamedAxioms, named_axioms, axiom; simpl. 33 | apply elem_of_PropSet. 34 | exists ax. 35 | reflexivity. 36 | } 37 | { 38 | unfold theory in HΓ. 39 | set_solver. 40 | } 41 | } 42 | Defined. 43 | 44 | Theorem prod_sort : forall Γ , theory s1 s2 wfs1 wfs2 ⊆ Γ -> 45 | Γ ⊢ all mlProd(s1,s2), ex s1, ex s2, ( b1 ∷ s1 , b0 ∷ s2 ) =ml b2 . 46 | Proof. 47 | intros. 48 | toMLGoal. 49 | 1: clear H;wf_auto2. 50 | mlIntroAll x. 51 | mlSimpl. 52 | mlIntro. 53 | repeat rewrite bevar_subst_not_occur. 54 | 1-2: clear H;wf_auto2. 55 | 56 | pose proof use_productsort_axiom AxProjLeft Γ H. 57 | pose proof use_productsort_axiom AxProjRight Γ H. 58 | pose proof use_productsort_axiom InversePairProjb Γ H. 59 | 60 | simpl in *. 61 | mlAdd H0 as "f". 62 | mlAdd H1 as "g". 63 | mlAdd H2 as "z". 64 | 65 | mlSpecialize "f" with x. 66 | mlSimpl. 67 | unfold evar_open. 68 | rewrite bevar_subst_not_occur. 69 | 1:{ clear H. wf_auto2. } 70 | 71 | mlAssert ("C" : ( patt_free_evar x ∈ml ⟦ mlProd (s1, s2) ⟧) ). 72 | 1:wf_auto2. 73 | 1:mlAssumption. 74 | mlApply "C" in "f". 75 | 76 | mlDestructEx "C" as y. 77 | 78 | mlSimpl. unfold nest_ex. rewrite nest_ex_aux_wfcex. 79 | 1:{ clear H. wf_auto2. } 80 | 81 | rewrite evar_open_not_occur. 82 | 1:{ clear H. wf_auto2. } 83 | mlDestructAnd "C". 84 | mlClear "f". 85 | 86 | mlSpecialize "g" with x. 87 | mlSimpl. 88 | rewrite evar_open_not_occur. 89 | 1:{ clear H. wf_auto2. } 90 | 91 | mlAssert ("C" : ( patt_free_evar x ∈ml ⟦ mlProd (s1, s2) ⟧) ). 92 | 1:wf_auto2. 93 | 1:mlAssumption. 94 | mlApply "C" in "g". 95 | 96 | mlDestructEx "C" as z. 97 | 98 | mlSimpl. unfold nest_ex. rewrite nest_ex_aux_wfcex. 99 | 1:clear H;wf_auto2. 100 | rewrite evar_open_not_occur. 101 | 1:clear H;wf_auto2. 102 | mlDestructAnd "C". 103 | mlClear "g". 104 | 105 | mlExists y. mlSimpl. 106 | mlSplitAnd. 107 | * mlSimpl. unfold nest_ex. rewrite nest_ex_aux_wfcex. 108 | 1:clear H;wf_auto2. 109 | rewrite evar_open_not_occur. 110 | 1:clear H;wf_auto2. 111 | mlAssumption. 112 | * mlSimpl. 113 | rewrite evar_open_not_occur. 114 | 1:{ clear H. wf_auto2. } 115 | mlExists z. mlSimpl. unfold nest_ex. rewrite nest_ex_aux_wfcex. 116 | 1:clear H;wf_auto2. 117 | rewrite evar_open_not_occur. 118 | clear H;wf_auto2. 119 | mlSplitAnd. 120 | + mlAssumption. 121 | + mlSymmetry in "2". mlRewriteBy "2" at 1. 122 | mlSymmetry in "4". mlRewriteBy "4" at 1. 123 | mlSpecialize "z" with x. mlSimpl. 124 | mlApply "z". 125 | mlAssumption. 126 | Defined. 127 | 128 | End productsort. 129 | -------------------------------------------------------------------------------- /matching-logic/src/Theories/RecursiveSymbol.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export ProductSortWithLookup. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations 5 | MatchingLogic.Theories.ProductSort.Notations. 6 | 7 | Set Default Proof Mode "Classic". 8 | 9 | Delimit Scope ml_scope with ml. (* TODO move this somewhere else *) 10 | 11 | Section rs. 12 | Context 13 | {Σ : Signature} 14 | {sorts_syntax : Sorts_Syntax.Syntax} 15 | . 16 | 17 | Definition apply_connective (connective arg1 arg2 : Pattern) : Pattern 18 | := (connective ⋅ arg1 ⋅ arg2)%ml. 19 | 20 | Definition chain_patterns 21 | (connective : Pattern) 22 | (ps : list Pattern) 23 | (last : Pattern) 24 | : Pattern 25 | := 26 | fold_right 27 | (apply_connective connective) 28 | last 29 | ps 30 | . 31 | 32 | #[local] Example chain_1_patterns: 33 | chain_patterns 34 | (⊥%ml) 35 | [] 36 | (b0) 37 | = b0 38 | . 39 | Proof. reflexivity. Qed. 40 | 41 | #[local] Example chain_2_patterns: 42 | chain_patterns 43 | (⊥%ml) 44 | [b0] 45 | (b1) 46 | = (⊥ ⋅ b0 ⋅ b1)%ml 47 | . 48 | Proof. reflexivity. Qed. 49 | 50 | #[local] Example chain_3_patterns: 51 | chain_patterns 52 | (⊥%ml) 53 | [b0;b1] 54 | (b2) 55 | = (⊥ ⋅ b0 ⋅ (⊥ ⋅ b1 ⋅ b2))%ml 56 | . 57 | Proof. reflexivity. Qed. 58 | 59 | #[local] Example chain_4_patterns: 60 | chain_patterns 61 | (⊥%ml) 62 | [b0;b1;b2] 63 | (b3) 64 | = (⊥ ⋅ b0 ⋅ (⊥ ⋅ b1 ⋅ (⊥ ⋅ b2 ⋅ b3)))%ml 65 | . 66 | Proof. reflexivity. Qed. 67 | 68 | Context 69 | (param_sort : list Pattern) 70 | (ret_sort : Pattern) 71 | . 72 | 73 | (* 74 | This is going to be tricky. 75 | We need to define those three operations on lists of things: 76 | (1) s1 ⊗ · · · ⊗ sn ⊗ t ≡ s1 ⊗ (s2 ⊗ (· · · ⊗ (sn ⊗ t) . . . )) 77 | (2) ⟨ϕ1, . . . , ϕn, ϕ⟩ ≡ ⟨ϕ1, ⟨. . . , ⟨ϕn, ϕ⟩ . . .⟩⟩ 78 | (3) ψ(ϕ1, . . . , ϕn ) ≡ ψ(ϕ1 ) . . . (ϕn ). 79 | 80 | Therefore, we need to have syntax for 81 | sn ⊗ t, sn-1 ⊗ sn ⊗ t, etc. 82 | By "syntax", we mean 83 | `ProductSort.Syntax s1 s2`. 84 | 85 | What sorts do we need? 86 | 87 | Case length(param_sort)=0: 88 | `ret_sort` 89 | 90 | Case length(param_sort)=1: 91 | `ret_sort` 92 | `param_sort!!0 ⊗ ret_sort` 93 | 94 | Case length(param_sort)=2: 95 | `ret_sort` 96 | `param_sort!!1 ⊗ ret_sort` 97 | `param_sort!!0 ⊗ (param_sort!!1 ⊗ ret_sort)` 98 | 99 | Case length(param_sort)=3: 100 | `ret_sort` 101 | `param_sort!!2 ⊗ ret_sort` 102 | `param_sort!!1 ⊗ (param_sort!!2 ⊗ ret_sort)` 103 | `param_sort!!0 ⊗ (param_sort!!1 ⊗ (param_sort!!2 ⊗ ret_sort))` 104 | 105 | Let n=3. We need the user to provide us with something like 106 | *) 107 | 108 | 109 | (* 110 | Definition partial_sort_applications : list Pattern := 111 | fold_right (fun b a => a) ret_sort param_sort 112 | . 113 | Print fold_right. 114 | 115 | Inductive Syntaxes := 116 | | sxs_leaf 117 | (s_right : Pattern) 118 | | sxs_step 119 | (s_left : Pattern) 120 | (s_right : Pattern) 121 | (syntax: ProductSortWithLookup.Syntax s_left s_right) 122 | (next : Syntaxes) 123 | . 124 | 125 | Definition sxs_right (sxs : Syntaxes) : Pattern := 126 | match sxs with 127 | | sxs_leaf s_right => s_right 128 | | sxs_step s_left s_right syntax next => 129 | (mlProd(s_left, s_right))%ml 130 | end 131 | . 132 | 133 | Fixpoint sxs_valid (sxs : Syntaxes) : Prop := 134 | match sxs with 135 | | sxs_leaf _ => True 136 | | sxs_step s_left s_right syntax next => 137 | s_right = sxs_right next /\ sxs_valid next 138 | end 139 | . 140 | 141 | *) 142 | End rs. -------------------------------------------------------------------------------- /matching-logic/src/Theories/Sorts_ProofSystem.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_Syntax 2 | MLPM 3 | FOEquality_ProofSystem. 4 | Import MatchingLogic.Logic.Notations 5 | MatchingLogic.Theories.Definedness_Syntax.Notations 6 | MatchingLogic.Theories.Sorts_Syntax.Notations. 7 | 8 | Set Default Proof Mode "Classic". 9 | 10 | Open Scope list_scope. 11 | 12 | Local Lemma simplTest 13 | {Σ : Signature} 14 | {syntax : Sorts_Syntax.Syntax} 15 | (Γ : Theory) 16 | (φ ψ τ: Pattern) 17 | (s : symbols) x: 18 | well_formed (ex , φ) -> 19 | well_formed ψ -> 20 | well_formed τ -> 21 | Definedness_Syntax.theory ⊆ Γ -> 22 | Γ ⊢ ((all ψ , φ) ---> ex ψ , φ)^[[evar:x↦τ]]. 23 | Proof. 24 | intros. 25 | mlSimpl. 26 | remember (fresh_evar (ψ ⋅ φ ⋅ τ)) as y. 27 | mlIntro. 28 | mlSpecialize "0" with x. 29 | mlExists x. 30 | Abort. 31 | 32 | Lemma ex_sort_impl_ex 33 | {Σ : Signature} 34 | {syntax : Sorts_Syntax.Syntax} 35 | (Γ : Theory) 36 | (ϕ : Pattern) 37 | (s : symbols) 38 | : 39 | well_formed (ex , ϕ) -> 40 | Definedness_Syntax.theory ⊆ Γ -> 41 | Γ ⊢ (ex (patt_sym s) , ϕ) ---> (ex , ϕ). 42 | Proof. 43 | intros wfϕ HΓ. 44 | 45 | unfold "ex _ , _". 46 | 47 | unfold nest_ex; simpl. 48 | 49 | remember (fresh_evar (b0 ∈ml ⟦ patt_sym s ⟧ and ϕ)) as x. 50 | rewrite <- evar_quantify_evar_open with (n := 0) (x := x) (phi := b0 ∈ml ⟦ patt_sym s ⟧ and ϕ). 51 | 2: { 52 | subst x. eapply evar_is_fresh_in_richer'. 53 | 2: apply set_evar_fresh_is_fresh'. 54 | clear. set_solver. 55 | } 56 | 2: { 57 | wf_auto2. 58 | } 59 | 60 | gapply Ex_gen. 61 | { apply pile_any. } 62 | { apply pile_any. } 63 | { 64 | subst x. eapply evar_is_fresh_in_richer'. 65 | 2: { apply set_evar_fresh_is_fresh'. } 66 | clear. set_solver. 67 | } 68 | 69 | mlSimpl. unfold evar_open. simpl. 70 | 71 | toMLGoal. 72 | { wf_auto2. } 73 | mlIntro "H". 74 | mlDestructAnd "H" as "H0" "H1". 75 | mlClear "H0". 76 | 77 | mlApplyMeta Ex_quan. simpl. 78 | mlExact "H1". 79 | Defined. 80 | 81 | Theorem top_includes_everything {Σ : Signature} {syntax : Sorts_Syntax.Syntax}: 82 | ∀ (Γ : Theory) (x : evar), 83 | Definedness_Syntax.theory ⊆ Γ -> 84 | Γ ⊢i patt_free_evar x ∈ml patt_top using AnyReasoning. 85 | Proof. 86 | intros. 87 | pose proof proved_membership_functional Γ (patt_top) (patt_free_evar x) ltac:(set_solver) ltac:(wf_auto2) ltac:(wf_auto2). 88 | mlApplyMeta H0. 89 | * unfold is_functional. 90 | mlExists x. 91 | mlSimpl. cbn. 92 | mlReflexivity. 93 | * pose proof top_holds Γ. 94 | use AnyReasoning in H1. 95 | mlExactMeta H1. 96 | Defined. 97 | -------------------------------------------------------------------------------- /matching-logic/src/Theories/Subseteq_ProofSystem.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export FOEquality_ProofSystem. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations. 4 | 5 | Set Default Proof Mode "Classic". 6 | 7 | Open Scope list_scope. 8 | 9 | Lemma patt_subseteq_trans 10 | {Σ : Signature} 11 | {syntax : Definedness_Syntax.Syntax} 12 | (Γ : Theory) 13 | (ϕ₁ ϕ₂ ϕ₃ : Pattern) 14 | : 15 | well_formed ϕ₁ -> 16 | well_formed ϕ₂ -> 17 | well_formed ϕ₃ -> 18 | Definedness_Syntax.theory ⊆ Γ -> 19 | Γ ⊢ patt_subseteq ϕ₁ ϕ₂ ---> 20 | patt_subseteq ϕ₂ ϕ₃ ---> 21 | patt_subseteq ϕ₁ ϕ₃ 22 | . 23 | Proof. 24 | intros wfϕ1 wfϕ2 wfϕ3 HΓ. 25 | toMLGoal. 26 | { wf_auto2. } 27 | mlIntro "H1". 28 | mlIntro "H2". 29 | mlAssert ("H3":((patt_subseteq ϕ₁ ϕ₂) and (patt_subseteq ϕ₂ ϕ₃))). 30 | { wf_auto2. } 31 | { 32 | mlSplitAnd; mlAssumption. 33 | } 34 | mlClear "H1". 35 | mlClear "H2". 36 | mlRevert "H3". 37 | pose proof (Htmp := patt_total_and Γ (ϕ₁ ---> ϕ₂) (ϕ₂ ---> ϕ₃) HΓ ltac:(wf_auto2) ltac:(wf_auto2)). 38 | apply useGenericReasoning with (i := AnyReasoning) in Htmp . 39 | 2: { apply pile_any. } 40 | unfold patt_subseteq. 41 | mlRewrite <- Htmp at 1. 42 | clear Htmp. 43 | mlIntro "H3". 44 | mlDeduct "H3". 45 | fromMLGoal. 46 | apply phi_impl_total_phi_meta. 47 | { wf_auto2. } 48 | { try_solve_pile. } 49 | 50 | lazymatch goal with 51 | | [|- ?th ⊢i _ using ?i] => remember th as Γ'; remember i as pi 52 | end. 53 | assert (Hand: Γ' ⊢i ((ϕ₁ ---> ϕ₂) and (ϕ₂ ---> ϕ₃)) using pi). 54 | { 55 | gapply hypothesis. 56 | { subst. try_solve_pile. } 57 | { wf_auto2. } 58 | { 59 | subst. clear. set_solver. 60 | } 61 | } 62 | pose proof (H1 := Hand). 63 | apply pf_conj_elim_l_meta in H1. 64 | 2,3: wf_auto2. 65 | pose proof (H2 := Hand). 66 | apply pf_conj_elim_r_meta in H2. 67 | 2,3: wf_auto2. 68 | (* TODO rename to patt_imp_trans or similar *) 69 | eapply syllogism_meta. 70 | 1,3: wf_auto2. 71 | 2: apply H1. 72 | 1: wf_auto2. 73 | apply H2. 74 | Defined. -------------------------------------------------------------------------------- /matching-logic/src/Theories/SumSort_Syntax.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export Sorts_Syntax. 2 | Import MatchingLogic.Logic.Notations 3 | MatchingLogic.Theories.Definedness_Syntax.Notations 4 | MatchingLogic.Theories.Sorts_Syntax.Notations. 5 | 6 | Set Default Proof Mode "Classic". 7 | 8 | Open Scope ml_scope. 9 | 10 | Inductive Symbols {Σ : Signature} (s1 s2 : Pattern) := 11 | | ml_sum 12 | | ml_injectL 13 | | ml_injectR 14 | | ml_ejectL 15 | | ml_ejectR 16 | . 17 | 18 | #[global] 19 | Instance Symbols_eqdec {Σ : Signature} s1 s2 : EqDecision (Symbols s1 s2). 20 | Proof. solve_decision. Defined. 21 | 22 | Class Syntax {Σ : Signature} (s1 s2 : Pattern) := 23 | { 24 | imported_sorts : Sorts_Syntax.Syntax; 25 | sym_inj: Symbols s1 s2 -> symbols; 26 | inj_inj: Inj (=) (=) sym_inj; 27 | }. 28 | 29 | #[global] Existing Instance imported_sorts. 30 | #[global] Existing Instance inj_inj. 31 | 32 | Module Notations. 33 | 34 | 35 | Notation "'mlSum' '(' s1 ',' s2 ')'" := 36 | (patt_sym (sym_inj (ml_sum s1 s2))) 37 | : ml_scope 38 | . 39 | 40 | Notation "'(' phi ').mlInjectL(' s1 ',' s2 ')'" := 41 | (patt_app (patt_sym (sym_inj (ml_injectL s1 s2))) phi) 42 | : ml_scope 43 | . 44 | 45 | Notation "'(' phi ').mlInjectR(' s1 ',' s2 ')'" := 46 | (patt_app (patt_sym (sym_inj (ml_injectR s1 s2))) phi) 47 | : ml_scope 48 | . 49 | 50 | Notation "'(' phi ').mlEjectL(' s1 ',' s2 ')'" := 51 | (patt_app (patt_sym (sym_inj (ml_ejectL s1 s2))) phi) 52 | : ml_scope 53 | . 54 | 55 | Notation "'(' phi ').mlEjectR(' s1 ',' s2 ')'" := 56 | (patt_app (patt_sym (sym_inj (ml_ejectR s1 s2))) phi) 57 | : ml_scope 58 | . 59 | 60 | End Notations. 61 | 62 | 63 | Section axioms. 64 | Context 65 | {Σ : Signature} 66 | (s1 s2 : Pattern) 67 | (wfs1 : well_formed s1 = true) 68 | (wfs2 : well_formed s2 = true) 69 | {syntax : Syntax s1 s2} 70 | . 71 | Import Notations. 72 | Open Scope ml_scope. 73 | 74 | 75 | Inductive AxiomName := 76 | | AxSumSort 77 | | AxInjectLeft 78 | | AxInjectRight 79 | 80 | | AxEjectLeft 81 | | AxEjectRight 82 | 83 | | AxInverseInja1 84 | | AxInverseInja2 85 | 86 | | AxInverseInjb1 87 | | AxInverseInjb2 88 | 89 | | AxCoProduct 90 | . 91 | 92 | Definition axiom (name : AxiomName) : Pattern := 93 | match name with 94 | | AxSumSort => 95 | s1 ∈ml ⟦Sorts⟧ and s2 ∈ml ⟦Sorts⟧ ---> mlSum (s1, s2) ∈ml ⟦Sorts⟧ 96 | | AxInjectLeft => 97 | all s1, ex mlSum (s1,s2) , (b1).mlInjectL( s1 , s2 ) =ml b0 98 | 99 | | AxInjectRight => 100 | all s2, ex mlSum (s1,s2) , (b1).mlInjectR( s1 , s2 ) =ml b0 101 | 102 | | AxEjectLeft => 103 | all mlSum (s1,s2), ex s1 , (b1).mlEjectL( s1 , s2 ) ⊆ml b0 104 | 105 | | AxEjectRight => 106 | all mlSum (s1,s2), ex s2, (b1).mlEjectL( s1 , s2 ) ⊆ml b0 107 | 108 | | AxInverseInja1 => 109 | all s1, ( (b0).mlInjectL( s1 , s2 ) ).mlEjectL( s1 , s2 ) =ml b0 110 | 111 | | AxInverseInja2 => 112 | all s2, ( (b0).mlInjectR( s1 , s2 ) ).mlEjectR( s1 , s2 ) =ml b0 113 | 114 | | AxInverseInjb1 => 115 | all s2, ( (b0).mlInjectR( s1 , s2 ) ).mlEjectL( s1 , s2 ) =ml patt_bott 116 | 117 | | AxInverseInjb2 => 118 | all s1, ( (b0).mlInjectL( s1 , s2 ) ).mlEjectR( s1 , s2 ) =ml patt_bott 119 | 120 | | AxCoProduct => 121 | ⟦ mlSum (s1, s2) ⟧ ⊆ml patt_or ( (⟦s1⟧).mlInjectL( s1 , s2 ) ) ( (⟦s2⟧).mlInjectR( s1 , s2 ) ) 122 | end. 123 | 124 | Program Definition named_axioms : NamedAxioms := 125 | {| 126 | NAName := AxiomName; 127 | NAAxiom := axiom; 128 | |}. 129 | Next Obligation. 130 | destruct name; simpl; wf_auto2. 131 | Qed. 132 | 133 | Definition theory := Definedness_Syntax.theory ∪ 134 | theory_of_NamedAxioms named_axioms. 135 | 136 | End axioms. -------------------------------------------------------------------------------- /matching-logic/src/Theories/Test.v: -------------------------------------------------------------------------------- 1 | (* TODO I probably don't need half of these *) 2 | 3 | From Equations Require Import Equations. 4 | From Coq Require Import ssreflect ssrfun ssrbool. 5 | 6 | Require Import Logic.Classical_Prop Coq.Logic.FunctionalExtensionality. 7 | 8 | From stdpp 9 | Require Import 10 | base 11 | decidable 12 | propset 13 | fin_maps 14 | fin_sets 15 | . 16 | 17 | From MatchingLogic 18 | Require Import 19 | Utils.extralibrary 20 | Utils.stdpp_ext 21 | Pattern 22 | Syntax 23 | Semantics 24 | DerivedOperators_Syntax 25 | DerivedOperators_Semantics 26 | PrePredicate 27 | monotonic 28 | Theories.Definedness_Syntax 29 | Theories.Definedness_Semantics 30 | Theories.Sorts_Syntax 31 | Theories.Sorts_Semantics 32 | Theories.DefaultModels 33 | . 34 | 35 | 36 | Import MatchingLogic.Logic.Notations. 37 | Import MatchingLogic.Semantics.Notations. 38 | 39 | Open Scope ml_scope. 40 | 41 | Section helpers. 42 | Context 43 | {Σ₁ Σ₂ : Signature} 44 | (M₁ : @Model Σ₁) 45 | (M₂ : @Model Σ₂) 46 | . 47 | 48 | (* Add extra context arguments here *) 49 | Record ModelCombiners := { 50 | oneToTwo : Domain M₁ -> Domain M₂ -> propset (Domain M₁ + Domain M₂)%type; 51 | twoToOne : Domain M₂ -> Domain M₁ -> propset (Domain M₁ + Domain M₂)%type; 52 | (* Ignore these for now, come back when you reached 53 | * the long comment later *) 54 | (* oneToOneOverride : Domain M₁ -> Domain M₁ -> option (propset (Domain M₁ M₂)); *) 55 | (* twoToTwoOverride : Domain M₂ -> Domain M₂ -> option (propset (Domain M₁ M₂)); *) 56 | }. 57 | End helpers. 58 | 59 | Section test. 60 | Context 61 | {Σ₁ Σ₂ : Signature} 62 | (M₁ : @Model Σ₁) 63 | (M₂ : @Model Σ₂) 64 | (mc : ModelCombiners M₁ M₂) 65 | . 66 | 67 | Instance Σext : Signature := { 68 | (* TODO this definitely needs to change *) 69 | variables := StringMLVariables; 70 | ml_symbols := {| 71 | symbols := @symbols (@ml_symbols Σ₁) + @symbols (@ml_symbols Σ₂) 72 | |} 73 | }. 74 | 75 | Program Definition Mext : @Model Σext := {| 76 | Domain := (Domain M₁ + Domain M₂)%type; 77 | Domain_inhabited := sum_inhabited_l (Domain_inhabited M₁); 78 | |}. 79 | Next Obligation. 80 | destruct mc. 81 | intros [] []. 82 | exact (inl <$> app_interp M₁ d d0). 83 | exact (oneToTwo0 d d0). 84 | exact (twoToOne0 d d0). 85 | exact (inr <$> app_interp M₂ d d0). 86 | Defined. 87 | Next Obligation. 88 | intros []. 89 | exact (inl <$> sym_interp M₁ s). 90 | exact (inr <$> sym_interp M₂ s). 91 | Defined. 92 | End test. 93 | 94 | Section natbool. 95 | Definition NatBoolModel := Mext BoolModel NatModel {| 96 | (* Not sure if this is necessarily correct. 97 | * 0 andThen True might arise and should not be empty set. 98 | * Then again, our andThen is not standard, this is probably 99 | * the same issue we have with definedness later. *) 100 | oneToTwo _ _ := ∅; (* $ *) 101 | twoToOne _ _ := ∅; (* $ *) 102 | |}. 103 | 104 | Instance PlainDefinedness_Σ : Signature := { 105 | variables := StringMLVariables; 106 | ml_symbols := {| symbols := unit |}; 107 | }. 108 | 109 | Definition PlainDefinedness : @Model PlainDefinedness_Σ := {| 110 | Domain := unit; 111 | app_interp _ _ := ⊤; 112 | sym_interp _ := singleton (); 113 | |}. 114 | 115 | Definition DefinedNatBoolModel := Mext NatBoolModel PlainDefinedness {| 116 | oneToTwo _ _ := ∅; (* $ def *) 117 | twoToOne _ _ := ⊤; (* def $ *) 118 | |}. 119 | 120 | (* These get complicated, let Coq figure it out for us *) 121 | Definition get_signature {Σ : Signature} (m : @Model Σ) : Signature := Σ. 122 | 123 | Instance def_syntax : @Definedness_Syntax.Syntax (get_signature DefinedNatBoolModel) := { 124 | inj _ := inr (); 125 | }. 126 | 127 | Goal DefinedNatBoolModel ⊨ᵀ Definedness_Syntax.theory. 128 | Proof. 129 | unfold theory, named_axioms, theory_of_NamedAxioms. simpl. 130 | unfold satisfies_theory. intros. apply elem_of_PropSet in H. 131 | destruct H, x. subst. cbn. unfold satisfies_model. intros. 132 | unfold patt_defined, p_x, ev_x. simp eval. 133 | unfold app_ext. simpl. unshelve eapply leibniz_equiv. 134 | exact (@propset_leibniz_equiv _ DefinedNatBoolModel). 135 | eapply set_equiv. intros. split; intros. set_solver. 136 | rewrite elem_of_PropSet. 137 | exists (inr ()), (evar_valuation ρ (evar_fresh [])). 138 | split. set_solver. split. set_solver. 139 | case_match. set_solver. 140 | (* This condition is unsolvable. It comes from 141 | * Mext def -> obligation 1 -> case 4 and 142 | * PlainDefinedness def -> app_interp. 143 | * These definitions both seen sensible on their own. 144 | * Use the second models app_interp if both elements are 145 | * from the second model, then wrap it in inr. Also 146 | * def $ def is full set (right?). However, when we combine 147 | * these, we get something wrong. I suspect this is because 148 | * def $ def needs to be full set even AFTER gluing the models, 149 | * and not inr <$> full set. We could take as extra params in 150 | * ModelCombiners two functions that specifiy these special 151 | * behaviours, maybe even functions returning options, 152 | * so we retain the default behaviour of delegating to 153 | * the sets underlying app_interp. This raises two questions: 154 | * - Are there any other cases where this is needed or is this 155 | * special to definedness? Should definedness be treated as 156 | * special and we don't need this change elsewhere? 157 | * ∙ PB: Yes, potentially generic datatypes would raise this issue too. 158 | For example, lists, maps, sets. Depending on the element's sort 159 | you might need to extend the behaviour of list/set/etc. symbols. 160 | * - If we override the models original app_interp, do we not 161 | * lose any reasoning we did about the original one? Is there 162 | * a way to retain the proofs and allow special behaviour? 163 | * ∙ PB: This is a main question. I think, you can only retain the original 164 | behaviour, if you override (or rather, extend) the behaviour in a 165 | correct way. For example, in case of definedness, you extend its 166 | interpretation in M₂ to full. 167 | *) 168 | Abort. 169 | End natbool. 170 | 171 | Section transformers. 172 | (* TODO *) 173 | End transformers. 174 | -------------------------------------------------------------------------------- /matching-logic/src/Utils/Surj.v: -------------------------------------------------------------------------------- 1 | From Coq Require Import ssreflect 2 | ssrfun 3 | ssrbool. 4 | 5 | Require Import Coq.Setoids.Setoid 6 | Coq.Classes.Morphisms 7 | Coq.Relations.Relations. 8 | Require Import Logic.IndefiniteDescription 9 | Coq.Logic.FunctionalExtensionality. 10 | 11 | From stdpp 12 | Require Import 13 | base 14 | decidable 15 | propset 16 | sets 17 | . 18 | 19 | 20 | Class Surj' {A B} (R : relation B) (f : A -> B) : Type := { 21 | surj'_inv : B -> A ; 22 | surj'_pf: ∀ (b : B), R (f (surj'_inv b)) b 23 | }. 24 | 25 | #[export] 26 | Instance surj_surj' {A B} (R : relation B) (f : A -> B) {_ : @Surj' A B R f} : Surj R f. 27 | Proof. 28 | unfold Surj. 29 | intros y. 30 | exists (surj'_inv y). 31 | apply surj'_pf. 32 | Defined. 33 | 34 | #[export] 35 | Instance surj'_id {A} : @Surj' A A (=) Datatypes.id. 36 | Proof. 37 | exists Datatypes.id. 38 | intros b. reflexivity. 39 | Defined. 40 | 41 | #[export] 42 | Instance compose_surj' {A B C} R (f : A → B) (g : B → C) : 43 | Surj' (=) f -> Surj' R g -> Surj' R (g ∘ f). 44 | Proof. 45 | intros [sf Hsf] [sg Hsg]. 46 | exists (sf ∘ sg). 47 | intros x. unfold compose. 48 | rewrite Hsf. 49 | apply Hsg. 50 | Qed. 51 | -------------------------------------------------------------------------------- /matching-logic/src/dune: -------------------------------------------------------------------------------- 1 | (coq.theory 2 | (name MatchingLogic) 3 | (package coq-matching-logic) 4 | (synopsis "Matching Logic in Coq") 5 | ) 6 | (include_subdirs qualified) 7 | -------------------------------------------------------------------------------- /prover/Makefile: -------------------------------------------------------------------------------- 1 | all: Makefile.coq 2 | @+$(MAKE) -f Makefile.coq all 3 | 4 | test: all 5 | ./check-generated-proof-objects.sh 6 | 7 | html: Makefile.coq 8 | @+$(MAKE) -f Makefile.coq html COQDOCEXTRAFLAGS="--gallina --external https://plv.mpi-sws.org/coqdoc/stdpp/ stdpp" 9 | 10 | clean: Makefile.coq 11 | @+$(MAKE) -f Makefile.coq cleanall 12 | @rm -f Makefile.coq Makefile.coq.conf 13 | 14 | Makefile.coq: _CoqProject 15 | $(COQBIN)coq_makefile -f _CoqProject -o Makefile.coq 16 | 17 | force _CoqProject Makefile: ; 18 | 19 | %: Makefile.coq force 20 | @+$(MAKE) -f Makefile.coq $@ 21 | 22 | .PHONY: all clean force 23 | -------------------------------------------------------------------------------- /prover/_CoqProject: -------------------------------------------------------------------------------- 1 | -R theories MatchingLogicProver 2 | 3 | theories/Matchers.v 4 | theories/Named.v 5 | theories/NMatchers.v 6 | theories/NamedProofSystem.v 7 | theories/PSTStateless.v 8 | theories/PSTReader.v 9 | theories/MMProofExtractor.v 10 | theories/TEST_MMProofExtractor.v 11 | theories/ProofSystemTranslation.v 12 | 13 | -------------------------------------------------------------------------------- /prover/check-generated-proof-objects.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | compare() { 4 | NAME="$1" 5 | GENERATED="$NAME" 6 | REFERENCE="ref/$NAME.ref" 7 | 8 | cat "$GENERATED" | grep the-proof | sed 's/the-proof $p |- \(.*\) $=.*/\1/' > $NAME.tmp 9 | diff -uZ "$NAME.tmp" "$REFERENCE" 10 | } 11 | 12 | RESULT="0" 13 | for hs_file in *_mm.hs 14 | do 15 | echo "Patching $hs_file" 16 | patched_hs_file="$(basename "$hs_file" ".hs").p.hs" 17 | ./patch-extracted-hs.sh "$hs_file" "$patched_hs_file" 18 | runner_hs="$(basename $hs_file ".hs")_main.hs" 19 | str_name="$(basename "$hs_file" "_mm.hs")" 20 | printf "module Main where\n import Proof\n main = Prelude.putStrLn Proof.$str_name" > "$runner_hs" 21 | # https://github.com/coq/coq/issues/15180 22 | ghc -XNoPolyKinds "$patched_hs_file" "$runner_hs" -o runner 23 | mm_file="$(basename "$hs_file" "_mm.hs").mm" 24 | ./runner > "$mm_file" 25 | #continue 26 | echo "Checking $mm_file" 27 | compare "$mm_file" 28 | if [[ "$?" -gt 0 ]] 29 | then 30 | echo "ERROR" 31 | RESULT="1" 32 | continue 33 | fi 34 | 35 | echo "verify proof *" | metamath "$mm_file" 36 | done 37 | 38 | exit "$RESULT" 39 | # compare proof_4.mm 40 | -------------------------------------------------------------------------------- /prover/patch-extracted-hs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cat "$1" | head -n 2 > "$2" 4 | printf "module Proof where\nimport qualified Data.Bits\nimport qualified Data.Char\n" >> "$2" 5 | cat "$1" | tail -n +5 >> "$2" 6 | -------------------------------------------------------------------------------- /prover/proof_ex.mm: -------------------------------------------------------------------------------- 1 | $[ mm/matching-logic.mm $] 2 | $v var_x var_y $. 3 | $d var_x var_y $. 4 | var-x-is-element-var $f #ElementVariable var_x $. 5 | var-y-is-element-var $f #ElementVariable var_y $. 6 | the-proof-1 $p |- ( \exists var_x var_x ) $= var-x-is-element-var proof-rule-existence $. 7 | the-proof-2 $p |- ( \imp ( \exists var_x var_x ) ( \imp ( \exists var_y var_y ) ( \exists var_x var_x ) ) ) $= 8 | var-x-is-element-var element-var-is-var var-is-pattern var-x-is-element-var exists-is-pattern 9 | var-y-is-element-var element-var-is-var var-is-pattern var-y-is-element-var exists-is-pattern 10 | proof-rule-prop-1 $. 11 | -------------------------------------------------------------------------------- /prover/ref/proof_1.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp sym-a ( \imp sym-b sym-a ) ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_2.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp sym-a ( \imp sym-b sym-c ) ) ( \imp ( \imp sym-a sym-b ) ( \imp sym-a sym-c ) ) ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_3.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp ( \imp sym-a \bot ) \bot ) sym-a ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_4.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp sym-a sym-a ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_5.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp ( \imp ( \imp ( \imp ( \imp sym-a sym-b ) ( \imp ( \imp ( \imp sym-a \bot ) \bot ) sym-b ) ) \bot ) \bot ) ( \imp ( \imp ( \imp ( \imp ( \imp sym-a \bot ) \bot ) sym-b ) ( \imp sym-a sym-b ) ) \bot ) ) \bot ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_6.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp sym-a ( \imp ( \imp sym-b \bot ) \bot ) ) ( \imp sym-a sym-b ) ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_7.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp sym-b sym-c ) ( \imp ( \imp sym-a sym-b ) ( \imp sym-a sym-c ) ) ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_8.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \imp ( \imp ( \imp ( \imp sym-a \bot ) \bot ) ( \imp sym-b \bot ) ) \bot ) sym-a ) 2 | -------------------------------------------------------------------------------- /prover/ref/proof_9.mm.ref: -------------------------------------------------------------------------------- 1 | ( \imp ( \exists evar-0 evar-0 ) ( \imp sym-b ( \exists evar-0 evar-0 ) ) ) 2 | -------------------------------------------------------------------------------- /prover/theories/MMProofExtractorLoader.v: -------------------------------------------------------------------------------- 1 | Declare ML Module "mmpf_plugin". 2 | -------------------------------------------------------------------------------- /prover/theories/Matchers.v: -------------------------------------------------------------------------------- 1 | From MatchingLogic Require Export 2 | Logic 3 | . 4 | 5 | 6 | Import MatchingLogic.Logic.Notations. 7 | 8 | 9 | Global Set Transparent Obligations. 10 | Derive NoConfusion for Pattern. 11 | Derive Subterm for Pattern. 12 | 13 | Set Default Proof Mode "Classic". 14 | 15 | 16 | Open Scope ml_scope. 17 | 18 | Equations match_not {Σ : Signature} (p : Pattern) 19 | : ({ p' : Pattern & p = patt_not p'}) + (forall p', p <> patt_not p') 20 | := 21 | match_not (p' ---> ⊥) := inl _ ; 22 | match_not _ := inr _ . 23 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 24 | Next Obligation. 25 | intros. eapply existT. reflexivity. 26 | Defined. 27 | 28 | Lemma match_not_patt_not {Σ : Signature} p: is_inl (match_not (patt_not p)). 29 | Proof. 30 | funelim (match_not _). simpl. reflexivity. 31 | Qed. 32 | 33 | Equations match_or {Σ : Signature} (p : Pattern) 34 | : ({ p1 : Pattern & {p2 : Pattern & p = patt_or p1 p2} } ) + (forall p1 p2, p <> patt_or p1 p2) 35 | := 36 | match_or (p1 ---> p2) with match_not p1 => { 37 | | inl (existT p1' e) => inl _ 38 | | inr _ => inr _ 39 | } ; 40 | match_or _ := inr _. 41 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 42 | Next Obligation. 43 | intros. inversion e. subst. eapply existT. eapply existT. reflexivity. 44 | Defined. 45 | Next Obligation. 46 | intros. 47 | unfold patt_or. 48 | assert (p1 <> patt_not p0). auto. 49 | congruence. 50 | Defined. 51 | 52 | Lemma match_or_patt_or {Σ : Signature} p1 p2: is_inl (match_or (patt_or p1 p2)). 53 | Proof. reflexivity. Qed. 54 | 55 | Equations? match_and {Σ : Signature} (p : Pattern) 56 | : ({ p1 : Pattern & {p2 : Pattern & p = patt_and p1 p2} } ) + (forall p1 p2, p <> patt_and p1 p2) 57 | := 58 | match_and p with match_not p => { 59 | | inr _ := inr _ ; 60 | | inl (existT p' e') with match_or p' => { 61 | | inr _ := inr _ ; 62 | | inl (existT p1 (existT p2 e12)) with match_not p1 => { 63 | | inr _ := inr _ ; 64 | | inl (existT np1 enp1) with match_not p2 => { 65 | | inr _ := inr _ ; 66 | | inl (existT np2 enp2) := inl _ 67 | } 68 | } 69 | } 70 | }. 71 | Proof. 72 | - subst. eapply existT. eapply existT. reflexivity. 73 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 74 | subst. specialize (n p0). contradiction. 75 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 76 | subst. specialize (n p0). contradiction. 77 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 78 | subst. specialize (n (patt_not p1) (patt_not p2)). contradiction. 79 | - intros. unfold not. intros Hcontra. subst. 80 | specialize (n ((patt_or (patt_not p1) (patt_not p2)))). contradiction. 81 | Defined. 82 | 83 | Lemma match_and_patt_and {Σ : Signature} p1 p2: is_inl (match_and (patt_and p1 p2)). 84 | Proof. reflexivity. Qed. 85 | 86 | Lemma match_and_patt_or {Σ : Signature} p1 p2: is_inl (match_and (patt_or p1 p2)) = false. 87 | Proof. 88 | funelim (match_and _); try rewrite -Heqcall; simpl; try reflexivity. 89 | subst. try inversion e'. 90 | Qed. 91 | 92 | Equations match_imp {Σ : Signature} (p : Pattern) 93 | : ({ p1 : Pattern & {p2 : Pattern & p = patt_imp p1 p2} } ) + (forall p1 p2, p <> patt_imp p1 p2) 94 | := 95 | match_imp (p1 ---> p2) := inl _ ; 96 | match_imp _ := inr _. 97 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 98 | Next Obligation. 99 | intros. eapply existT. eapply existT. reflexivity. 100 | Defined. 101 | 102 | Lemma match_imp_patt_imp {Σ : Signature} p1 p2: is_inl (match_imp (patt_imp p1 p2)). 103 | Proof. reflexivity. Qed. 104 | 105 | Equations match_bott {Σ : Signature} (p : Pattern) 106 | : (p = patt_bott) + (p <> patt_bott) 107 | := 108 | match_bott patt_bott := inl _ ; 109 | match_bott _ := inr _. 110 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 111 | Next Obligation. reflexivity. Defined. 112 | 113 | 114 | Equations match_a_impl_b_impl_c {Σ : Signature} (p : Pattern) : 115 | ({a : Pattern & {b : Pattern & {c : Pattern & p = patt_imp a (patt_imp b c)} } }) 116 | + (forall (a b c : Pattern), p <> patt_imp a (patt_imp b c)) := 117 | match_a_impl_b_impl_c (p1 ---> (p2 ---> p3)) := inl _ ; 118 | match_a_impl_b_impl_c _ := inr _ . 119 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 120 | Next Obligation. 121 | intros Σ p1 p2 p3. 122 | do 3 eapply existT. 123 | reflexivity. 124 | Defined. 125 | 126 | -------------------------------------------------------------------------------- /prover/theories/NMatchers.v: -------------------------------------------------------------------------------- 1 | From MatchingLogicProver Require Export Named. 2 | 3 | Import MatchingLogic.Logic.Notations. 4 | 5 | Set Default Proof Mode "Classic". 6 | 7 | Equations nmatch_not {Σ : Signature} (p : NamedPattern) 8 | : ({ p' : NamedPattern & p = npatt_not p'} ) + (forall p', p <> npatt_not p') 9 | := 10 | nmatch_not (npatt_imp p' npatt_bott) := inl _ ; 11 | nmatch_not _ := inr _ . 12 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 13 | Next Obligation. 14 | intros. eapply existT. reflexivity. 15 | Defined. 16 | 17 | (* 18 | Lemma match_not_patt_not {Σ : Signature} p: is_inl (match_not (patt_not p)). 19 | Proof. 20 | funelim (match_not _). simpl. reflexivity. 21 | Qed. 22 | 23 | Equations match_or {Σ : Signature} (p : Pattern) 24 | : ({ p1 : Pattern & {p2 : Pattern & p = patt_or p1 p2}}) + (forall p1 p2, p <> patt_or p1 p2) 25 | := 26 | match_or (p1 ---> p2) with match_not p1 => { 27 | | inl (existT p1' e) => inl _ 28 | | inr _ => inr _ 29 | } ; 30 | match_or _ := inr _. 31 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 32 | Next Obligation. 33 | intros. inversion e. subst. eapply existT. eapply existT. reflexivity. 34 | Defined. 35 | Next Obligation. 36 | intros. 37 | unfold patt_or. 38 | assert (p1 <> patt_not p0). auto. 39 | congruence. 40 | Defined. 41 | 42 | Lemma match_or_patt_or {Σ : Signature} p1 p2: is_inl (match_or (patt_or p1 p2)). 43 | Proof. reflexivity. Qed. 44 | 45 | Equations? match_and {Σ : Signature} (p : Pattern) 46 | : ({ p1 : Pattern & {p2 : Pattern & p = patt_and p1 p2}}) + (forall p1 p2, p <> patt_and p1 p2) 47 | := 48 | match_and p with match_not p => { 49 | | inr _ := inr _ ; 50 | | inl (existT p' e') with match_or p' => { 51 | | inr _ := inr _ ; 52 | | inl (existT p1 (existT p2 e12)) with match_not p1 => { 53 | | inr _ := inr _ ; 54 | | inl (existT np1 enp1) with match_not p2 => { 55 | | inr _ := inr _ ; 56 | | inl (existT np2 enp2) := inl _ 57 | } 58 | } 59 | } 60 | }. 61 | Proof. 62 | - subst. eapply existT. eapply existT. reflexivity. 63 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 64 | subst. specialize (n p0). contradiction. 65 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 66 | subst. specialize (n p0). contradiction. 67 | - subst. intros. unfold not. intros Hcontra. inversion Hcontra. 68 | subst. specialize (n (patt_not p1) (patt_not p2)). contradiction. 69 | - intros. unfold not. intros Hcontra. subst. 70 | specialize (n ((patt_or (patt_not p1) (patt_not p2)))). contradiction. 71 | Defined. 72 | 73 | Lemma match_and_patt_and {Σ : Signature} p1 p2: is_inl (match_and (patt_and p1 p2)). 74 | Proof. reflexivity. Qed. 75 | 76 | Lemma match_and_patt_or {Σ : Signature} p1 p2: is_inl (match_and (patt_or p1 p2)) = false. 77 | Proof. 78 | funelim (match_and _); rewrite -Heqcall; simpl; try reflexivity. 79 | subst. try inversion e'. 80 | Qed. 81 | *) 82 | 83 | Equations nmatch_imp {Σ : Signature} (p : NamedPattern) 84 | : ({ p1 : NamedPattern & {p2 : NamedPattern & p = npatt_imp p1 p2} }) 85 | + (forall p1 p2, p <> npatt_imp p1 p2) 86 | := 87 | nmatch_imp (npatt_imp p1 p2) := inl _ ; 88 | nmatch_imp _ := inr _. 89 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 90 | Next Obligation. 91 | intros. eapply existT. eapply existT. reflexivity. 92 | Defined. 93 | 94 | (* 95 | Lemma match_imp_patt_imp {Σ : Signature} p1 p2: is_inl (match_imp (patt_imp p1 p2)). 96 | Proof. reflexivity. Qed. 97 | 98 | Equations match_bott {Σ : Signature} (p : Pattern) 99 | : (p = patt_bott) + (p <> patt_bott) 100 | := 101 | match_bott patt_bott := inl _ ; 102 | match_bott _ := inr _. 103 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 104 | Next Obligation. reflexivity. Defined. 105 | *) 106 | 107 | Equations nmatch_a_impl_b_impl_c {Σ : Signature} (p : NamedPattern) : 108 | ({a : NamedPattern & {b : NamedPattern & {c : NamedPattern & p = npatt_imp a (npatt_imp b c)} } }) 109 | + (forall (a b c : NamedPattern), p <> npatt_imp a (npatt_imp b c)) := 110 | nmatch_a_impl_b_impl_c (npatt_imp p1 (npatt_imp p2 p3)) := inl _ ; 111 | nmatch_a_impl_b_impl_c _ := inr _ . 112 | Solve Obligations with Tactics.program_simplify; CoreTactics.equations_simpl. 113 | Next Obligation. 114 | intros Σ p1 p2 p3. 115 | do 3 eapply existT. 116 | reflexivity. 117 | Defined. 118 | 119 | -------------------------------------------------------------------------------- /prover/theories/NamedProofSystem.v: -------------------------------------------------------------------------------- 1 | From MatchingLogicProver Require Export MMProofExtractor. 2 | Set Default Proof Mode "Classic". 3 | 4 | Section named_proof_system. 5 | 6 | Context {signature : Signature}. 7 | 8 | Definition NamedTheory := propset NamedPattern. 9 | 10 | Reserved Notation "theory ⊢N pattern" (at level 76). 11 | Inductive NP_ML_proof_system (theory : NamedTheory) : 12 | NamedPattern -> Set := 13 | 14 | (* Hypothesis *) 15 | | N_hypothesis (axiom : NamedPattern) : 16 | named_well_formed axiom = true -> 17 | axiom ∈ theory -> theory ⊢N axiom 18 | 19 | (* FOL reasoning *) 20 | (* Propositional tautology *) 21 | | N_P1 (phi psi : NamedPattern) : 22 | named_well_formed phi = true -> named_well_formed psi = true -> 23 | theory ⊢N npatt_imp phi (npatt_imp psi phi) 24 | | N_P2 (phi psi xi : NamedPattern) : 25 | named_well_formed phi = true -> named_well_formed psi = true -> named_well_formed xi = true -> 26 | theory ⊢N npatt_imp (npatt_imp phi (npatt_imp psi xi)) 27 | (npatt_imp (npatt_imp phi psi) (npatt_imp phi xi)) 28 | | N_P3 (phi : NamedPattern) : 29 | named_well_formed phi = true -> 30 | theory ⊢N npatt_imp (npatt_imp (npatt_imp phi npatt_bott) npatt_bott) phi 31 | 32 | (* Modus ponens *) 33 | | N_Modus_ponens (phi1 phi2 : NamedPattern) : 34 | named_well_formed phi1 = true -> named_well_formed (npatt_imp phi1 phi2) = true -> 35 | theory ⊢N phi1 -> 36 | theory ⊢N npatt_imp phi1 phi2 -> 37 | theory ⊢N phi2 38 | 39 | (* Existential quantifier *) 40 | | N_Ex_quan (phi : NamedPattern) (x y : evar) : 41 | theory ⊢N npatt_imp (rename_free_evar phi y x) (npatt_exists x phi) 42 | 43 | (* Existential generalization *) 44 | | N_Ex_gen (phi1 phi2 : NamedPattern) (x : evar) : 45 | named_well_formed phi1 = true -> 46 | named_well_formed phi2 = true -> 47 | theory ⊢N npatt_imp phi1 phi2 -> 48 | x ∉ named_free_evars phi2 -> 49 | theory ⊢N npatt_imp (npatt_exists x phi1) phi2 50 | 51 | (* Frame reasoning *) 52 | (* Propagation bottom *) 53 | | N_Prop_bott_left (phi : NamedPattern) : 54 | named_well_formed phi = true -> 55 | theory ⊢N npatt_imp (npatt_app npatt_bott phi) npatt_bott 56 | 57 | | N_Prop_bott_right (phi : NamedPattern) : 58 | named_well_formed phi = true -> 59 | theory ⊢N npatt_imp (npatt_app phi npatt_bott) npatt_bott 60 | 61 | (* Propagation disjunction *) 62 | | N_Prop_disj_left (phi1 phi2 psi : NamedPattern) : 63 | named_well_formed phi1 = true -> 64 | named_well_formed phi2 = true -> 65 | named_well_formed psi = true -> 66 | theory ⊢N npatt_imp (npatt_app (npatt_or phi1 phi2) psi) 67 | (npatt_or (npatt_app phi1 psi) (npatt_app phi2 psi)) 68 | 69 | | N_Prop_disj_right (phi1 phi2 psi : NamedPattern) : 70 | named_well_formed phi1 = true -> 71 | named_well_formed phi2 = true -> 72 | named_well_formed psi = true -> 73 | theory ⊢N npatt_imp (npatt_app psi (npatt_or phi1 phi2)) 74 | (npatt_or (npatt_app psi phi1) (npatt_app psi phi2)) 75 | 76 | (* Propagation exist *) 77 | | N_Prop_ex_left (phi psi : NamedPattern) (x : evar) : 78 | named_well_formed (npatt_exists x phi) = true -> 79 | named_well_formed psi = true -> 80 | x ∉ named_free_evars psi -> 81 | theory ⊢N npatt_imp (npatt_app (npatt_exists x phi) psi) 82 | (npatt_exists x (npatt_app phi psi)) 83 | 84 | | N_Prop_ex_right (phi psi : NamedPattern) (x : evar) : 85 | named_well_formed (npatt_exists x phi) = true -> 86 | named_well_formed psi = true -> 87 | x ∉ named_free_evars psi -> 88 | theory ⊢N npatt_imp (npatt_app psi (npatt_exists x phi)) 89 | (npatt_exists x (npatt_app psi phi)) 90 | 91 | (* Framing *) 92 | | N_Framing_left (phi1 phi2 psi : NamedPattern) : 93 | theory ⊢N npatt_imp phi1 phi2 -> 94 | theory ⊢N npatt_imp (npatt_app phi1 psi) (npatt_app phi2 psi) 95 | 96 | | N_Framing_right (phi1 phi2 psi : NamedPattern) : 97 | theory ⊢N npatt_imp phi1 phi2 -> 98 | theory ⊢N npatt_imp (npatt_app psi phi1) (npatt_app psi phi2) 99 | 100 | (* Fixpoint reasoning *) 101 | (* Set Variable Substitution *) 102 | | N_Svar_subst (phi psi : NamedPattern) (X : svar) : 103 | named_well_formed phi = true -> 104 | named_well_formed psi = true -> 105 | theory ⊢N phi -> theory ⊢N named_svar_subst phi psi X 106 | 107 | (* Pre-Fixpoint *) 108 | | N_Pre_fixp (phi : NamedPattern) (X : svar) : 109 | theory ⊢N npatt_imp (named_svar_subst phi (npatt_mu X phi) X) (npatt_mu X phi) 110 | 111 | (* Knaster-Tarski *) 112 | | N_Knaster_tarski (phi psi : NamedPattern) (X : svar) : 113 | theory ⊢N npatt_imp (named_svar_subst phi psi X) psi -> 114 | theory ⊢N npatt_imp (npatt_mu X phi) psi 115 | 116 | (* Technical rules *) 117 | (* Existence *) 118 | | N_Existence (x : evar) : 119 | theory ⊢N npatt_exists x (npatt_evar x) 120 | 121 | (* Singleton *) 122 | | N_Singleton_ctx (C1 C2 : Named_Application_context) (phi : NamedPattern) (x : evar) : 123 | theory ⊢N npatt_not (npatt_and 124 | (named_subst_ctx C1 (npatt_and (npatt_evar x) phi)) 125 | (named_subst_ctx C2 (npatt_and (npatt_evar x) (npatt_not phi)))) 126 | 127 | where "theory ⊢N pattern" := (NP_ML_proof_system theory pattern). 128 | 129 | End named_proof_system. 130 | -------------------------------------------------------------------------------- /scripts/convert_to_unicode.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import re 3 | 4 | def to_unicode(s: str): 5 | return bytes(s,'ascii').decode("unicode-escape") 6 | 7 | def find_unicodes(f: Path): 8 | try: 9 | patt = re.compile(r'\\'+'u[a-f0-9]{4}') 10 | return f, set(patt.findall(f.open('r').read())) 11 | except UnicodeDecodeError: 12 | raise 13 | if __name__ == '__main__': 14 | AML = Path.cwd() 15 | while AML.name != 'AML-Formalization': 16 | AML = AML.parent 17 | root = AML # / 'matching-logic' / 'src' 18 | replaces = [] 19 | print('The following unicodes were found in the following .v files:') 20 | for f in root.glob('*/*/*.v'): 21 | res = find_unicodes(f) 22 | if len(res[1]) > 0: 23 | print(res[0].relative_to(AML)) 24 | for i in res[1]: 25 | replaces.append((i,to_unicode(i))) 26 | print(f'\t{replaces[-1]}') 27 | print(f"{len(replaces)} codes were replaced in the .v files") 28 | replaces = set(replaces) 29 | for f in root.glob('*/*/*.v'): 30 | data = f.open('r').read() 31 | for esc, uni in replaces: 32 | data = data.replace(esc,uni) 33 | f.open("w",encoding='utf8').write(data) --------------------------------------------------------------------------------