├── .envrc ├── .ghci ├── .gitattributes ├── .github └── workflows │ ├── ghc.yml │ ├── ghcjs.yml │ ├── mkdocs.yml │ └── release.yml ├── .gitignore ├── CITATION.cff ├── CONTRIBUTORS.md ├── README.md ├── cabal.project ├── default.nix ├── docs ├── config │ ├── base.yml │ ├── en │ │ └── mkdocs.yml │ └── ru │ │ └── mkdocs.yml ├── docs │ ├── en │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTORS.md │ │ ├── blog │ │ │ └── index.html │ │ ├── community.md │ │ ├── examples │ │ │ └── recId.rzk.md │ │ ├── getting-started │ │ │ ├── dependent-types.rzk.md │ │ │ ├── index.md │ │ │ ├── install.md │ │ │ ├── project.md │ │ │ └── quickstart.rzk.md │ │ ├── index.md │ │ ├── playground │ │ │ └── index.html │ │ ├── reference │ │ │ ├── builtins │ │ │ │ ├── directed-interval.rzk.md │ │ │ │ └── unit.rzk.md │ │ │ ├── commands │ │ │ │ ├── check.rzk.md │ │ │ │ ├── compute.rzk.md │ │ │ │ ├── define-postulate.rzk.md │ │ │ │ └── options.rzk.md │ │ │ ├── cube-layer.rzk.md │ │ │ ├── extension-types.rzk.md │ │ │ ├── introduction.rzk.md │ │ │ ├── render.rzk.md │ │ │ ├── sections.rzk.md │ │ │ ├── tope-disjunction-elimination.rzk.md │ │ │ ├── tope-layer.rzk.md │ │ │ └── type-layer.rzk.md │ │ ├── related.md │ │ ├── rzk.yaml │ │ └── tools.md │ └── ru │ │ ├── CHANGELOG.md │ │ ├── CONTRIBUTORS.md │ │ ├── blog │ │ └── index.html │ │ ├── community.md │ │ ├── examples │ │ └── recId.rzk.md │ │ ├── getting-started │ │ ├── dependent-types.rzk.md │ │ ├── index.md │ │ ├── install.md │ │ ├── project.md │ │ └── quickstart.rzk.md │ │ ├── index.md │ │ ├── playground │ │ └── index.html │ │ ├── reference │ │ ├── builtins │ │ │ ├── directed-interval.rzk.md │ │ │ └── unit.rzk.md │ │ ├── commands │ │ │ ├── check.rzk.md │ │ │ ├── compute.rzk.md │ │ │ ├── define-postulate.rzk.md │ │ │ └── options.rzk.md │ │ ├── cube-layer.rzk.md │ │ ├── extension-types.rzk.md │ │ ├── introduction.rzk.md │ │ ├── render.rzk.md │ │ ├── sections.rzk.md │ │ ├── tope-disjunction-elimination.rzk.md │ │ ├── tope-layer.rzk.md │ │ └── type-layer.rzk.md │ │ ├── related.md │ │ ├── rzk.yaml │ │ └── tools.md ├── overrides │ ├── assets │ │ ├── css │ │ │ └── rzk-render.css │ │ └── images │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── apple-touch-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon.ico │ │ │ ├── logo-1000x1000.png │ │ │ ├── vscode-rzk-install-prompt.png │ │ │ ├── vscode-rzk-install-success-reload-prompt.png │ │ │ └── vscode-rzk-select-language.png │ └── javascript │ │ └── mathjax.js └── requirements.txt ├── flake.lock ├── flake.nix ├── hie.yaml ├── images ├── split-demo-render.png └── split-demo.png ├── nix ├── default.nix ├── ghcjs.nix ├── js-backend.nix └── scripts.nix ├── rzk-js ├── Main.hs └── rzk-js.cabal ├── rzk-playground ├── .eslintrc.cjs ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── rzk-lezer │ ├── .gitignore │ ├── examples │ │ └── src │ │ │ └── example.rzk │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── run-examples.ts │ │ └── rzk.grammar │ └── tsconfig.json ├── src │ ├── App.tsx │ ├── editor │ │ ├── Editor.tsx │ │ ├── cursor-height.ts │ │ ├── example.ts │ │ ├── parser.ts │ │ └── theme.ts │ ├── index.css │ ├── main.tsx │ └── rzk.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── rzk.yaml ├── rzk ├── .gitignore ├── ChangeLog.md ├── LICENSE ├── Makefile ├── README.md ├── Setup.hs ├── app │ └── Main.hs ├── grammar │ └── Syntax.cf ├── package.yaml ├── rzk.cabal ├── src │ ├── Free │ │ ├── Scoped.hs │ │ └── Scoped │ │ │ └── TH.hs │ ├── Language │ │ └── Rzk │ │ │ ├── Free │ │ │ └── Syntax.hs │ │ │ ├── Makefile │ │ │ ├── Syntax.hs │ │ │ ├── Syntax │ │ │ ├── Abs.hs │ │ │ ├── Doc.txt │ │ │ ├── ErrM.hs │ │ │ ├── Layout.hs │ │ │ ├── Lex.hs │ │ │ ├── Lex.x │ │ │ ├── Par.hs │ │ │ ├── Par.info │ │ │ ├── Par.y │ │ │ ├── Print.hs │ │ │ ├── Skel.hs │ │ │ └── Test.hs │ │ │ └── VSCode │ │ │ ├── Config.hs │ │ │ ├── Env.hs │ │ │ ├── Handlers.hs │ │ │ ├── Logging.hs │ │ │ ├── Lsp.hs │ │ │ └── Tokenize.hs │ ├── Rzk.hs │ └── Rzk │ │ ├── Format.hs │ │ ├── Main.hs │ │ ├── Project │ │ └── Config.hs │ │ └── TypeCheck.hs └── test │ ├── Rzk │ └── FormatSpec.hs │ ├── Spec.hs │ ├── doctests.hs │ └── files │ ├── bin-ops-bad.rzk │ ├── bin-ops-good.rzk │ ├── comments-bad.rzk │ ├── comments-good.rzk │ ├── definition-structure-bad.rzk │ ├── definition-structure-good.rzk │ ├── empty-bad.rzk │ ├── empty-good.rzk │ ├── literate-bad.rzk.md │ ├── literate-good.rzk.md │ ├── tree-structure-bad.rzk │ ├── tree-structure-good.rzk │ ├── unicode-bad.rzk │ └── unicode-good.rzk ├── shell.nix ├── stack.yaml └── stack.yaml.lock /.envrc: -------------------------------------------------------------------------------- 1 | if ! type "nix" > /dev/null; then 2 | use nix -A default 3 | eval "$shellHook" 4 | use nix -A ghcjs 5 | else 6 | use flake .#default 7 | eval "$shellHook" 8 | use flake .#ghcjs 9 | fi -------------------------------------------------------------------------------- /.ghci: -------------------------------------------------------------------------------- 1 | :set -XOverloadedStrings 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | rzk/grammar/Syntax.cf linguist-language=EBNF linguist-detectable=true 2 | rzk/src/Language/Rzk/Syntax/* linguist-generated=true 3 | docs/** linguist-documentation=true 4 | -------------------------------------------------------------------------------- /.github/workflows/ghc.yml: -------------------------------------------------------------------------------- 1 | name: GHC (build, test, haddock) 2 | 3 | # Controls when the workflow will run 4 | on: 5 | push: 6 | branches: [main, develop] 7 | tags: [v*] 8 | paths: 9 | - .github/workflows/ghcjs.yml 10 | - rzk/** 11 | - stack.yaml 12 | - rzk.yaml 13 | - "**/*.rzk.md" 14 | - "**/*.rzk" 15 | - "**/*.rzk.tex" 16 | pull_request: 17 | branches: [develop] 18 | paths: 19 | - .github/workflows/ghcjs.yml 20 | - rzk/** 21 | - stack.yaml 22 | - rzk.yaml 23 | - "**/*.rzk.md" 24 | - "**/*.rzk" 25 | - "**/*.rzk.tex" 26 | 27 | # Allows you to run this workflow manually from the Actions tab 28 | workflow_dispatch: 29 | 30 | permissions: 31 | contents: write 32 | 33 | jobs: 34 | build: 35 | name: "Build and test with GHC" 36 | runs-on: ${{ matrix.os }} 37 | strategy: 38 | matrix: 39 | os: [ubuntu-latest, windows-latest, macos-12] 40 | 41 | steps: 42 | - name: 📥 Checkout repository 43 | uses: actions/checkout@v4 44 | 45 | - name: 🧰 Setup Stack 46 | uses: freckle/stack-action@v5 47 | 48 | - name: Tar and strip the binary 49 | run: | 50 | mkdir -p bin/ 51 | cp $(stack exec -- which rzk) bin/. 52 | tar -cvzf rzk-bin.tar.gz bin/ 53 | shell: bash 54 | 55 | - name: Upload rzk binary as Artifact 56 | uses: actions/upload-artifact@v4 57 | with: 58 | path: rzk-bin.tar.gz 59 | name: rzk-${{ runner.os }}-${{ runner.arch }}.tar.gz 60 | if-no-files-found: error 61 | 62 | haddock: 63 | needs: [build] 64 | if: ${{ github.ref_name == 'develop' }} 65 | name: "Build and upload Haddock documentation (develop)" 66 | runs-on: ubuntu-latest 67 | 68 | steps: 69 | - name: 📥 Checkout repository 70 | uses: actions/checkout@v4 71 | 72 | - name: 🧰 Setup Stack 73 | uses: freckle/stack-action@v5 74 | 75 | - name: 🔨 Build Haddock Documentation (with Stack) 76 | run: | 77 | stack haddock 78 | mkdir -p dist/haddock 79 | mv $(stack path --local-doc-root)/* dist/haddock 80 | 81 | - name: 🚀 Publish Haddock Documentation 82 | uses: JamesIves/github-pages-deploy-action@v4 83 | with: 84 | token: ${{ secrets.GITHUB_TOKEN }} 85 | folder: dist/haddock 86 | target-folder: haddock 87 | single-commit: true 88 | 89 | rzk: 90 | needs: [build] 91 | name: "Check Rzk formalizations" 92 | runs-on: ubuntu-latest 93 | 94 | steps: 95 | - name: 📥 Checkout repository 96 | uses: actions/checkout@v4 97 | 98 | - name: 📥 Download rzk 99 | id: download 100 | uses: actions/download-artifact@v4 101 | with: 102 | name: rzk-${{ runner.os }}-${{ runner.arch }}.tar.gz 103 | 104 | - name: Unpack rzk-bin.tar.gz 105 | run: | 106 | tar xzf ${{ steps.download.outputs.download-path}}/rzk-bin.tar.gz 107 | 108 | - name: Check Rzk files 109 | run: ./bin/rzk typecheck 110 | shell: bash 111 | -------------------------------------------------------------------------------- /.github/workflows/ghcjs.yml: -------------------------------------------------------------------------------- 1 | name: GHCJS (build and deploy Rzk playground) 2 | 3 | on: 4 | push: 5 | branches: [main, develop] 6 | tags: [v*] 7 | paths: 8 | - .github/workflows/ghcjs.yml 9 | - rzk/** 10 | - rzk-js/** 11 | - rzk-playground/** 12 | - stack.yaml 13 | - "**/*.nix" 14 | pull_request: 15 | branches: [develop] 16 | paths: 17 | - .github/workflows/ghcjs.yml 18 | - rzk/** 19 | - rzk-js/** 20 | - rzk-playground/** 21 | - stack.yaml 22 | - "**/*.nix" 23 | 24 | workflow_dispatch: # allow triggering this workflow manually 25 | 26 | permissions: 27 | contents: write 28 | 29 | jobs: 30 | build-and-deploy-with-ghcjs: 31 | name: "Build with GHCJS (and deploy Rzk playground)" 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: 📥 Checkout repository 35 | uses: actions/checkout@v4 36 | 37 | - name: ❄️ Install Nix 38 | uses: nixbuild/nix-quick-install-action@v27 39 | with: 40 | nix_conf: | 41 | substituters = https://cache.nixos.org/ https://cache.iog.io https://nix-community.cachix.org https://miso-haskell.cachix.org 42 | trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= miso-haskell.cachix.org-1:6N2DooyFlZOHUfJtAx1Q09H0P5XXYzoxxQYiwn6W1e8= 43 | keep-outputs = true 44 | 45 | - name: 👝 Restore and Cache Nix store 46 | uses: nix-community/cache-nix-action@v5 47 | with: 48 | primary-key: ${{ runner.os }}-nix-${{ hashfiles('./flake.nix', './flake.lock', '.github/workflows/ghcjs.yml', './rzk/rzk.cabal') }} 49 | restore-prefixes-first-match: | 50 | ${{ runner.os }}-nix-${{ hashfiles('./flake.nix', './flake.lock', '.github/workflows/ghcjs.yml', './rzk/rzk.cabal') }} 51 | ${{ runner.os }}-nix- 52 | gc-max-store-size: 7000000000 53 | purge: true 54 | purge-prefixes: ${{ runner.os }}-nix- 55 | purge-created: 0 56 | purge-primary-key: never 57 | 58 | - name: 👝 Restore and cache NodeJS deps 59 | uses: actions/cache@v4 60 | with: 61 | key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} 62 | restore-keys: | 63 | ${{ runner.os }}-node- 64 | path: | 65 | ~/.npm 66 | 67 | - name: 🔨 Remove lexer and parser generator files 68 | run: | 69 | rm -f rzk/src/Language/Rzk/Syntax/Lex.x 70 | rm -f rzk/src/Language/Rzk/Syntax/Par.y 71 | 72 | # Uncomment to debug this job 73 | # - name: Setup tmate session 74 | # uses: mxschmitt/action-tmate@v3 75 | 76 | - name: 🔨 Build Playground 77 | env: 78 | ASSET_URL: /${{ github.event.repository.name }}/${{ github.ref_name }}/playground 79 | run: nix run .#release-rzk-playground 80 | 81 | - name: 🔨 Save flake from garbage collection 82 | run: nix run .#save-flake 83 | 84 | - name: '🚀 Publish JS "binaries" (${{ github.ref_name }})' 85 | if: ${{ github.ref_name != 'main' && github.event_name == 'push' }} 86 | uses: JamesIves/github-pages-deploy-action@v4 87 | with: 88 | token: ${{ secrets.GITHUB_TOKEN }} 89 | folder: rzk-playground-release 90 | target-folder: ${{ github.ref_name }}/playground 91 | clean: false 92 | single-commit: true 93 | 94 | - name: '🚀 Publish JS "binaries" (latest)' 95 | if: ${{ startsWith(github.ref, 'refs/tags/') && startsWith(github.ref_name, 'v') && github.event_name == 'push' }} 96 | uses: JamesIves/github-pages-deploy-action@v4 97 | with: 98 | token: ${{ secrets.GITHUB_TOKEN }} 99 | folder: rzk-playground-release 100 | target-folder: latest/playground 101 | clean: false 102 | single-commit: true 103 | 104 | - name: '🚀 Publish JS "binaries"' 105 | if: ${{ github.ref_name == 'main' && github.event_name == 'push' }} 106 | uses: JamesIves/github-pages-deploy-action@v4 107 | with: 108 | token: ${{ secrets.GITHUB_TOKEN }} 109 | folder: rzk-playground-release 110 | target-folder: playground 111 | clean: false 112 | single-commit: true 113 | -------------------------------------------------------------------------------- /.github/workflows/mkdocs.yml: -------------------------------------------------------------------------------- 1 | name: MKDocs 2 | 3 | on: 4 | push: 5 | branches: [develop, mkdocs-*] 6 | tags: [v*] 7 | paths: 8 | - .github/workflows/mkdocs.yml 9 | - docs/** 10 | 11 | workflow_dispatch: 12 | 13 | permissions: 14 | contents: write 15 | 16 | jobs: 17 | mkdocs: 18 | name: "Build and Deploy MkDocs to GitHub Pages" 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: 📥 Checkout repository 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: 🧰 Set up Python 27 | uses: actions/setup-python@v5 28 | with: 29 | python-version: "3.9" 30 | cache: "pip" # caching pip dependencies 31 | 32 | - name: 🔨 Install rzk proof assistant 33 | uses: jaxxstorm/action-install-gh-release@v1.10.0 34 | with: 35 | repo: rzk-lang/rzk 36 | tag: latest # FIXME: should use the version from the same Git commit 37 | rename-to: rzk 38 | chmod: 0755 39 | 40 | - name: Check Rzk files for each language 41 | run: for lang_dir in $(ls -d docs/docs/*/); do 42 | pushd ${lang_dir} && rzk typecheck; popd ; 43 | done 44 | 45 | - name: Check Rzk formatting for each language 46 | run: for lang_dir in $(ls -d docs/docs/*/); do 47 | pushd ${lang_dir} && rzk format --check; popd ; 48 | done 49 | 50 | - name: 🔨 Install MkDocs Material and mike 51 | run: pip install -r docs/requirements.txt 52 | 53 | - name: ⚙️ Configure Git user 54 | run: | 55 | git config --local user.email "github-actions[bot]@users.noreply.github.com" 56 | git config --local user.name "github-actions[bot]" 57 | 58 | - name: 🚀 Deploy with mike (${{ github.ref_name }}, latest) 59 | if: ${{ github.ref_name != 'develop' && !startsWith(github.ref_name, 'mkdocs') }} 60 | run: | 61 | for config in $(ls docs/config/*/mkdocs.yml); do 62 | mike deploy --push --update-aliases --config-file ${config} ${{ github.ref_name }} latest; 63 | mike set-default latest --config-file ${config} --push; 64 | done 65 | 66 | - name: 🚀 Deploy with mike (${{ github.ref_name }}) 67 | if: ${{ github.ref_name == 'develop' || startsWith(github.ref_name, 'mkdocs') }} 68 | run: | 69 | for config in $(ls docs/config/*/mkdocs.yml); do 70 | mike deploy --push --config-file ${config} ${{ github.ref_name }}; 71 | done 72 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | release: 4 | types: [published] 5 | 6 | permissions: 7 | contents: write 8 | 9 | jobs: 10 | hackage: 11 | name: "Upload a new candidate on Hackage" 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: 📥 Checkout repository 15 | uses: actions/checkout@v4 16 | 17 | - name: 🧰 Setup Stack 18 | uses: freckle/stack-action@v5 19 | with: 20 | fast: false 21 | 22 | - name: 🔨 Generate package dist tarball 23 | run: stack sdist --tar-dir packages/ 24 | 25 | - name: 🚀 Upload on Hackage 26 | uses: haskell-actions/hackage-publish@v1 27 | with: 28 | hackageToken: ${{ secrets.HACKAGE_AUTH_TOKEN }} 29 | packagesPath: packages 30 | publish: false 31 | 32 | binaries: 33 | runs-on: ${{ matrix.os }} 34 | strategy: 35 | matrix: 36 | os: [ubuntu-latest, windows-latest, macos-latest] 37 | 38 | steps: 39 | - name: 📥 Checkout repository 40 | uses: actions/checkout@v4 41 | 42 | - name: 🧰 Setup Stack 43 | uses: freckle/stack-action@v5 44 | with: 45 | fast: false 46 | 47 | - name: Tar and strip the binary 48 | run: | 49 | mkdir -p prepared_binaries/ 50 | cd prepared_binaries/ 51 | export PROGRAM=rzk 52 | cp `stack exec -- which $PROGRAM` . 53 | tar -cavf program.tar.gz * 54 | shell: bash 55 | 56 | - name: 🚀 Upload assets 57 | id: upload-release-asset 58 | uses: actions/upload-release-asset@v1 59 | env: 60 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 61 | with: 62 | upload_url: ${{ github.event.release.upload_url }} 63 | asset_path: ./prepared_binaries/program.tar.gz 64 | asset_name: rzk-${{ github.ref_name }}-${{ runner.os }}-${{ runner.arch }}.tar.gz 65 | asset_content_type: application/tar.gz 66 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache/ 2 | .DS_Store 3 | docs/out/ 4 | docs/generated/ 5 | dist 6 | dist-* 7 | cabal-dev 8 | build 9 | *.o 10 | *.hi 11 | *.hie 12 | *.chi 13 | *.chs.h 14 | *.dyn_o 15 | *.dyn_hi 16 | .hpc 17 | .hsenv 18 | .cabal-sandbox/ 19 | cabal.sandbox.config 20 | *.prof 21 | *.aux 22 | *.hp 23 | *.eventlog 24 | .stack-work/ 25 | cabal.project.local 26 | cabal.project.local~ 27 | .HTF/ 28 | .ghc.environment.* 29 | docs/site 30 | result 31 | .direnv 32 | venv 33 | __pycache__ 34 | *.fdb_latexmk 35 | *.fls 36 | *.log 37 | rzk/doc/ 38 | /rzk-playground-release 39 | -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | authors: 3 | - family-names: Kudasov 4 | given-names: Nikolai 5 | orcid: "https://orcid.org/0000-0001-6572-7292" 6 | - family-names: Abounegm 7 | given-names: Abdelrahman 8 | - family-names: Danko 9 | given-names: Danila 10 | title: "Rzk: a proof assistant for synthetic $\\infty$-categories" 11 | version: 0.7.5 12 | url: "https://github.com/rzk-lang/rzk" 13 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # List of contributors 2 | 3 | The following people have contributed to Rzk proof assistant: 4 | 5 | 1. [Nikolai Kudasov](https://fizruk.github.io) 6 | 2. [Abdelrahman Abounegm](https://github.com/aabounegm/) — contributed to the Rzk Language Server 7 | 3. [Danila Danko](https://github.com/deemp) — helped set up Nix and Rzk playground 8 | 9 | You may see actual contributed commits in the [Contributors page on GitHub](https://github.com/rzk-lang/rzk/graphs/contributors). 10 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: rzk rzk-js -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | let t = (import 2 | ( 3 | let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in 4 | fetchTarball { 5 | url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; 6 | sha256 = lock.nodes.flake-compat.locked.narHash; 7 | } 8 | ) 9 | { src = ./.; } 10 | ).defaultNix; in t // t.packages.${builtins.currentSystem} -------------------------------------------------------------------------------- /docs/config/base.yml: -------------------------------------------------------------------------------- 1 | repo_url: https://github.com/rzk-lang/rzk 2 | repo_name: rzk-lang/rzk 3 | 4 | theme: 5 | name: material 6 | custom_dir: '../../overrides/' 7 | favicon: assets/images/favicon.png 8 | logo: assets/images/logo-1000x1000.png 9 | icon: 10 | repo: fontawesome/brands/github 11 | edit: material/pencil 12 | view: material/eye 13 | features: 14 | - content.code.copy 15 | - content.action.edit 16 | - navigation.footer 17 | - navigation.tabs 18 | - navigation.tabs.sticky 19 | - navigation.sections 20 | - navigation.prune 21 | - navigation.path 22 | - navigation.indexes 23 | - toc.integrate 24 | 25 | extra_javascript: 26 | - javascript/mathjax.js 27 | - https://polyfill.io/v3/polyfill.min.js?features=es6 28 | - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 29 | 30 | extra_css: 31 | - https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.7/katex.min.css 32 | - https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css 33 | - assets/css/rzk-render.css 34 | 35 | markdown_extensions: 36 | - admonition 37 | - footnotes 38 | - pymdownx.details 39 | - pymdownx.snippets: 40 | base_path: 41 | - . 42 | - .. 43 | check_paths: true 44 | - mdx_math 45 | - pymdownx.highlight: 46 | anchor_linenums: true 47 | line_spans: __span 48 | pygments_lang_class: true 49 | - pymdownx.inlinehilite 50 | - pymdownx.snippets 51 | - pymdownx.superfences 52 | - toc: 53 | permalink: true 54 | - pymdownx.arithmatex: 55 | generic: true 56 | - attr_list 57 | 58 | extra: 59 | version: 60 | provider: mike 61 | alternate: 62 | - name: English 63 | link: /rzk/en/ 64 | lang: en 65 | - name: Русский 66 | link: /rzk/ru/ 67 | lang: ru 68 | -------------------------------------------------------------------------------- /docs/config/en/mkdocs.yml: -------------------------------------------------------------------------------- 1 | INHERIT: "../base.yml" 2 | site_url: https://rzk-lang.github.io/rzk/en/ 3 | site_name: "Rzk proof assistant" 4 | site_description: "An experimental proof assistant for simplicial type theory and synthetic ∞-categories." 5 | site_author: "Nikolai Kudasov" 6 | docs_dir: '../../docs/en' 7 | site_dir: '../../generated/en' 8 | edit_uri: edit/develop/docs/docs/en/ 9 | 10 | nav: 11 | - About: 12 | - index.md 13 | - Community: community.md 14 | - Tools: tools.md 15 | - Contributors: CONTRIBUTORS.md 16 | - Changelog: CHANGELOG.md 17 | - Other proof assistants: related.md 18 | - Getting Started: 19 | - getting-started/index.md 20 | - Install: getting-started/install.md 21 | - Quickstart: getting-started/quickstart.rzk.md 22 | - Dependent Types: getting-started/dependent-types.rzk.md 23 | - Setting up an Rzk project: getting-started/project.md 24 | - Reference: 25 | - Introduction: reference/introduction.rzk.md 26 | - Cube layer: reference/cube-layer.rzk.md 27 | - Tope layer: reference/tope-layer.rzk.md 28 | - Dependent types: reference/type-layer.rzk.md 29 | - Tope disjunction elimination: reference/tope-disjunction-elimination.rzk.md 30 | - Extension types: reference/extension-types.rzk.md 31 | - Organizational features: 32 | - Sections and Variables: reference/sections.rzk.md 33 | - Builtins: 34 | - Directed interval: reference/builtins/directed-interval.rzk.md 35 | - Unit type: reference/builtins/unit.rzk.md 36 | - Commands: 37 | - Define and Postulate: reference/commands/define-postulate.rzk.md 38 | - Compute: reference/commands/compute.rzk.md 39 | - Check: reference/commands/check.rzk.md 40 | - Options: reference/commands/options.rzk.md 41 | - Other: 42 | - Rendering Diagrams: reference/render.rzk.md 43 | - Examples: 44 | - Weak tope disjunction elimination: examples/recId.rzk.md 45 | - Playground: playground/index.html 46 | - Blog: blog/index.html 47 | 48 | theme: 49 | language: en 50 | font: 51 | text: Inria Sans 52 | palette: 53 | # Palette toggle for light mode 54 | - media: "(prefers-color-scheme: light)" 55 | primary: white 56 | scheme: default 57 | toggle: 58 | icon: material/brightness-7 59 | name: "Switch to dark mode" 60 | # Palette toggle for dark mode 61 | - media: "(prefers-color-scheme: dark)" 62 | primary: black 63 | scheme: slate 64 | toggle: 65 | icon: material/brightness-4 66 | name: "Switch to light mode" 67 | 68 | plugins: 69 | - social 70 | - mike: 71 | deploy_prefix: 'en/' 72 | - search: 73 | lang: en 74 | - rzk: 75 | render_svg: true 76 | anchor_definitions: true 77 | -------------------------------------------------------------------------------- /docs/config/ru/mkdocs.yml: -------------------------------------------------------------------------------- 1 | INHERIT: "../base.yml" 2 | site_url: https://rzk-lang.github.io/rzk/ru/ 3 | site_name: "Решатель теорем Rzk" 4 | site_description: "Экспериментальный решатель теорем для симплициальной теории типов и синтетических ∞-категорий." 5 | site_author: "Николай Кудасов" 6 | docs_dir: '../../docs/ru' 7 | site_dir: '../../generated/ru' 8 | edit_uri: edit/develop/docs/docs/ru/ 9 | 10 | nav: 11 | - О проекте: 12 | - index.md 13 | - Сообщество: community.md 14 | - Инструменты: tools.md 15 | - Участники (англ.): CONTRIBUTORS.md 16 | - История изменений (англ.): CHANGELOG.md 17 | - Другие решатели: related.md 18 | - Первые шаги: 19 | - getting-started/index.md 20 | - Установка: getting-started/install.md 21 | - Быстрое начало: getting-started/quickstart.rzk.md 22 | - Введение в зависимые типы: getting-started/dependent-types.rzk.md 23 | - Настройка проекта: getting-started/project.md 24 | - Руководство: 25 | - Введение: reference/introduction.rzk.md 26 | - Слой кубов: reference/cube-layer.rzk.md 27 | - Слой форм: reference/tope-layer.rzk.md 28 | - Зависимые типы: reference/type-layer.rzk.md 29 | - Устранение объединений форм: reference/tope-disjunction-elimination.rzk.md 30 | - Типы-расширения: reference/extension-types.rzk.md 31 | - Организация кода: 32 | - Разделы и предпосылки: reference/sections.rzk.md 33 | - Встроенные определения: 34 | - Направленный интервал: reference/builtins/directed-interval.rzk.md 35 | - Единичный тип: reference/builtins/unit.rzk.md 36 | - Команды: 37 | - Определения и постулаты: reference/commands/define-postulate.rzk.md 38 | - Вычисления: reference/commands/compute.rzk.md 39 | - Проверка типов: reference/commands/check.rzk.md 40 | - Опции решателя: reference/commands/options.rzk.md 41 | - Другое: 42 | - Отрисовка диаграм: reference/render.rzk.md 43 | - Примеры: 44 | - Слабое устранение объединений форм: examples/recId.rzk.md 45 | - Песочница: playground/index.html 46 | - Блог (англ.): blog/index.html 47 | 48 | theme: 49 | language: ru 50 | font: 51 | text: PT Sans 52 | palette: 53 | # Palette toggle for light mode 54 | - media: "(prefers-color-scheme: light)" 55 | primary: white 56 | scheme: default 57 | toggle: 58 | icon: material/brightness-7 59 | name: "Переключить на тёмный режим" 60 | # Palette toggle for dark mode 61 | - media: "(prefers-color-scheme: dark)" 62 | primary: black 63 | scheme: slate 64 | toggle: 65 | icon: material/brightness-4 66 | name: "Переключить на светлый режим" 67 | 68 | plugins: 69 | - social 70 | - mike: 71 | deploy_prefix: 'ru/' 72 | - search: 73 | lang: ru 74 | - rzk: 75 | render_svg: true 76 | anchor_definitions: true 77 | -------------------------------------------------------------------------------- /docs/docs/en/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | --8<-- "rzk/ChangeLog.md" 2 | -------------------------------------------------------------------------------- /docs/docs/en/CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | --8<-- "CONTRIBUTORS.md" 2 | -------------------------------------------------------------------------------- /docs/docs/en/blog/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redirecting 6 | 9 | 12 | 13 | 14 | Redirecting to Blog/... 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/docs/en/community.md: -------------------------------------------------------------------------------- 1 | # Rzk Community 2 | 3 | There is a small community of mathematicians and computer scientists around Rzk. 4 | 5 | ## Chat 6 | 7 | A Zulip chat is available for all to join and chat about Rzk, including formalization projects, development of Rzk, and related projects: 8 | 9 | [Join Rzk Zulip](https://rzk-lang.zulipchat.com/register/){ .md-button .md-button--primary } 10 | -------------------------------------------------------------------------------- /docs/docs/en/examples/recId.rzk.md: -------------------------------------------------------------------------------- 1 | # Tope disjuction elimination along identity paths 2 | 3 | \(\mathsf{rec}_{\lor}^{\ψ,\φ}(a_\ψ, a*\φ)\) (written `recOR(ψ, φ, a_psi, a_phi)` in the code) 4 | is well-typed when \(a*\ψ\) and \(a*\φ\) are \_definitionally equal* on \(\ψ \land \φ\). 5 | Sometimes this is too strong since many terms are not _definitionally_ equal, but only equal up to a path. 6 | Luckily, assuming relative function extensionality, we can define a weaker version of \(rec*{\lor}\) (`recOR`), which we call `recId`, that can work in presence of a witness of type \(\prod*{t : I \mid \ψ \land \φ} a*\ψ = a*\φ\). 7 | 8 | ## Prerequisites 9 | 10 | This file relies on some definitions, defined in 11 | 12 | - [Getting Started > Dependent Types](../getting-started/dependent-types.rzk.md) 13 | 14 | We begin by introducing common HoTT definitions: 15 | 16 | ```rzk 17 | #lang rzk-1 18 | 19 | -- A is contractible there exists x : A such that for any y : A we have x = y. 20 | #define iscontr (A : U) 21 | : U 22 | := Σ (a : A) , (x : A) → a =_{A} x 23 | 24 | -- A is a proposition if for any x, y : A we have x = y 25 | #define isaprop (A : U) 26 | : U 27 | := (x : A) → (y : A) → x =_{A} y 28 | 29 | -- A is a set if for any x, y : A the type x =_{A} y is a proposition 30 | #define isaset (A : U) 31 | : U 32 | := (x : A) → (y : A) → isaprop (x =_{A} y) 33 | 34 | -- A function f : A → B is an equivalence 35 | -- if there exists g : B → A 36 | -- such that for all x : A we have g (f x) = x 37 | -- and for all y : B we have f (g y) = y 38 | #define isweq (A : U) (B : U) (f : A → B) 39 | : U 40 | := Σ (g : B → A) 41 | , prod 42 | ( ( x : A) → g (f x) =_{A} x) 43 | ( ( y : B) → f (g y) =_{B} y) 44 | 45 | -- Equivalence of types A and B 46 | #define weq (A : U) (B : U) 47 | : U 48 | := Σ (f : A → B) 49 | , isweq A B f 50 | 51 | -- Transport along a path 52 | #define transport 53 | ( A : U) 54 | ( C : A → U) 55 | ( x y : A) 56 | ( p : x =_{A} y) 57 | : C x → C y 58 | := \ cx → idJ(A , x , (\ z q → C z) , cx , y , p) 59 | ``` 60 | 61 | ## Relative function extensionality 62 | 63 | We can now define relative function extensionality. There are several formulations, we provide two, following Riehl and Shulman: 64 | 65 | ```rzk 66 | -- [RS17, Axiom 4.6] Relative function extensionality. 67 | #define relfunext 68 | : U 69 | := (I : CUBE) 70 | → ( ψ : I → TOPE) 71 | → ( φ : ψ → TOPE) 72 | → ( A : ψ → U) 73 | → ( ( t : ψ) → iscontr (A t)) 74 | → ( a : (t : φ) → A t) 75 | → ( t : ψ) → A t [ φ t ↦ a t] 76 | 77 | -- [RS17, Proposition 4.8] A (weaker) formulation of function extensionality. 78 | #define relfunext2 79 | : U 80 | := 81 | ( I : CUBE) 82 | → ( ψ : I → TOPE) 83 | → ( φ : ψ → TOPE) 84 | → ( A : ψ → U) 85 | → ( a : (t : φ) → A t) 86 | → ( f : (t : ψ) → A t [ φ t ↦ a t ]) 87 | → ( g : (t : ψ) → A t [ φ t ↦ a t ]) 88 | → weq 89 | ( f = g) 90 | ( ( t : ψ) → (f t =_{A t} g t) [ φ t ↦ refl ]) 91 | ``` 92 | 93 | ## Construction of `recId` 94 | 95 | The idea is straightforward. We ask for a proof that `a = b` for all points in `ψ ∧ φ`. Then, by relative function extensionality (`relfunext2`), we can show that restrictions of `a` and `b` to `ψ ∧ φ` are equal. If we reformulate `a` as extension of its restriction, then we can `transport` such reformulation along the path connecting two restrictions and apply `recOR`. 96 | 97 | First, we define how to restrict an extension type to a subshape: 98 | 99 | ```rzk 100 | #section construction-of-recId 101 | 102 | #variable r : relfunext2 103 | #variable I : CUBE 104 | #variables ψ φ : I → TOPE 105 | #variable A : (t : I | ψ t ∨ φ t) → U 106 | 107 | -- Restrict extension type to a subshape. 108 | #define restrict_phi 109 | ( a : (t : φ) → A t) 110 | : ( t : I | ψ t ∧ φ t) → A t 111 | := \ t → a t 112 | 113 | -- Restrict extension type to a subshape. 114 | #define restrict_psi 115 | ( a : (t : ψ) → A t) 116 | : ( t : I | ψ t ∧ φ t) → A t 117 | := \ t → a t 118 | ``` 119 | 120 | Then, how to reformulate an `a` (or `b`) as an extension of its restriction: 121 | 122 | ```rzk 123 | -- Reformulate extension type as an extension of a restriction. 124 | #define ext-of-restrict_psi 125 | ( a : (t : ψ) → A t) 126 | : ( t : ψ) 127 | → A t [ ψ t ∧ φ t ↦ restrict_psi a t ] 128 | := a -- type is coerced automatically here 129 | 130 | -- Reformulate extension type as an extension of a restriction. 131 | #define ext-of-restrict_phi 132 | ( a : (t : φ) → A t) 133 | : ( t : φ) 134 | → A t [ ψ t ∧ φ t ↦ restrict_phi a t ] 135 | := a -- type is coerced automatically here 136 | ``` 137 | 138 | Now, assuming relative function extensionality, we construct a path between restrictions: 139 | 140 | ```rzk 141 | -- Transform extension of an identity into an identity of restrictions. 142 | #define restricts-path 143 | ( a_psi : (t : ψ) → A t) 144 | ( a_phi : (t : φ) → A t) 145 | : ( e : (t : I | ψ t ∧ φ t) → a_psi t = a_phi t) 146 | → restrict_psi a_psi = restrict_phi a_phi 147 | := 148 | first 149 | ( second 150 | ( r I 151 | ( \ t → ψ t ∧ φ t) 152 | ( \ t → BOT) 153 | ( \ t → A t) 154 | ( \ t → recBOT) 155 | ( \ t → a_psi t) 156 | ( \ t → a_phi t))) 157 | ``` 158 | 159 | Finally, we bring everything together into `recId`: 160 | 161 | ```rzk 162 | -- A weaker version of recOR, demanding only a path between a and b: 163 | -- recOR(ψ, φ, a, b) demands that for ψ ∧ φ we have a == b (definitionally) 164 | -- (recId ψ φ a b e) demands that e is the proof that a = b (intensionally) for ψ ∧ φ 165 | #define recId uses (r) -- we declare that recId is using r on purpose 166 | ( a_psi : (t : ψ) → A t) 167 | ( a_phi : (t : φ) → A t) 168 | ( e : (t : I | ψ t ∧ φ t) → a_psi t = a_phi t) 169 | : ( t : I | ψ t ∨ φ t) → A t 170 | := \ t → recOR( 171 | ψ t ↦ 172 | transport 173 | ( ( s : I | ψ s ∧ φ s) → A s) 174 | ( \ ra → (s : ψ) → A s [ ψ s ∧ φ s ↦ ra s ]) 175 | ( restrict_psi a_psi) 176 | ( restrict_phi a_phi) 177 | ( restricts-path a_psi a_phi e) 178 | ( ext-of-restrict_psi a_psi) 179 | ( t) 180 | , φ t ↦ 181 | ext-of-restrict_phi a_phi t 182 | ) 183 | 184 | #end construction-of-recId 185 | ``` 186 | 187 | ## Gluing extension types 188 | 189 | An application of of `recId` is gluing together extension types, 190 | whenever we can show that they are equal on the intersection of shapes: 191 | 192 | ```rzk 193 | -- If two extension types are equal along two subshapes, 194 | -- then they are also equal along their union. 195 | #define id-along-border 196 | ( r : relfunext2) 197 | ( I : CUBE) 198 | ( ψ : I → TOPE) 199 | ( φ : I → TOPE) 200 | ( A : (t : I | ψ t ∨ φ t) → U) 201 | ( a b : (t : I | ψ t ∨ φ t) → A t) 202 | ( e_psi : (t : ψ) → a t = b t) 203 | ( e_phi : (t : φ) → a t = b t) 204 | ( border-is-a-set : (t : I | ψ t ∧ φ t) → isaset (A t)) 205 | : ( t : I | ψ t ∨ φ t) → a t = b t 206 | := 207 | recId r I ψ φ 208 | ( \ t → a t = b t) 209 | ( e_psi) 210 | ( e_phi) 211 | ( \ t → border-is-a-set t (a t) (b t) (e_psi t) (e_phi t)) 212 | ``` 213 | -------------------------------------------------------------------------------- /docs/docs/en/getting-started/index.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Rzk 2 | 3 | 1. [Install Rzk](install.md). 4 | 2. Get a [quick overview](quickstart.rzk.md) of Rzk language. 5 | 3. Get through the [introduction to dependent types](dependent-types.rzk.md) in Rzk. 6 | 4. Learn how to configure formalization [projects in Rzk](project.md). 7 | 5. Learn more about Rzk features in the [Rzk Reference](../reference/index.md). 8 | -------------------------------------------------------------------------------- /docs/docs/en/getting-started/install.md: -------------------------------------------------------------------------------- 1 | # How to install Rzk 2 | 3 | ## VS Code extension with binaries (recommended) 4 | 5 | These instructions will walk you through setting up Rzk using the "basic" setup and VS Code as the editor. 6 | 7 | 1. Install [VS Code](https://code.visualstudio.com/). 8 | 2. Launch VS Code and install the [`rzk` extension](https://marketplace.visualstudio.com/items?itemName=NikolaiKudasovfizruk.rzk-1-experimental-highlighting). 9 | 3. Create a new file using "File > New Text File" (Ctrl+N). Click the `Select a language` prompt, type in `rzk`, and select "Literate Rzk Markdown". 10 | ![VS Code rzk language selector.](../assets/images/vscode-rzk-select-language.png) 11 | 4. You should see the following popup: 12 | ![VS Code rzk install prompt.](../assets/images/vscode-rzk-install-prompt.png) 13 | 5. Click "Yes" button. 14 | 6. While it is installing, you can paste the following literate Rzk program into the new file: 15 | 16 | ````markdown 17 | # Sample literate Rzk markdown 18 | 19 | ```rzk 20 | #lang rzk-1 21 | 22 | #define id (A : U) 23 | : A -> A 24 | := \ x -> x 25 | ``` 26 | ```` 27 | 28 | 7. When the installation is done you should see the following popup: 29 | ![VS Code rzk reload prompt.](../assets/images/vscode-rzk-install-success-reload-prompt.png) 30 | 8. Click "Reload button". 31 | 9. Save your file as `example.rzk.md`. 32 | 10. Open local Terminal (Ctrl+`). 33 | 34 | 35 | 36 | 11. In the terminal, run 37 | 38 | ```sh 39 | rzk typecheck example.rzk.md 40 | ``` 41 | 42 | 12. You should see the output of the proof assistant: 43 | 44 | ```text 45 | Loading file example.rzk.md 46 | Checking module from example.rzk.md 47 | [ 1 out of 1 ] Checking #define id 48 | Everything is ok! 49 | ``` 50 | 51 | 13. Congratulations! Now you have a working rzk setup :) Note that the rzk extension will notify you about updates of `rzk` and prompt updating to new versions. 52 | 53 | 14. See [Quickstart](quickstart.rzk.md) to get familiar with the Rzk language! 54 | 55 | ## Install binaries 56 | 57 | ### Download from GitHub 58 | 59 | You can download and use binaries (at least for some platforms) directly for one of the latest releases on GitHub at . If your platform is not represented, please consider leaving an issue at . 60 | 61 | ## Install from sources 62 | 63 | You can install `rzk` from sources. You can get the latest "stable" release from Hackage or build from the `develop` branch on GitHub. 64 | 65 | ### Stack 66 | 67 | To build and install with Stack from Hackage: 68 | 69 | ```sh 70 | stack install rzk 71 | ``` 72 | 73 | To build and install with Stack from sources on GitHub: 74 | 75 | ```sh 76 | git clone https://github.com/rzk-lang/rzk.git 77 | cd rzk 78 | git checkout develop 79 | stack build && stack install 80 | ``` 81 | 82 | ### cabal-install 83 | 84 | To build and install with `cabal-install` from Hackage: 85 | 86 | ```sh 87 | cabal v2-update 88 | cabal v2-install rzk 89 | ``` 90 | 91 | To build and install with `cabal-install` from sources on GitHub: 92 | 93 | ```sh 94 | git clone https://github.com/rzk-lang/rzk.git 95 | cd rzk 96 | git checkout develop 97 | cabal v2-build && cabal v2-install 98 | ``` 99 | 100 | ### Nix 101 | 102 | !!! warning "Work-in-progress" 103 | 104 | To be done. 105 | -------------------------------------------------------------------------------- /docs/docs/en/getting-started/project.md: -------------------------------------------------------------------------------- 1 | # Setting up an Rzk project 2 | 3 | !!! warning "Work-in-progress" 4 | Guide will be here soon. 5 | For now, please use the template project: . 6 | Also check out for an example of a project with generated documentation. 7 | -------------------------------------------------------------------------------- /docs/docs/en/getting-started/quickstart.rzk.md: -------------------------------------------------------------------------------- 1 | # Quick introduction into Rzk 2 | 3 | !!! warning "Work-in-progress" 4 | Documentation is a work in progress. 5 | 6 | First, [install Rzk](install.md). 7 | 8 | This is a literate `rzk` file: 9 | 10 | ```rzk 11 | #lang rzk-1 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/docs/en/index.md: -------------------------------------------------------------------------------- 1 | # Rzk proof assistant 2 | 3 | Rzk is an experimental proof assistant, 4 | based on [«Type Theory for Synthetic ∞-categories»](https://arxiv.org/abs/1705.07442)[^1]. 5 | 6 | [Get started with Rzk](getting-started/install.md){ .md-button .md-button--primary } 7 | [Try Rzk Playground](playground/index.html){ .md-button } 8 | 9 | ## About this project 10 | 11 | This project has started with the idea of bringing Riehl and Shulman's 2017 paper[^1] 12 | to "life" by implementing a proof assistant based on their type theory with shapes. 13 | At the moment, Rzk provides a language that is close to the original paper, 14 | as well as some tooling around it (such as a VS Code extension and a language server with syntax highlighting and formatting support). 15 | 16 | ### Formalizing ∞-category theory 17 | 18 | A big portion of the original paper (up to the ∞-categorical Yoneda lemma) has been formalized in Rzk (see [Yoneda for ∞-categories](https://emilyriehl.github.io/yoneda/)[^2]). 19 | More formalization results are under way (see [sHoTT](https://rzk-lang.github.io/sHoTT/)). 20 | There are also some efforts to formalize the HoTT Book in Rzk (see [hottbook](https://rzk-lang.github.io/hottbook/)). 21 | 22 | ### Using Rzk 23 | 24 | The recommended way of interacting with Rzk is via VS Code (see [Getting Started](getting-started/install.md)), 25 | but you can also download binaries from [GitHub Releases](https://github.com/rzk-lang/rzk/releases), build [from sources](getting-started/install.md#install-from-sources), 26 | or try setting up the Rzk Language Server with your editor of choice. 27 | Additionally, for "throwaway" single-file formalizations, you can use [Rzk Online Playground](playground/index.html). 28 | 29 | ### Implementation 30 | 31 | Rzk serves also as a playground for some techniques of developing proof assistants in Haskell. 32 | In particular, it features a version of second-order abstract syntax for handling binders and, 33 | in the future, dependent type inference through higher-order unification[^3] [^4]. 34 | The idea is ultimately, to provide higher-order unification and/or dependent type inference "as a library", 35 | keeping the implementation of Rzk (at least its core language) small, maintainable, and safe. 36 | 37 | Another important part of Rzk is the tope layer solver[^5], 38 | which is a built-in intuitionistic theorem prover required for a part of the type theory. 39 | Although its implementation is fairly simple, 40 | it is sufficient to check existing proofs in synthetic ∞-categories 41 | without requiring any explicit proofs for the tope layer. 42 | 43 | Rzk and the tooling around it is developed by just a couple of people. 44 | See the list of contributors at [CONTRIBUTORS.md](CONTRIBUTORS.md). 45 | 46 | ### Discussing Rzk and getting help 47 | 48 | A Zulip chat is available for all to join and chat about Rzk, including formalization projects, development of Rzk, and related projects: 49 | 50 | [Join Rzk Zulip](https://rzk-lang.zulipchat.com/register/){ .md-button .md-button--primary } 51 | 52 | [^1]: 53 | Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories_. 54 | Higher Structures 1(1), 147-224. 2017. 55 | 56 | [^2]: 57 | Nikolai Kudasov, Emily Riehl, Jonathan Weinberger. 58 | _Formalizing the ∞-categorical Yoneda lemma_. 2023. 59 | 60 | [^3]: 61 | Nikolai Kudasov. _Functional Pearl: Dependent type inference via free higher-order unification_. 2022. 62 | 63 | 64 | [^4]: 65 | Nikolai Kudasov. _E-Unification for Second-Order Abstract Syntax_. In 8th International Conference on Formal Structures for Computation and Deduction (FSCD 2023). Leibniz International Proceedings in Informatics (LIPIcs), Volume 260, pp. 10:1-10:22, Schloss Dagstuhl - Leibniz-Zentrum für Informatik (2023) 66 | 67 | 68 | [^5]: 69 | Nikolai Kudasov. Experimental prover for Tope logic. SCAN 2023, pages 37–39. 2023. 70 | 71 | 72 | ## Other proof assistants for HoTT 73 | 74 | Rzk is not the first or the only proof assistant where it's possible to do (a variant of) homotopy type theory. 75 | See a [brief comparison of Rzk with other proof assistants](related.md). 76 | -------------------------------------------------------------------------------- /docs/docs/en/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redirecting 6 | 12 | 13 | 14 | Redirecting... 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/docs/en/reference/builtins/directed-interval.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/en/reference/builtins/directed-interval.rzk.md -------------------------------------------------------------------------------- /docs/docs/en/reference/builtins/unit.rzk.md: -------------------------------------------------------------------------------- 1 | # Unit type 2 | 3 | Since [:octicons-tag-24: v0.5.1][Unit support] 4 | 5 | ```rzk 6 | #lang rzk-1 7 | ``` 8 | 9 | In the syntax, only `Unit` (the type) and `unit` (the only inhabitant) are provided. Everything else should be available from computation rules. 10 | More specifically, `rzk` takes the uniqueness property of the `Unit` type (see Section 1.5 of the HoTT book[^1]) as the computation rule, meaning that any (well-typed) term of type `Unit` reduces to `unit`. 11 | This means in particular, that induction and uniqueness can be defined very easily: 12 | 13 | ```rzk 14 | #define ind-Unit 15 | (C : Unit -> U) 16 | (C-unit : C unit) 17 | (x : Unit) 18 | : C x 19 | := C-unit 20 | 21 | #define uniq-Unit 22 | (x : Unit) 23 | : x = unit 24 | := refl 25 | 26 | #define isProp-Unit 27 | (x y : Unit) 28 | : x = y 29 | := refl 30 | ``` 31 | 32 | As a non-trivial example, here is a proof that `Unit` is a Segal type: 33 | 34 | ```rzk 35 | #section isSegal-Unit 36 | 37 | #variable extext : ExtExt 38 | 39 | #define iscontr-Unit : isContr Unit 40 | := (unit, \_ -> refl) 41 | 42 | #define isContr-Δ²→Unit uses (extext) 43 | : isContr (Δ² -> Unit) 44 | := (\_ -> unit, \k -> eq-ext-htpy extext 45 | (2 * 2) Δ² (\_ -> BOT) 46 | (\_ -> Unit) (\_ -> recBOT) 47 | (\_ -> unit) k 48 | (\_ -> refl) 49 | ) 50 | 51 | #define isSegal-Unit uses (extext) 52 | : isSegal Unit 53 | := \x y z f g -> isRetract-ofContr-isContr 54 | (∑ (h : hom Unit x z), hom2 Unit x y z f g h) 55 | (Δ² -> Unit) 56 | (\(_, k) -> k, (\k -> (\t -> k (t, t), k), \_ -> refl)) 57 | isContr-Δ²→Unit 58 | 59 | #end isSegal-Unit 60 | ``` 61 | 62 | [Unit support]: https://github.com/rzk-lang/rzk/releases/tag/v0.5.1 63 | 64 | [^1]: The Univalent Foundations Program (2013). _Homotopy Type Theory: Univalent Foundations of Mathematics._ 65 | -------------------------------------------------------------------------------- /docs/docs/en/reference/commands/check.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/en/reference/commands/check.rzk.md -------------------------------------------------------------------------------- /docs/docs/en/reference/commands/compute.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/en/reference/commands/compute.rzk.md -------------------------------------------------------------------------------- /docs/docs/en/reference/commands/define-postulate.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/en/reference/commands/define-postulate.rzk.md -------------------------------------------------------------------------------- /docs/docs/en/reference/commands/options.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/en/reference/commands/options.rzk.md -------------------------------------------------------------------------------- /docs/docs/en/reference/cube-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Cube layer 2 | 3 | ```rzk 4 | #lang rzk-1 5 | ``` 6 | 7 | All cubes live in `#!rzk CUBE` universe. 8 | 9 | There are two built-in cubes: 10 | 11 | 1. `#!rzk 1` cube is a unit cube with a single point `#!rzk *_1` 12 | 2. `#!rzk 2` cube is a [directed interval](builtins/directed-interval.rzk.md) cube with points `#!rzk 0_2` and `#!rzk 1_2` 13 | 14 | It is also possible to have `#!rzk CUBE` variables and make products of cubes: 15 | 16 | 1. `#!rzk I * J` is a product of cubes `#!rzk I` and `#!rzk J` 17 | 2. `#!rzk (t, s)` is a point in `#!rzk I * J` if `#!rzk t : I` and `#!rzk s : J` 18 | 3. if `#!rzk ts : I * J`, then `#!rzk first ts : I` and `#!rzk second ts : J` 19 | 20 | You can usually use `#!rzk (t, s)` both as a pattern, and a construction of a pair of points: 21 | 22 | ```rzk 23 | -- Swap point components of a point in a cube I × I 24 | #define swap 25 | ( I : CUBE) 26 | : ( I × I) → I × I 27 | := \ ( t , s) → (s , t) 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/docs/en/reference/extension-types.rzk.md: -------------------------------------------------------------------------------- 1 | # Extension types 2 | 3 | 4 | 4. Extension types \(\left\langle \prod_{t : I \mid \psi} A \vert ^{\phi} _{a} \right\rangle\) are written as `#!rzk {t : I | psi t} -> A [ phi |-> a ]` 5 | - specifying `#!rzk [ phi |-> a ]` is optional, semantically defaults to `#!rzk [ BOT |-> recBOT ]` (like in RSTT); 6 | - specifying `#!rzk psi` in `#!rzk {t : I | psi}` is mandatory; 7 | - values of function types are \(\lambda\)-abstractions written in one of the following ways: 8 | - `#!rzk \t -> ` — this is usually fine; 9 | - `#!rzk \{t : I | psi} -> ` — this sometimes helps the typechecker; 10 | 11 | 5. Types of functions from a shape \(\prod_{t : I \mid \psi} A\) are a specialised variant of extension types and are written `#!rzk {t : I | psi} -> A` 12 | - specifying the name of the argument is mandatory; i.e. `#!rzk {I | psi} -> A` is invalid syntax! 13 | - values of function types are \(\lambda\)-abstractions written in one of the following ways: 14 | - `#!rzk \t -> ` — this is usually fine; 15 | - `#!rzk \{t : I | psi} -> ` — this sometimes helps the typechecker; 16 | 17 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 18 | -------------------------------------------------------------------------------- /docs/docs/en/reference/introduction.rzk.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | `rzk` is an experimental proof assistant for synthetic ∞-categories. 4 | `rzk-1` is an early version of the language supported by `rzk`. 5 | The language is based on Riehl and Shulman's «Type Theory for Synthetic ∞-categories»[^1]. In this section, we introduce syntax, discuss features and some of the current limitations of the proof assistant. 6 | 7 | Overall, a program in `rzk-1` consists of a language pragma (specifying that we use `rzk-1` and not one of the other languages[^2]) followed by a sequence of commands. For now, we will only use `#define` command. 8 | 9 | Here is a small formalisation in an MLTT subset of `rzk-1`: 10 | 11 | ```rzk 12 | #lang rzk-1 13 | 14 | -- Flipping the arguments of a function. 15 | #define flip 16 | (A B : U) -- For any types A and B 17 | (C : (x : A) -> (y : B) -> U) -- and a type family C 18 | (f : (x : A) -> (y : B) -> C x y) -- given a function f : A -> B -> C 19 | : (y : B) -> (x : A) -> C x y -- we construct a function of type B -> A -> C 20 | := \y x -> f x y -- by swapping the arguments 21 | 22 | -- Flipping a function twice is the same as not doing anything 23 | #define flip-flip-is-id 24 | (A B : U) -- For any types A and B 25 | (C : (x : A) -> (y : B) -> U) -- and a type family C 26 | (f : (x : A) -> (y : B) -> C x y) -- given a function f : A -> B -> C 27 | : f = flip B A (\y x -> C x y) 28 | (flip A B C f) -- flipping f twice is the same as f 29 | := refl -- proof by reflexivity 30 | ``` 31 | 32 | Let us explain parts of this code: 33 | 34 | 1. `#!rzk #lang rzk-1` specifies that we are in using `#!rzk rzk-1` language; 35 | 2. `#!rzk --` starts a comment line (until the end of the line); 36 | 3. `#!rzk #define «name» : «type» := «term»` defines a name `«name»` to be equal to `«term»`; the proof assistant will typecheck `«term»` against type `«type»`; 37 | 4. We define two terms here — `flip` and `flip-flip-is-id`; 38 | 5. `flip` is a function that takes 4 arguments and returns a function of two arguments. 39 | 6. `flip-flip-is-id` is a function that takes two types, a type family, and a function `f` and returns a value of an identity type `flip ... (flip ... f) = f`, indicating that flipping a function `f` twice gets us back to `f`. 40 | 41 | Similarly to the three layers in Riehl and Shulman's type theory, `rzk-1` has 3 universes: 42 | 43 | - `CUBE` is the universe of cubes, corresponding to the cube layer; 44 | - `TOPE` is the universe of topes, corresponding to the tope layer; 45 | - `U` is the universe of types, corresponding to the types and terms layer. 46 | 47 | These are explained in the following sections. 48 | 49 | ## Soundness 50 | 51 | `rzk-1` assumes "type-in-type", that is `U` has type `U`. 52 | This is known to make the type system unsound (due to Russell and Curry-style paradoxes), however, 53 | it is sometimes considered acceptable in proof assistants. 54 | And, since it simplifies implementation, `rzk-1` embraces this assumption, at least for now. 55 | 56 | Moreover, `rzk-1` does not prevent cubes or topes to depend on types and terms. For example, the following definition typechecks: 57 | 58 | ```rzk 59 | #define weird 60 | (A : U) 61 | (I : A -> CUBE) 62 | (x y : A) 63 | : CUBE 64 | := I x * I y 65 | ``` 66 | 67 | This likely leads to another inconsistency, but it will probably not lead to bugs in actual proofs of interest, 68 | so current version embraces this lax treatment of universes. 69 | 70 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 71 | 72 | [^2]: In version [:octicons-tag-24: v0.1.0](https://github.com/rzk-lang/rzk/releases/tag/v0.1.0), `rzk` has supported simply typed lambda calculus, PCF, and MLTT. However, those languages have been removed. 73 | -------------------------------------------------------------------------------- /docs/docs/en/reference/render.rzk.md: -------------------------------------------------------------------------------- 1 | # Rendering Diagrams 2 | 3 | Starting from version `0.3.0`, `rzk` supports rendering of topes, types, and terms as diagrams. 4 | 5 | This is a literate `rzk` file: 6 | 7 | ```rzk 8 | #lang rzk-1 9 | ``` 10 | 11 | To enable rendering, enable option `"render" = "svg"` (to disable, `"render" = "none"`): 12 | 13 | ```rzk 14 | #set-option "render" = "svg" -- enable rendering in SVG 15 | ``` 16 | 17 | Rendering is completely automatic, and works in the following situations: 18 | 19 | 1. Mapping from a shape (including curried mappings), up to 3 dimensions, only in products of `2` cubes; 20 | 2. Type of mapping from a shape (including curried mappings), up to 3 dimensions, only in products of `2` cubes. 21 | 3. Mappings from a shape that is a section of an existing shape. 22 | 23 | The rendering assigns the following colors: 24 | 25 | - purple is assigned for parameters (context) variables; 26 | - blue is used for fillings for types (e.g. for `hom` and `hom2`); 27 | - red is used for terms (e.g. `Segal-comp-witness`); 28 | - orange is used for shapes in the tope layer; 29 | - grey is used for discarded parts of a (larger) mapping (e.g. when extracting a diagonal/face from a larger shape). 30 | 31 | The SVG pictures can be inserted directly into `.md` files before a corresponding `rzk` code block. At the bottom of a markdown file, you might want to add stylization, e.g.: 32 | 33 | ```html 34 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 56 | 57 | ``` 58 | 59 | ## Examples 60 | 61 | ### Visualising Simplicial Topes 62 | 63 | Topes are visualised with **orange** color: 64 | 65 | ```rzk 66 | -- 2-simplex 67 | #define Δ² : (2 * 2) -> TOPE 68 | := \(t, s) -> s <= t 69 | ``` 70 |

71 | Boundary of a tope: 72 | 73 | ```rzk 74 | -- boundary of a 2-simplex 75 | #define ∂Δ² : Δ² -> TOPE 76 | := \(t, s) -> s === 0_2 \/ t === 1_2 \/ s === t 77 | ``` 78 | 79 | The busiest tope diagram involves the entire 3D cube: 80 |

81 | 82 | ```rzk 83 | -- 3-dim cube 84 | #define 2³ : (2 * 2 * 2) -> TOPE 85 | := \_ -> TOP 86 | ``` 87 |


88 | 89 | ```rzk 90 | -- 3-simplex 91 | #define Δ³ : (2 * 2 * 2) -> TOPE 92 | := \((t1, t2), t3) -> t3 <= t2 /\ t2 <= t1 93 | ``` 94 | 95 |

96 | ### Visualising Simplicial Types 97 | 98 | Types are visualised with **blue** color. Recognised parameter part (e.g. fixed endpoints, edges, faces with clear labels) are visualised with **purple** color. When a type is constructed by taking a part of another shape, the rest of the larger shape is colored using **gray** color. 99 | 100 | ```rzk 101 | -- [RS17, Definition 5.1] 102 | -- The type of arrows in A from x to y. 103 | #define hom 104 | (A : U) -- A type. 105 | (x y : A) -- Two points in A. 106 | : U -- (hom A x y) is a 1-simplex (an arrow) 107 | := (t : 2) -> A [ -- in A where 108 | t === 0_2 |-> x, -- * the left endpoint is exactly x 109 | t === 1_2 |-> y -- * the right endpoint is exactly y 110 | ] 111 | ``` 112 | 113 | ```rzk 114 | -- [RS17, Definition 5.2] 115 | -- the type of commutative triangles in A 116 | #define hom2 117 | (A : U) -- A type. 118 | (x y z : A) -- Three points in A. 119 | (f : hom A x y) -- An arrow in A from x to y. 120 | (g : hom A y z) -- An arrow in A from y to z. 121 | (h : hom A x z) -- An arrow in A from x to z. 122 | : U -- (hom2 A x y z f g h) is a 2-simplex (triangle) 123 | := { (t1, t2) : Δ² } -> A [ -- in A where 124 | t2 === 0_2 |-> f t1, -- * the top edge is exactly f, 125 | t1 === 1_2 |-> g t2, -- * the right edge is exactly g, and 126 | t2 === t1 |-> h t2 -- * the diagonal is exactly h 127 | ] 128 | ``` 129 | 130 | ### Visualising Terms of Simplicial Types 131 | 132 | Terms (with non-trivial labels) are visualised with **red** color (you can see a detailed label on hover). Recognised parameter part (e.g. fixed endpoints, edges, faces with clear labels) are visualised with **purple** color. When a term is constructed by taking a part of another shape, the rest of the larger shape is colored using **gray** color. 133 | 134 | We can visualise terms that fill a shape: 135 | 136 | ```rzk 137 | #define square 138 | (A : U) 139 | (x y z : A) 140 | (f : hom A x y) 141 | (g : hom A y z) 142 | (h : hom A x z) 143 | (a : Sigma (h' : hom A x z), hom2 A x y z f g h') 144 | : (2 * 2) -> A 145 | := \(t, s) -> recOR( s <= t |-> second a (t, s) , t <= s |-> second a (s, t)) 146 | ``` 147 | 148 | If a term is extracted as a part of a larger shape, generally, the whole shape will be shown (in gray): 149 | 150 | ```rzk 151 | #define face 152 | (A : U) 153 | (x y z : A) 154 | (f : hom A x y) 155 | (a : Sigma (g : hom A y z), {((t1, t2), t3) : 2 * 2 * 2 | t3 <= t1 \/ t2 <= t1} -> A [ t1 === 0_2 |-> f t2, t1 === 1_2 |-> g t3 ]) 156 | : Δ² -> A 157 | := \(t, s) -> second a ((t, t), s) 158 | ``` 159 | 160 | 161 | 165 | 166 | 167 | 168 | 169 | 170 | 172 | 173 | 174 | 175 | 183 | 184 | -------------------------------------------------------------------------------- /docs/docs/en/reference/sections.rzk.md: -------------------------------------------------------------------------------- 1 | # Sections and Variables 2 | 3 | Sections and variables allow to simplify definitions by factoring out common assumptions. 4 | 5 | !!! info "Coq-style variables" 6 | `rzk` implements variables similarly to 7 | `Variable` command in Coq. 8 | An important difference is that `rzk` does not allow definitions to use variables implicitly and adds `uses (...)` annotations to ensure such dependencies are not accidental. 9 | This is, perhaps, somewhat related to this error message in Coq. 10 | 11 | This is a literate `rzk` file: 12 | 13 | ```rzk 14 | #lang rzk-1 15 | ``` 16 | 17 | ## Variables 18 | 19 | Consider the following definitions: 20 | 21 | ```rzk 22 | #define compose₁ 23 | (A B C : U) 24 | (g : B -> C) 25 | (f : A -> B) 26 | : A -> C 27 | := \x -> g (f x) 28 | 29 | #define twice₁ 30 | (A : U) 31 | (h : A -> A) 32 | : A -> A 33 | := \x -> h (h x) 34 | ``` 35 | 36 | Since it might be common to introduce types `A`, `B`, and `C`, we can declare these are variables: 37 | 38 | ```rzk 39 | #variables A B C : U 40 | 41 | #define compose₂ 42 | (g : B -> C) 43 | (f : A -> B) 44 | : A -> C 45 | := \x -> g (f x) 46 | 47 | #define twice₂ 48 | (h : A -> A) 49 | : A -> A 50 | := \x -> h (h x) 51 | ``` 52 | 53 | The `#variables` command here introduces assumptions, which can be used in the following definitions. Importantly, after checking a file (module), all definitions will have the assumptions used (explicitly or implicitly) attached as bound variables. 54 | 55 | ### Implicitly used variables (and `uses`) 56 | 57 | We can try going even further and declare variables `f`, `g`, `h`, and `x`: 58 | 59 | ```rzk 60 | #variable g : B -> C 61 | #variable f : A -> B 62 | #variable h : A -> A 63 | #variable x : A 64 | 65 | -- #define bad-compose₃ : C := g (f x) -- ERROR: implicit assumptions A and B 66 | #define twice₃ : A := h (h x) 67 | ``` 68 | 69 | Note how this definition of `bad-compose₃` is implicitly dependent on the types `A` and `B`, which is promptly noted by `rzk`, which issues an error (if we uncomment the corresponding line): 70 | 71 | ```text 72 | implicit assumption 73 | B : U 74 | used in definition of 75 | bad-compose₃ 76 | ``` 77 | 78 | To let `rzk` know that this is not accidental, we can add `uses (...)` annotation to specify a list of variables implicitly used in the definition: 79 | 80 | ```rzk 81 | #define compose₃ uses (A B) : C := g (f x) 82 | ``` 83 | 84 | ## Sections 85 | 86 | To introduce assumption variables temporarily inside of one file, you can use sections: 87 | 88 | ```rzk 89 | #section example-1 90 | 91 | #variables X Y Z : U 92 | #variable k : X -> X 93 | #variable x' : X 94 | 95 | #define compose₄ 96 | (g : Y -> Z) 97 | (f : X -> Y) 98 | : X -> Z 99 | := \x -> g (f x) 100 | 101 | #define twice₄ : X := k (k x') 102 | 103 | #end example-1 104 | ``` 105 | 106 | Now, once outside of the section, `compose₄` and `twice₄` obtain corresponding parameters 107 | (only those used, explicitly or implicitly): 108 | 109 | ```rzk 110 | -- compose₄ : (X : U) -> (Y : U) -> (Z : U) -> (g : Y -> Z) -> (f : X -> Y) -> (X -> Z) 111 | -- twice₄ : (X : U) -> (k : X -> X) -> (x' : X) -> X 112 | 113 | #define twice₅ 114 | (T : U) 115 | (e : T -> T) 116 | : T -> T 117 | := compose₄ T T T e e 118 | 119 | #define identity 120 | (T : U) 121 | : T -> T 122 | := twice₄ T (\t -> t) 123 | ``` 124 | 125 | !!! warning "Lack of indentation" 126 | `rzk` currently does not support indentation, so all definitions and commands inside a section (including nested sections) have to start at the beginning of a line. 127 | -------------------------------------------------------------------------------- /docs/docs/en/reference/tope-disjunction-elimination.rzk.md: -------------------------------------------------------------------------------- 1 | # Tope disjuction elimination 2 | 3 | Following Riehl and Shulman's type theory[^1], `#!rzk rzk-1` introduces two primitive terms for disjunction elimination: 4 | 5 | 1. `#!rzk recBOT` corresponds to \(\mathsf{rec}_\bot\), has any type, and is valid whenever tope context is included in `#!rzk BOT`; 6 | 7 | 2. `#!rzk recOR(«tope_1» |-> «term_1», ..., «tope_n» |-> «term_n»)` defines a term for a disjunction of topes `#!rzk «tope_1» \/ ... \/ «tope_n»`. This is well-typed when for an intersection of any two topes `#!rzk «tope_i» /\ «tope_j»` the corresponding terms `#!rzk «term_i»` and `#!rzk «term_j»` are judgementally equal. In particular, `#!rzk recOR(psi |-> a_psi, phi |-> a_phi)` corresponds to \(\mathsf{rec}_\lor^{\psi, \phi}(a_\psi, a_\phi)\). 8 | 9 | !!! warning "Deprecated syntax" 10 | `#!rzk recOR(psi, phi, a_psi, a_phi)` corresponds to \(\mathsf{rec}_\lor^{\psi, \phi}(a_\psi, a_\phi)\), is well-typed when `#!rzk a_psi` is definitionally equal to `#!rzk a_phi` under `#!rzk psi /\ phi`. However, this syntax is deprecated since it is easy to confuse which tope relates to which term. 11 | 12 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 13 | 14 | -------------------------------------------------------------------------------- /docs/docs/en/reference/tope-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Tope layer 2 | 3 | All topes live in `#!rzk TOPE` universe. 4 | 5 | Here are all the ways to build a tope: 6 | 7 | 1. Introduce a variable, e.g. `#!rzk (psi : TOPE) -> ...`; 8 | 9 | - Usually, topes depend on point variables from some cube(s). To indicate that, we usually introduce topes as "functions" from some cube to `#!rzk TOPE`. For example, `#!rzk (psi : I -> TOPE) -> ...`. 10 | 11 | 2. Use a constant: 12 | 13 | - top tope \(\top\) is written `#!rzk TOP` 14 | - bottom tope \(\bot\) is written `#!rzk BOT` 15 | 16 | 3. Usa a tope connective: 17 | - tope conjunction \(\psi \land \phi\) is written `#!rzk psi /\ phi` 18 | - tope disjunction \(\psi \lor \phi\) is written `#!rzk psi \/ phi` 19 | - equality tope \(t \equiv s\) is written `#!rzk t === s`, whenever `#!rzk t` and `#!rzk s` are points of the same cube 20 | - inequality tope \(t \leq s\) is written `#!rzk t <= s` whenever `#!rzk t : 2` and `#!rzk s : 2` 21 | 22 | -------------------------------------------------------------------------------- /docs/docs/en/reference/type-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Types and terms 2 | 3 | ```rzk 4 | #lang rzk-1 5 | ``` 6 | 7 | ## Functions (dependent products) 8 | 9 | Function (dependent product) types \(\prod_{x : A} B\) are written `#!rzk (x : A) -> B x`. Values of function types are \(\lambda\)-abstractions written in one of the following ways: 10 | 11 | - `#!rzk \x -> ` — this is usually fine; 12 | - `#!rzk \(x : A) -> ` — this sometimes helps the typechecker. 13 | 14 | ## Dependent sums 15 | 16 | Dependent sum type \(\sum_{x : A} B\) is written `#!rzk ∑ (x : A), B` or `#!rzk Sigma (x : A), B`. Values of dependent sum types are pairs written as `#!rzk (x, y)`. 17 | 18 | To access components of a dependent pair `#!rzk p`, use `#!rzk first p` and `#!rzk second p`. 19 | 20 | !!! warning 21 | `#!rzk first` and `#!rzk second` are not valid syntax without an argument! 22 | 23 | ## Identity types 24 | 25 | Identity (path) type \(x =_A y\) is written `#!rzk x =_{A} y`. 26 | 27 | !!! tip 28 | Specifying the type `#!rzk A` is optional: `#!rzk x = y` is valid syntax! 29 | 30 | Any identity type has value `#!rzk refl_{x : A}` whose type is `#!rzk x =_{A} x` whenever `#!rzk x : A` 31 | 32 | !!! tip 33 | Specifying term and type of `#!rzk refl_{x : A}` is optional: `#!rzk refl_{x}` and `#!rzk refl` are both valid syntax. 34 | 35 | Path induction is done using \(\mathcal{J}\) path eliminator: 36 | 37 | - for 38 | - any type \(A\) and \(a : A\), 39 | - type family \(C : \prod_{x : A} ((a =_A x) \to \mathcal{U})\) and 40 | - \(d : C(a,\mathsf{refl}_a)\) and 41 | - \(x : A\) and \(p : a =_A x\) 42 | - we have \(\mathcal{J}(A, a, C, d, x, p) : C(x, p)\) 43 | 44 | In `#!rzk rzk-1` we write `#!rzk idJ(A, a, C, d, x, p)` 45 | 46 | !!! warning 47 | `#!rzk idJ` is not valid syntax without exactly 6-tuple provided as an argument! 48 | 49 | -------------------------------------------------------------------------------- /docs/docs/en/rzk.yaml: -------------------------------------------------------------------------------- 1 | include: 2 | - getting-started/dependent-types.rzk.md 3 | - examples/recId.rzk.md 4 | -------------------------------------------------------------------------------- /docs/docs/en/tools.md: -------------------------------------------------------------------------------- 1 | # Tools 2 | 3 | Rzk proof assistant comes with built-in language server and formatter. 4 | 5 | Other tools help enhance user experience or automate things. 6 | 7 | ### VS Code extension for Rzk 8 | 9 | See [rzk-lang/vscode-rzk](https://github.com/rzk-lang/vscode-rzk). 10 | VS Code extension offers a lot of conveniences and using VS Code is recommended for newcomers, 11 | as it is considered the primary use case and has most support from the developers. 12 | 13 | ### MkDocs plugin for Rzk 14 | 15 | See [rzk-lang/mkdocs-plugin-rzk](https://github.com/rzk-lang/mkdocs-plugin-rzk). 16 | MkDocs plugin enhances documentation build from literate Rzk Markdown files: 17 | - adds diagram rendering (experimental) 18 | - adds definition anchors (helpful to have "permalinks" to definitions) 19 | 20 | ### GitHub Action for Rzk 21 | 22 | See [rzk-lang/rzk-action](https://github.com/rzk-lang/rzk-action). 23 | This action allows to check your Rzk formalizations on GitHub automatically. 24 | It can also be used to check formatting (experimental). 25 | 26 | ### Syntax highlighting (Pygments) for Rzk 27 | 28 | See [rzk-lang/pygments-rzk](https://github.com/rzk-lang/pygments-rzk). 29 | This is a simple syntax highlighter for Pygments (used by MkDocs and `minted` package in LaTeX). 30 | Note that VS Code extension is using the Rzk Language Server for more accurate "semantic highlighting". 31 | -------------------------------------------------------------------------------- /docs/docs/ru/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | --8<-- "rzk/ChangeLog.md" 2 | -------------------------------------------------------------------------------- /docs/docs/ru/CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | --8<-- "CONTRIBUTORS.md" 2 | -------------------------------------------------------------------------------- /docs/docs/ru/blog/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redirecting 6 | 9 | 12 | 13 | 14 | Redirecting to Blog/... 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/docs/ru/community.md: -------------------------------------------------------------------------------- 1 | # Сообщество Rzk 2 | 3 | Вокруг Rzk собралось небольшое сообщество математиков и информатиков. 4 | 5 | ## Чат 6 | 7 | Для всех желающих доступен (преимущественно англоязычный) чат Zulip, 8 | в котором можно обсудить формализации, разработку Rzk и смежные проекты: 9 | 10 | [Присоединиться к сообществу Rzk в Zulip](https://rzk-lang.zulipchat.com/register/){ .md-button .md-button--primary } 11 | -------------------------------------------------------------------------------- /docs/docs/ru/getting-started/index.md: -------------------------------------------------------------------------------- 1 | # Первые шаги с Rzk 2 | 3 | 1. [Установите Rzk](install.md). 4 | 2. Получите [краткий экскурс](quickstart.rzk.md) по языку Rzk. 5 | 3. Просмотрите [введение в зависимые типы](dependent-types.rzk.md) в Rzk. 6 | 4. Научитесь настраивать [проекты формализации в Rzk](project.md). 7 | 5. Узнайте больше о возможностях Rzk в [Руководстве](../reference/index.md). 8 | -------------------------------------------------------------------------------- /docs/docs/ru/getting-started/install.md: -------------------------------------------------------------------------------- 1 | # Установка Rzk 2 | 3 | ## Через расширение VS Code (рекомендуется) 4 | 5 | Следуйте этим инструкциям, чтобы настроить работу с Rzk в редакторе VS Code. 6 | 7 | 1. Установите [VS Code](https://code.visualstudio.com/). 8 | 2. Запустите VS Code и установите [расширение `rzk`](https://marketplace.visualstudio.com/items?itemName=NikolaiKudasovfizruk.rzk-1-experimental-highlighting). 9 | 3. Создайте новый файл через "Файл > Создать текстовый файл" (Ctrl+N). Нажмите `Select a language`, введите в поиске `rzk` и выберите "Literate Rzk Markdown". 10 | ![VS Code rzk language selector.](../assets/images/vscode-rzk-select-language.png) 11 | 4. Вы должны увидеть следующее сообщение: 12 | ![VS Code rzk install prompt.](../assets/images/vscode-rzk-install-prompt.png) 13 | 5. Нажмите "Yes". 14 | 6. Пока Rzk устанавливается, скопируйте и вставьте следующий текст в открытый файл: 15 | 16 | ````markdown 17 | # Пример литературного кода с Rzk 18 | 19 | ```rzk 20 | #lang rzk-1 21 | 22 | -- тождественная функция 23 | #define id (A : U) 24 | : A -> A 25 | := \ x -> x 26 | ``` 27 | ```` 28 | 29 | 7. Когда установка завершится, вы должны увидеть следующее сообщение: 30 | ![VS Code rzk reload prompt.](../assets/images/vscode-rzk-install-success-reload-prompt.png) 31 | 8. Нажмите "Reload" (перезагрузить VS Code). 32 | 9. Сохраните ваш файл (например, как `example.rzk.md`). 33 | 10. Откройте терминал внутри VS Code (Ctrl+`). 34 | 35 | 36 | 37 | 11. В терминале запустите команду 38 | 39 | ```sh 40 | rzk typecheck example.rzk.md 41 | ``` 42 | 43 | 12. Вы должны увидеть что-то такое: 44 | 45 | ```text 46 | Loading file example.rzk.md 47 | Checking module from example.rzk.md 48 | [ 1 out of 1 ] Checking #define id 49 | Everything is ok! 50 | ``` 51 | 52 | 13. Поздравляем! Теперь ваш VS Code настроен на работу с Rzk :) Заметьте, что расширение будет уведомлять вас о наличии обновлений Rzk и предлагать обновить автоматически. 53 | 54 | 14. Можете перейти к [Быстрому началу](quickstart.rzk.md) чтобы познакомиться с языком Rzk! 55 | 56 | ## Установка исполняемых файлов 57 | 58 | ### Через страницу релизов на GitHub 59 | 60 | Вы можете скачать исполняемые файлы (для Linux, Windows, и macOS) напрямую со страницы релизов на GitHub: . 61 | Если ваша платформа не поддержана, вы можете попробовать установить Rzk из исходников (см. ниже) 62 | или оставить пожелание о расширении поддержки на странице задач: . 63 | 64 | ## Сборка и установка из исходников 65 | 66 | Вы можете установить Rzk из исходников: вы можете либо скачать стабильную версию из репозитория пакетов Hackage, либо собрать самую свежую версию из ветки `develop` на GitHub. 67 | 68 | ### Stack 69 | 70 | Чтобы собрать и установить Rzk при помощи Stack, из репозитория Hackage: 71 | 72 | ```sh 73 | stack install rzk 74 | ``` 75 | 76 | Чтобы собрать и установить Rzk при помощи Stack, из исходников на GitHub: 77 | 78 | ```sh 79 | git clone https://github.com/rzk-lang/rzk.git 80 | cd rzk 81 | git checkout develop 82 | stack build && stack install 83 | ``` 84 | 85 | ### cabal-install 86 | 87 | Чтобы собрать и установить Rzk при помощи `cabal-install`, из репозитория Hackage: 88 | 89 | ```sh 90 | cabal v2-update 91 | cabal v2-install rzk 92 | ``` 93 | 94 | Чтобы собрать и установить Rzk при помощи `cabal-install`, из исходников на GitHub: 95 | 96 | ```sh 97 | git clone https://github.com/rzk-lang/rzk.git 98 | cd rzk 99 | git checkout develop 100 | cabal v2-build && cabal v2-install 101 | ``` 102 | 103 | ### Nix 104 | 105 | !!! warning "Раздел в работе." 106 | 107 | Раздел нуждается в доработке. 108 | -------------------------------------------------------------------------------- /docs/docs/ru/getting-started/project.md: -------------------------------------------------------------------------------- 1 | # Настройка проекта 2 | 3 | !!! warning "Раздел в работе" 4 | Скоро здесь будет описание работы с проектами формализации. 5 | До тех пор вы можете воспользоваться шаблонным проектом: . 6 | Также см. для примера реального проекта. 7 | -------------------------------------------------------------------------------- /docs/docs/ru/getting-started/quickstart.rzk.md: -------------------------------------------------------------------------------- 1 | # Быстрое начало 2 | 3 | !!! warning "Раздел в работе" 4 | Этот раздел нуждается в доработке. 5 | 6 | Для начала, [установите Rzk](install.md). 7 | 8 | Этот раздел является литературным файлом Rzk: 9 | 10 | ```rzk 11 | #lang rzk-1 12 | ``` 13 | -------------------------------------------------------------------------------- /docs/docs/ru/index.md: -------------------------------------------------------------------------------- 1 | # Решатель теорем Rzk 2 | 3 | Rzk — это экспериментальный интерактивный решатель теорем, 4 | основанный на [«Теории типов для синтетических ∞-категорий](https://arxiv.org/abs/1705.07442)[^1]. 5 | 6 | [Первые шаги с Rzk](getting-started/install.md){ .md-button .md-button--primary } 7 | [Попробовать Rzk в онлайн-песочнице](playground/index.html){ .md-button } 8 | 9 | ## Об этом проекте 10 | 11 | Проект начался с идеи воплотить "в жизнь" статью Эмили Рил и Майкла Шульмана 2017 года[^1], 12 | реализуя решатель для их теории типов с формами (type theory with shapes). 13 | На момент написания этого текста, Rzk поддерживает формальный язык, близкий к теории типов в упомянутой статье, 14 | а также вокруг решателя существует некая инструментальная поддержка 15 | (например, расширение для VS Code и языковой сервер с поддержкой подсветки синтаксиса и автоформатирования). 16 | 17 | ### Формализация теории ∞-категорий 18 | 19 | Большая часть статьи Рил и Шульмана (вплоть до леммы Йонеды для ∞-категорий) уже формализована на Rzk (см. [Yoneda for ∞-categories](https://emilyriehl.github.io/yoneda/)[^2]). 20 | Оставшие результаты, а также результаты из других работ находятся в процессе формализации (см. проект по формализации симплициальной гомопотической теории типов, [sHoTT](https://rzk-lang.github.io/sHoTT/)). 21 | Также некоторые усилия направлены на формализацию "книжной"[^6] [^7] гомотопической теории типов (см. [hottbook](https://rzk-lang.github.io/hottbook/)). 22 | 23 | ### Работа с Rzk 24 | 25 | Рекомендуемый способ работы с Rzk — через среду разработки VS Code (см. [Первые шаги](getting-started/install.md)). 26 | Тем не менее, вы также можете скачать исполняемые файлы на [странице релизов на GitHub](https://github.com/rzk-lang/rzk/releases), 27 | собрать самостоятельно [из исходников](getting-started/install.md#install-from-sources), 28 | а также попытаться интегрировать языковой сервер Rzk с вашим любимым текстовым редактором. 29 | Для небольших формализаций, умещающихся в один файл, можно также воспользоваться [онлайн-песочницей Rzk](playground/index.html). 30 | 31 | ### Реализация 32 | 33 | Помимо своей основной цели, Rzk также служит полем экспериментов для методов реализации решателей теорем (на языке Haskell). 34 | В частности, в реализации используется вариант абстрактного синтаксиса второго порядка 35 | для комфортной работы со связанными переменными и, в будущем, для вывода (зависимых) типов 36 | через унификацию высшего порядка[^3] [^4]. 37 | В конечном итоге, хочется получить приемлемое общее (библиотечное) решение для унификации высшего порядка и вывода типов, 38 | оставив реализацию Rzk (по крайней мере, его ядра) небольшим, простым для поддержки, и надёжным. 39 | 40 | Ещё одна интересная деталь реализации Rzk — это автоматический решатель для слоя форм (tope layer)[^5]. 41 | Это встроенный полностью автоматический решатель для варианта интуиционистской логики, 42 | необходимый для проверки типов. 43 | Хотя текущая реализация решателя относительно проста, 44 | её хватает на практике для проверки доказательств о синтетических ∞-категориях 45 | без нужды в дополнительном коде от формализующего математика. 46 | 47 | Rzk и сопутствующие инструменты разработаны всего парой человек. 48 | Вы можете ознакомится с участниками проекта в файле [CONTRIBUTORS.md](CONTRIBUTORS.md). 49 | 50 | ### Обсуждения вокруг Rzk 51 | 52 | Для всех желающих доступен (преимущественно англоязычный) чат Zulip, 53 | в котором можно обсудить формализации, разработку Rzk и смежные проекты: 54 | 55 | [Присоединиться к сообществу Rzk в Zulip](https://rzk-lang.zulipchat.com/register/){ .md-button .md-button--primary } 56 | 57 | [^1]: 58 | Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories_. 59 | Higher Structures 1(1), 147-224. 2017. 60 | 61 | [^2]: 62 | Nikolai Kudasov, Emily Riehl, Jonathan Weinberger. 63 | _Formalizing the ∞-categorical Yoneda lemma_. 2023. 64 | 65 | [^3]: 66 | Nikolai Kudasov. _Functional Pearl: Dependent type inference via free higher-order unification_. 2022. 67 | 68 | 69 | [^4]: 70 | Nikolai Kudasov. _E-Unification for Second-Order Abstract Syntax_. In 8th International Conference on Formal Structures for Computation and Deduction (FSCD 2023). Leibniz International Proceedings in Informatics (LIPIcs), Volume 260, pp. 10:1-10:22, Schloss Dagstuhl - Leibniz-Zentrum für Informatik (2023) 71 | 72 | 73 | [^5]: 74 | Nikolai Kudasov. Experimental prover for Tope logic. SCAN 2023, pages 37–39. 2023. 75 | 76 | 77 | [^6]: 78 | The Univalent Foundations Program. _Homotopy Type Theory: Univalent Foundations of Mathematics_. 79 | Institute for Advanced Study. 2013. 80 | 81 | [^7]: 82 | Международный коллектив авторов. _Гомотопическая теория типов: унивалентные основания математики_. 83 | ИНСТИТУТ ПЕРСПЕКТИВНЫХ ИССЛЕДОВАНИЙ. Перевод и редактирование: ГЕННАДИЙ ЧЕРНЫШЕВ. 84 | 85 | 86 | ## Другие решатели для гомотопической теории типов 87 | 88 | Rzk — не первый и не единственный решатель для (варианта) гомотопической теории типов. 89 | См. [краткое сравнение Rzk с другими решателями](related.md). 90 | -------------------------------------------------------------------------------- /docs/docs/ru/playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Redirecting 6 | 12 | 13 | 14 | Redirecting... 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/builtins/directed-interval.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/ru/reference/builtins/directed-interval.rzk.md -------------------------------------------------------------------------------- /docs/docs/ru/reference/builtins/unit.rzk.md: -------------------------------------------------------------------------------- 1 | # Unit type 2 | 3 | Since [:octicons-tag-24: v0.5.1][Unit support] 4 | 5 | ```rzk 6 | #lang rzk-1 7 | ``` 8 | 9 | In the syntax, only `Unit` (the type) and `unit` (the only inhabitant) are provided. Everything else should be available from computation rules. 10 | More specifically, `rzk` takes the uniqueness property of the `Unit` type (see Section 1.5 of the HoTT book[^1]) as the computation rule, meaning that any (well-typed) term of type `Unit` reduces to `unit`. 11 | This means in particular, that induction and uniqueness can be defined very easily: 12 | 13 | ```rzk 14 | #define ind-Unit 15 | (C : Unit -> U) 16 | (C-unit : C unit) 17 | (x : Unit) 18 | : C x 19 | := C-unit 20 | 21 | #define uniq-Unit 22 | (x : Unit) 23 | : x = unit 24 | := refl 25 | 26 | #define isProp-Unit 27 | (x y : Unit) 28 | : x = y 29 | := refl 30 | ``` 31 | 32 | As a non-trivial example, here is a proof that `Unit` is a Segal type: 33 | 34 | ```rzk 35 | #section isSegal-Unit 36 | 37 | #variable extext : ExtExt 38 | 39 | #define iscontr-Unit : isContr Unit 40 | := (unit, \_ -> refl) 41 | 42 | #define isContr-Δ²→Unit uses (extext) 43 | : isContr (Δ² -> Unit) 44 | := (\_ -> unit, \k -> eq-ext-htpy extext 45 | (2 * 2) Δ² (\_ -> BOT) 46 | (\_ -> Unit) (\_ -> recBOT) 47 | (\_ -> unit) k 48 | (\_ -> refl) 49 | ) 50 | 51 | #define isSegal-Unit uses (extext) 52 | : isSegal Unit 53 | := \x y z f g -> isRetract-ofContr-isContr 54 | (∑ (h : hom Unit x z), hom2 Unit x y z f g h) 55 | (Δ² -> Unit) 56 | (\(_, k) -> k, (\k -> (\t -> k (t, t), k), \_ -> refl)) 57 | isContr-Δ²→Unit 58 | 59 | #end isSegal-Unit 60 | ``` 61 | 62 | [Unit support]: https://github.com/rzk-lang/rzk/releases/tag/v0.5.1 63 | 64 | [^1]: The Univalent Foundations Program (2013). _Homotopy Type Theory: Univalent Foundations of Mathematics._ 65 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/commands/check.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/ru/reference/commands/check.rzk.md -------------------------------------------------------------------------------- /docs/docs/ru/reference/commands/compute.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/ru/reference/commands/compute.rzk.md -------------------------------------------------------------------------------- /docs/docs/ru/reference/commands/define-postulate.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/ru/reference/commands/define-postulate.rzk.md -------------------------------------------------------------------------------- /docs/docs/ru/reference/commands/options.rzk.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/docs/ru/reference/commands/options.rzk.md -------------------------------------------------------------------------------- /docs/docs/ru/reference/cube-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Cube layer 2 | 3 | ```rzk 4 | #lang rzk-1 5 | ``` 6 | 7 | All cubes live in `#!rzk CUBE` universe. 8 | 9 | There are two built-in cubes: 10 | 11 | 1. `#!rzk 1` cube is a unit cube with a single point `#!rzk *_1` 12 | 2. `#!rzk 2` cube is a [directed interval](builtins/directed-interval.rzk.md) cube with points `#!rzk 0_2` and `#!rzk 1_2` 13 | 14 | It is also possible to have `#!rzk CUBE` variables and make products of cubes: 15 | 16 | 1. `#!rzk I * J` is a product of cubes `#!rzk I` and `#!rzk J` 17 | 2. `#!rzk (t, s)` is a point in `#!rzk I * J` if `#!rzk t : I` and `#!rzk s : J` 18 | 3. if `#!rzk ts : I * J`, then `#!rzk first ts : I` and `#!rzk second ts : J` 19 | 20 | You can usually use `#!rzk (t, s)` both as a pattern, and a construction of a pair of points: 21 | 22 | ```rzk 23 | -- Swap point components of a point in a cube I × I 24 | #define swap 25 | ( I : CUBE) 26 | : ( I × I) → I × I 27 | := \ ( t , s) → (s , t) 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/extension-types.rzk.md: -------------------------------------------------------------------------------- 1 | # Extension types 2 | 3 | 4 | 4. Extension types \(\left\langle \prod_{t : I \mid \psi} A \vert ^{\phi} _{a} \right\rangle\) are written as `#!rzk {t : I | psi t} -> A [ phi |-> a ]` 5 | - specifying `#!rzk [ phi |-> a ]` is optional, semantically defaults to `#!rzk [ BOT |-> recBOT ]` (like in RSTT); 6 | - specifying `#!rzk psi` in `#!rzk {t : I | psi}` is mandatory; 7 | - values of function types are \(\lambda\)-abstractions written in one of the following ways: 8 | - `#!rzk \t -> ` — this is usually fine; 9 | - `#!rzk \{t : I | psi} -> ` — this sometimes helps the typechecker; 10 | 11 | 5. Types of functions from a shape \(\prod_{t : I \mid \psi} A\) are a specialised variant of extension types and are written `#!rzk {t : I | psi} -> A` 12 | - specifying the name of the argument is mandatory; i.e. `#!rzk {I | psi} -> A` is invalid syntax! 13 | - values of function types are \(\lambda\)-abstractions written in one of the following ways: 14 | - `#!rzk \t -> ` — this is usually fine; 15 | - `#!rzk \{t : I | psi} -> ` — this sometimes helps the typechecker; 16 | 17 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 18 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/introduction.rzk.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | `rzk` is an experimental proof assistant for synthetic ∞-categories. 4 | `rzk-1` is an early version of the language supported by `rzk`. 5 | The language is based on Riehl and Shulman's «Type Theory for Synthetic ∞-categories»[^1]. In this section, we introduce syntax, discuss features and some of the current limitations of the proof assistant. 6 | 7 | Overall, a program in `rzk-1` consists of a language pragma (specifying that we use `rzk-1` and not one of the other languages[^2]) followed by a sequence of commands. For now, we will only use `#define` command. 8 | 9 | Here is a small formalisation in an MLTT subset of `rzk-1`: 10 | 11 | ```rzk 12 | #lang rzk-1 13 | 14 | -- Flipping the arguments of a function. 15 | #define flip 16 | (A B : U) -- For any types A and B 17 | (C : (x : A) -> (y : B) -> U) -- and a type family C 18 | (f : (x : A) -> (y : B) -> C x y) -- given a function f : A -> B -> C 19 | : (y : B) -> (x : A) -> C x y -- we construct a function of type B -> A -> C 20 | := \y x -> f x y -- by swapping the arguments 21 | 22 | -- Flipping a function twice is the same as not doing anything 23 | #define flip-flip-is-id 24 | (A B : U) -- For any types A and B 25 | (C : (x : A) -> (y : B) -> U) -- and a type family C 26 | (f : (x : A) -> (y : B) -> C x y) -- given a function f : A -> B -> C 27 | : f = flip B A (\y x -> C x y) 28 | (flip A B C f) -- flipping f twice is the same as f 29 | := refl -- proof by reflexivity 30 | ``` 31 | 32 | Let us explain parts of this code: 33 | 34 | 1. `#!rzk #lang rzk-1` specifies that we are in using `#!rzk rzk-1` language; 35 | 2. `#!rzk --` starts a comment line (until the end of the line); 36 | 3. `#!rzk #define «name» : «type» := «term»` defines a name `«name»` to be equal to `«term»`; the proof assistant will typecheck `«term»` against type `«type»`; 37 | 4. We define two terms here — `flip` and `flip-flip-is-id`; 38 | 5. `flip` is a function that takes 4 arguments and returns a function of two arguments. 39 | 6. `flip-flip-is-id` is a function that takes two types, a type family, and a function `f` and returns a value of an identity type `flip ... (flip ... f) = f`, indicating that flipping a function `f` twice gets us back to `f`. 40 | 41 | Similarly to the three layers in Riehl and Shulman's type theory, `rzk-1` has 3 universes: 42 | 43 | - `CUBE` is the universe of cubes, corresponding to the cube layer; 44 | - `TOPE` is the universe of topes, corresponding to the tope layer; 45 | - `U` is the universe of types, corresponding to the types and terms layer. 46 | 47 | These are explained in the following sections. 48 | 49 | ## Soundness 50 | 51 | `rzk-1` assumes "type-in-type", that is `U` has type `U`. 52 | This is known to make the type system unsound (due to Russell and Curry-style paradoxes), however, 53 | it is sometimes considered acceptable in proof assistants. 54 | And, since it simplifies implementation, `rzk-1` embraces this assumption, at least for now. 55 | 56 | Moreover, `rzk-1` does not prevent cubes or topes to depend on types and terms. For example, the following definition typechecks: 57 | 58 | ```rzk 59 | #define weird 60 | (A : U) 61 | (I : A -> CUBE) 62 | (x y : A) 63 | : CUBE 64 | := I x * I y 65 | ``` 66 | 67 | This likely leads to another inconsistency, but it will probably not lead to bugs in actual proofs of interest, 68 | so current version embraces this lax treatment of universes. 69 | 70 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 71 | 72 | [^2]: In version [:octicons-tag-24: v0.1.0](https://github.com/rzk-lang/rzk/releases/tag/v0.1.0), `rzk` has supported simply typed lambda calculus, PCF, and MLTT. However, those languages have been removed. 73 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/render.rzk.md: -------------------------------------------------------------------------------- 1 | # Rendering Diagrams 2 | 3 | Starting from version `0.3.0`, `rzk` supports rendering of topes, types, and terms as diagrams. 4 | 5 | This is a literate `rzk` file: 6 | 7 | ```rzk 8 | #lang rzk-1 9 | ``` 10 | 11 | To enable rendering, enable option `"render" = "svg"` (to disable, `"render" = "none"`): 12 | 13 | ```rzk 14 | #set-option "render" = "svg" -- enable rendering in SVG 15 | ``` 16 | 17 | Rendering is completely automatic, and works in the following situations: 18 | 19 | 1. Mapping from a shape (including curried mappings), up to 3 dimensions, only in products of `2` cubes; 20 | 2. Type of mapping from a shape (including curried mappings), up to 3 dimensions, only in products of `2` cubes. 21 | 3. Mappings from a shape that is a section of an existing shape. 22 | 23 | The rendering assigns the following colors: 24 | 25 | - purple is assigned for parameters (context) variables; 26 | - blue is used for fillings for types (e.g. for `hom` and `hom2`); 27 | - red is used for terms (e.g. `Segal-comp-witness`); 28 | - orange is used for shapes in the tope layer; 29 | - grey is used for discarded parts of a (larger) mapping (e.g. when extracting a diagonal/face from a larger shape). 30 | 31 | The SVG pictures can be inserted directly into `.md` files before a corresponding `rzk` code block. At the bottom of a markdown file, you might want to add stylization, e.g.: 32 | 33 | ```html 34 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 46 | 47 | 48 | 56 | 57 | ``` 58 | 59 | ## Examples 60 | 61 | ### Visualising Simplicial Topes 62 | 63 | Topes are visualised with **orange** color: 64 | 65 | ```rzk 66 | -- 2-simplex 67 | #define Δ² : (2 * 2) -> TOPE 68 | := \(t, s) -> s <= t 69 | ``` 70 |

71 | Boundary of a tope: 72 | 73 | ```rzk 74 | -- boundary of a 2-simplex 75 | #define ∂Δ² : Δ² -> TOPE 76 | := \(t, s) -> s === 0_2 \/ t === 1_2 \/ s === t 77 | ``` 78 | 79 | The busiest tope diagram involves the entire 3D cube: 80 |

81 | 82 | ```rzk 83 | -- 3-dim cube 84 | #define 2³ : (2 * 2 * 2) -> TOPE 85 | := \_ -> TOP 86 | ``` 87 |


88 | 89 | ```rzk 90 | -- 3-simplex 91 | #define Δ³ : (2 * 2 * 2) -> TOPE 92 | := \((t1, t2), t3) -> t3 <= t2 /\ t2 <= t1 93 | ``` 94 | 95 |

96 | ### Visualising Simplicial Types 97 | 98 | Types are visualised with **blue** color. Recognised parameter part (e.g. fixed endpoints, edges, faces with clear labels) are visualised with **purple** color. When a type is constructed by taking a part of another shape, the rest of the larger shape is colored using **gray** color. 99 | 100 | ```rzk 101 | -- [RS17, Definition 5.1] 102 | -- The type of arrows in A from x to y. 103 | #define hom 104 | (A : U) -- A type. 105 | (x y : A) -- Two points in A. 106 | : U -- (hom A x y) is a 1-simplex (an arrow) 107 | := (t : 2) -> A [ -- in A where 108 | t === 0_2 |-> x, -- * the left endpoint is exactly x 109 | t === 1_2 |-> y -- * the right endpoint is exactly y 110 | ] 111 | ``` 112 | 113 | ```rzk 114 | -- [RS17, Definition 5.2] 115 | -- the type of commutative triangles in A 116 | #define hom2 117 | (A : U) -- A type. 118 | (x y z : A) -- Three points in A. 119 | (f : hom A x y) -- An arrow in A from x to y. 120 | (g : hom A y z) -- An arrow in A from y to z. 121 | (h : hom A x z) -- An arrow in A from x to z. 122 | : U -- (hom2 A x y z f g h) is a 2-simplex (triangle) 123 | := { (t1, t2) : Δ² } -> A [ -- in A where 124 | t2 === 0_2 |-> f t1, -- * the top edge is exactly f, 125 | t1 === 1_2 |-> g t2, -- * the right edge is exactly g, and 126 | t2 === t1 |-> h t2 -- * the diagonal is exactly h 127 | ] 128 | ``` 129 | 130 | ### Visualising Terms of Simplicial Types 131 | 132 | Terms (with non-trivial labels) are visualised with **red** color (you can see a detailed label on hover). Recognised parameter part (e.g. fixed endpoints, edges, faces with clear labels) are visualised with **purple** color. When a term is constructed by taking a part of another shape, the rest of the larger shape is colored using **gray** color. 133 | 134 | We can visualise terms that fill a shape: 135 | 136 | ```rzk 137 | #define square 138 | (A : U) 139 | (x y z : A) 140 | (f : hom A x y) 141 | (g : hom A y z) 142 | (h : hom A x z) 143 | (a : Sigma (h' : hom A x z), hom2 A x y z f g h') 144 | : (2 * 2) -> A 145 | := \(t, s) -> recOR( s <= t |-> second a (t, s) , t <= s |-> second a (s, t)) 146 | ``` 147 | 148 | If a term is extracted as a part of a larger shape, generally, the whole shape will be shown (in gray): 149 | 150 | ```rzk 151 | #define face 152 | (A : U) 153 | (x y z : A) 154 | (f : hom A x y) 155 | (a : Sigma (g : hom A y z), {((t1, t2), t3) : 2 * 2 * 2 | t3 <= t1 \/ t2 <= t1} -> A [ t1 === 0_2 |-> f t2, t1 === 1_2 |-> g t3 ]) 156 | : Δ² -> A 157 | := \(t, s) -> second a ((t, t), s) 158 | ``` 159 | 160 | 161 | 165 | 166 | 167 | 168 | 169 | 170 | 172 | 173 | 174 | 175 | 183 | 184 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/sections.rzk.md: -------------------------------------------------------------------------------- 1 | # Sections and Variables 2 | 3 | Sections and variables allow to simplify definitions by factoring out common assumptions. 4 | 5 | !!! info "Coq-style variables" 6 | `rzk` implements variables similarly to 7 | `Variable` command in Coq. 8 | An important difference is that `rzk` does not allow definitions to use variables implicitly and adds `uses (...)` annotations to ensure such dependencies are not accidental. 9 | This is, perhaps, somewhat related to this error message in Coq. 10 | 11 | This is a literate `rzk` file: 12 | 13 | ```rzk 14 | #lang rzk-1 15 | ``` 16 | 17 | ## Variables 18 | 19 | Consider the following definitions: 20 | 21 | ```rzk 22 | #define compose₁ 23 | (A B C : U) 24 | (g : B -> C) 25 | (f : A -> B) 26 | : A -> C 27 | := \x -> g (f x) 28 | 29 | #define twice₁ 30 | (A : U) 31 | (h : A -> A) 32 | : A -> A 33 | := \x -> h (h x) 34 | ``` 35 | 36 | Since it might be common to introduce types `A`, `B`, and `C`, we can declare these are variables: 37 | 38 | ```rzk 39 | #variables A B C : U 40 | 41 | #define compose₂ 42 | (g : B -> C) 43 | (f : A -> B) 44 | : A -> C 45 | := \x -> g (f x) 46 | 47 | #define twice₂ 48 | (h : A -> A) 49 | : A -> A 50 | := \x -> h (h x) 51 | ``` 52 | 53 | The `#variables` command here introduces assumptions, which can be used in the following definitions. Importantly, after checking a file (module), all definitions will have the assumptions used (explicitly or implicitly) attached as bound variables. 54 | 55 | ### Implicitly used variables (and `uses`) 56 | 57 | We can try going even further and declare variables `f`, `g`, `h`, and `x`: 58 | 59 | ```rzk 60 | #variable g : B -> C 61 | #variable f : A -> B 62 | #variable h : A -> A 63 | #variable x : A 64 | 65 | -- #define bad-compose₃ : C := g (f x) -- ERROR: implicit assumptions A and B 66 | #define twice₃ : A := h (h x) 67 | ``` 68 | 69 | Note how this definition of `bad-compose₃` is implicitly dependent on the types `A` and `B`, which is promptly noted by `rzk`, which issues an error (if we uncomment the corresponding line): 70 | 71 | ```text 72 | implicit assumption 73 | B : U 74 | used in definition of 75 | bad-compose₃ 76 | ``` 77 | 78 | To let `rzk` know that this is not accidental, we can add `uses (...)` annotation to specify a list of variables implicitly used in the definition: 79 | 80 | ```rzk 81 | #define compose₃ uses (A B) : C := g (f x) 82 | ``` 83 | 84 | ## Sections 85 | 86 | To introduce assumption variables temporarily inside of one file, you can use sections: 87 | 88 | ```rzk 89 | #section example-1 90 | 91 | #variables X Y Z : U 92 | #variable k : X -> X 93 | #variable x' : X 94 | 95 | #define compose₄ 96 | (g : Y -> Z) 97 | (f : X -> Y) 98 | : X -> Z 99 | := \x -> g (f x) 100 | 101 | #define twice₄ : X := k (k x') 102 | 103 | #end example-1 104 | ``` 105 | 106 | Now, once outside of the section, `compose₄` and `twice₄` obtain corresponding parameters 107 | (only those used, explicitly or implicitly): 108 | 109 | ```rzk 110 | -- compose₄ : (X : U) -> (Y : U) -> (Z : U) -> (g : Y -> Z) -> (f : X -> Y) -> (X -> Z) 111 | -- twice₄ : (X : U) -> (k : X -> X) -> (x' : X) -> X 112 | 113 | #define twice₅ 114 | (T : U) 115 | (e : T -> T) 116 | : T -> T 117 | := compose₄ T T T e e 118 | 119 | #define identity 120 | (T : U) 121 | : T -> T 122 | := twice₄ T (\t -> t) 123 | ``` 124 | 125 | !!! warning "Lack of indentation" 126 | `rzk` currently does not support indentation, so all definitions and commands inside a section (including nested sections) have to start at the beginning of a line. 127 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/tope-disjunction-elimination.rzk.md: -------------------------------------------------------------------------------- 1 | # Tope disjuction elimination 2 | 3 | Following Riehl and Shulman's type theory[^1], `#!rzk rzk-1` introduces two primitive terms for disjunction elimination: 4 | 5 | 1. `#!rzk recBOT` corresponds to \(\mathsf{rec}_\bot\), has any type, and is valid whenever tope context is included in `#!rzk BOT`; 6 | 7 | 2. `#!rzk recOR(«tope_1» |-> «term_1», ..., «tope_n» |-> «term_n»)` defines a term for a disjunction of topes `#!rzk «tope_1» \/ ... \/ «tope_n»`. This is well-typed when for an intersection of any two topes `#!rzk «tope_i» /\ «tope_j»` the corresponding terms `#!rzk «term_i»` and `#!rzk «term_j»` are judgementally equal. In particular, `#!rzk recOR(psi |-> a_psi, phi |-> a_phi)` corresponds to \(\mathsf{rec}_\lor^{\psi, \phi}(a_\psi, a_\phi)\). 8 | 9 | !!! warning "Deprecated syntax" 10 | `#!rzk recOR(psi, phi, a_psi, a_phi)` corresponds to \(\mathsf{rec}_\lor^{\psi, \phi}(a_\psi, a_\phi)\), is well-typed when `#!rzk a_psi` is definitionally equal to `#!rzk a_phi` under `#!rzk psi /\ phi`. However, this syntax is deprecated since it is easy to confuse which tope relates to which term. 11 | 12 | [^1]: Emily Riehl & Michael Shulman. _A type theory for synthetic ∞-categories._ Higher Structures 1(1), 147-224. 2017. 13 | 14 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/tope-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Tope layer 2 | 3 | All topes live in `#!rzk TOPE` universe. 4 | 5 | Here are all the ways to build a tope: 6 | 7 | 1. Introduce a variable, e.g. `#!rzk (psi : TOPE) -> ...`; 8 | 9 | - Usually, topes depend on point variables from some cube(s). To indicate that, we usually introduce topes as "functions" from some cube to `#!rzk TOPE`. For example, `#!rzk (psi : I -> TOPE) -> ...`. 10 | 11 | 2. Use a constant: 12 | 13 | - top tope \(\top\) is written `#!rzk TOP` 14 | - bottom tope \(\bot\) is written `#!rzk BOT` 15 | 16 | 3. Usa a tope connective: 17 | - tope conjunction \(\psi \land \phi\) is written `#!rzk psi /\ phi` 18 | - tope disjunction \(\psi \lor \phi\) is written `#!rzk psi \/ phi` 19 | - equality tope \(t \equiv s\) is written `#!rzk t === s`, whenever `#!rzk t` and `#!rzk s` are points of the same cube 20 | - inequality tope \(t \leq s\) is written `#!rzk t <= s` whenever `#!rzk t : 2` and `#!rzk s : 2` 21 | 22 | -------------------------------------------------------------------------------- /docs/docs/ru/reference/type-layer.rzk.md: -------------------------------------------------------------------------------- 1 | # Types and terms 2 | 3 | ```rzk 4 | #lang rzk-1 5 | ``` 6 | 7 | ## Functions (dependent products) 8 | 9 | Function (dependent product) types \(\prod_{x : A} B\) are written `#!rzk (x : A) -> B x`. Values of function types are \(\lambda\)-abstractions written in one of the following ways: 10 | 11 | - `#!rzk \x -> ` — this is usually fine; 12 | - `#!rzk \(x : A) -> ` — this sometimes helps the typechecker. 13 | 14 | ## Dependent sums 15 | 16 | Dependent sum type \(\sum_{x : A} B\) is written `#!rzk ∑ (x : A), B` or `#!rzk Sigma (x : A), B`. Values of dependent sum types are pairs written as `#!rzk (x, y)`. 17 | 18 | To access components of a dependent pair `#!rzk p`, use `#!rzk first p` and `#!rzk second p`. 19 | 20 | !!! warning 21 | `#!rzk first` and `#!rzk second` are not valid syntax without an argument! 22 | 23 | ## Identity types 24 | 25 | Identity (path) type \(x =_A y\) is written `#!rzk x =_{A} y`. 26 | 27 | !!! tip 28 | Specifying the type `#!rzk A` is optional: `#!rzk x = y` is valid syntax! 29 | 30 | Any identity type has value `#!rzk refl_{x : A}` whose type is `#!rzk x =_{A} x` whenever `#!rzk x : A` 31 | 32 | !!! tip 33 | Specifying term and type of `#!rzk refl_{x : A}` is optional: `#!rzk refl_{x}` and `#!rzk refl` are both valid syntax. 34 | 35 | Path induction is done using \(\mathcal{J}\) path eliminator: 36 | 37 | - for 38 | - any type \(A\) and \(a : A\), 39 | - type family \(C : \prod_{x : A} ((a =_A x) \to \mathcal{U})\) and 40 | - \(d : C(a,\mathsf{refl}_a)\) and 41 | - \(x : A\) and \(p : a =_A x\) 42 | - we have \(\mathcal{J}(A, a, C, d, x, p) : C(x, p)\) 43 | 44 | In `#!rzk rzk-1` we write `#!rzk idJ(A, a, C, d, x, p)` 45 | 46 | !!! warning 47 | `#!rzk idJ` is not valid syntax without exactly 6-tuple provided as an argument! 48 | 49 | -------------------------------------------------------------------------------- /docs/docs/ru/rzk.yaml: -------------------------------------------------------------------------------- 1 | include: 2 | - getting-started/dependent-types.rzk.md 3 | - examples/recId.rzk.md 4 | -------------------------------------------------------------------------------- /docs/docs/ru/tools.md: -------------------------------------------------------------------------------- 1 | # Инструменты 2 | 3 | Решатель теорем Rzk включает в себя языковой сервер и возможность автоматичекого форматирования. 4 | 5 | Другие инструменты улучшают пользовательский опыт и/или автоматизируют частные задачи. 6 | 7 | ### Расширение для VS Code 8 | 9 | См. [rzk-lang/vscode-rzk](https://github.com/rzk-lang/vscode-rzk). 10 | Расширение предлагает много удобств и использование VS Code с ним рекомендуется, особенно новичкам, 11 | поскольку это наиболее распространённый способ работы с Rzk и ему уделяется больше внимания со стороны разработчиков. 12 | 13 | ### Плагин для MkDocs 14 | 15 | См. [rzk-lang/mkdocs-plugin-rzk](https://github.com/rzk-lang/mkdocs-plugin-rzk). 16 | Плагин улучшает документацию, получаемую из литературных файлов с формализациями (`.rzk.md`): 17 | - добавляет SVG-диаграммы по определениям/доказательствам, если возможно (экспериментальная поддержка) 18 | - добавляет якоря для определний (полезно для создания ссылок на конкретные определения) 19 | 20 | ### Скрипт для GitHub Action 21 | 22 | См. [rzk-lang/rzk-action](https://github.com/rzk-lang/rzk-action). 23 | Этот скрипт позволяет проверять формализации на Rzk для проектов на GitHub автоматически. 24 | Скрипт также экспериментально поддерживает проверку форматирования. 25 | 26 | ### Подсветка синтаксиса (Pygments) 27 | 28 | См. [rzk-lang/pygments-rzk](https://github.com/rzk-lang/pygments-rzk). 29 | Это простая реализация подсветки синтаксиса (используется при генерации документации с MkDocs и пакетом `minted` package в LaTeX). 30 | Учтите, что подсветка может отличатся от подсветки в VS Code, т.к. последний использует языковой сервер Rzk для более точной "семантической подсветки". 31 | -------------------------------------------------------------------------------- /docs/overrides/assets/css/rzk-render.css: -------------------------------------------------------------------------------- 1 | .rzk-render { 2 | float: right; 3 | clear: both; 4 | position: relative; 5 | z-index: 1; 6 | } 7 | -------------------------------------------------------------------------------- /docs/overrides/assets/images/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/android-chrome-192x192.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/android-chrome-512x512.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/favicon-16x16.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/favicon-32x32.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/favicon.ico -------------------------------------------------------------------------------- /docs/overrides/assets/images/logo-1000x1000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/logo-1000x1000.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/vscode-rzk-install-prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/vscode-rzk-install-prompt.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/vscode-rzk-install-success-reload-prompt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/vscode-rzk-install-success-reload-prompt.png -------------------------------------------------------------------------------- /docs/overrides/assets/images/vscode-rzk-select-language.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/docs/overrides/assets/images/vscode-rzk-select-language.png -------------------------------------------------------------------------------- /docs/overrides/javascript/mathjax.js: -------------------------------------------------------------------------------- 1 | window.MathJax = { 2 | tex: { 3 | inlineMath: [["\\(", "\\)"]], 4 | displayMath: [["\\[", "\\]"]], 5 | processEscapes: true, 6 | processEnvironments: true 7 | }, 8 | options: { 9 | ignoreHtmlClass: ".*|", 10 | processHtmlClass: "arithmatex" 11 | } 12 | }; 13 | 14 | document$.subscribe(() => { 15 | MathJax.typesetPromise() 16 | }) 17 | 18 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs-material[imaging] 2 | mike==2.0.0 3 | python-markdown-math 4 | mkdocs-plugin-rzk 5 | pygments-rzk 6 | mkdocs-rss-plugin 7 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-compat": { 4 | "flake": false, 5 | "locked": { 6 | "lastModified": 1673956053, 7 | "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", 8 | "owner": "edolstra", 9 | "repo": "flake-compat", 10 | "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", 11 | "type": "github" 12 | }, 13 | "original": { 14 | "owner": "edolstra", 15 | "repo": "flake-compat", 16 | "type": "github" 17 | } 18 | }, 19 | "flake-utils": { 20 | "inputs": { 21 | "systems": "systems" 22 | }, 23 | "locked": { 24 | "lastModified": 1694529238, 25 | "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", 26 | "owner": "numtide", 27 | "repo": "flake-utils", 28 | "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", 29 | "type": "github" 30 | }, 31 | "original": { 32 | "owner": "numtide", 33 | "repo": "flake-utils", 34 | "type": "github" 35 | } 36 | }, 37 | "jsaddle": { 38 | "flake": false, 39 | "locked": { 40 | "lastModified": 1694167118, 41 | "narHash": "sha256-QNWimHH7c0xYe8sVmS2U3CgCR2q2fz2G35XTUywSrk8=", 42 | "owner": "ghcjs", 43 | "repo": "jsaddle", 44 | "rev": "ffcda85943fd4b91a715643b921a10df9aba44e1", 45 | "type": "github" 46 | }, 47 | "original": { 48 | "owner": "ghcjs", 49 | "repo": "jsaddle", 50 | "type": "github" 51 | } 52 | }, 53 | "miso": { 54 | "flake": false, 55 | "locked": { 56 | "lastModified": 1712007677, 57 | "narHash": "sha256-6Ewu/T+VyeQ93lrN6bcpyCcoinwtO/X8HJrJp7hLSEQ=", 58 | "owner": "dmjio", 59 | "repo": "miso", 60 | "rev": "8277ac79941825abaf50b917e074e3df7ef6d213", 61 | "type": "github" 62 | }, 63 | "original": { 64 | "owner": "dmjio", 65 | "repo": "miso", 66 | "rev": "8277ac79941825abaf50b917e074e3df7ef6d213", 67 | "type": "github" 68 | } 69 | }, 70 | "nix-filter": { 71 | "locked": { 72 | "lastModified": 1694857738, 73 | "narHash": "sha256-bxxNyLHjhu0N8T3REINXQ2ZkJco0ABFPn6PIe2QUfqo=", 74 | "owner": "numtide", 75 | "repo": "nix-filter", 76 | "rev": "41fd48e00c22b4ced525af521ead8792402de0ea", 77 | "type": "github" 78 | }, 79 | "original": { 80 | "owner": "numtide", 81 | "repo": "nix-filter", 82 | "type": "github" 83 | } 84 | }, 85 | "nixpkgs": { 86 | "locked": { 87 | "lastModified": 1713187215, 88 | "narHash": "sha256-3WqIvGM8G5mgF9sabP7eAG+lW0n6RaN/xUdjk15lqP4=", 89 | "owner": "NixOS", 90 | "repo": "nixpkgs", 91 | "rev": "2436aaf8fad634ee66a6280fb82a19c1771c173f", 92 | "type": "github" 93 | }, 94 | "original": { 95 | "owner": "NixOS", 96 | "repo": "nixpkgs", 97 | "rev": "2436aaf8fad634ee66a6280fb82a19c1771c173f", 98 | "type": "github" 99 | } 100 | }, 101 | "root": { 102 | "inputs": { 103 | "flake-compat": "flake-compat", 104 | "flake-utils": "flake-utils", 105 | "jsaddle": "jsaddle", 106 | "miso": "miso", 107 | "nix-filter": "nix-filter", 108 | "nixpkgs": "nixpkgs" 109 | } 110 | }, 111 | "systems": { 112 | "locked": { 113 | "lastModified": 1681028828, 114 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 115 | "owner": "nix-systems", 116 | "repo": "default", 117 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 118 | "type": "github" 119 | }, 120 | "original": { 121 | "owner": "nix-systems", 122 | "repo": "default", 123 | "type": "github" 124 | } 125 | } 126 | }, 127 | "root": "root", 128 | "version": 7 129 | } 130 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | flake-utils.url = "github:numtide/flake-utils"; 4 | nixpkgs.url = "github:NixOS/nixpkgs/2436aaf8fad634ee66a6280fb82a19c1771c173f"; 5 | miso = { 6 | url = "github:dmjio/miso/8277ac79941825abaf50b917e074e3df7ef6d213"; 7 | flake = false; 8 | }; 9 | flake-compat = { 10 | url = "github:edolstra/flake-compat"; 11 | flake = false; 12 | }; 13 | nix-filter.url = "github:numtide/nix-filter"; 14 | jsaddle = { 15 | url = "github:ghcjs/jsaddle"; 16 | flake = false; 17 | }; 18 | }; 19 | outputs = inputs: inputs.flake-utils.lib.eachDefaultSystem (system: 20 | let 21 | pkgs = inputs.nixpkgs.legacyPackages.${system}; 22 | 23 | rzk = "rzk"; 24 | rzk-js = "rzk-js"; 25 | ghcVersion = "ghc963"; 26 | rzk-src = (inputs.nix-filter { 27 | root = ./${rzk}; 28 | include = [ "app" "src" "test" "package.yaml" ]; 29 | }); 30 | rzk-js-src = (inputs.nix-filter { 31 | root = ./${rzk-js}; 32 | include = [ "Main.hs" "${rzk-js}.cabal" ]; 33 | }); 34 | 35 | tools = [ 36 | pkgs.cabal-install 37 | pkgs.hpack 38 | pkgs.nodejs_18 39 | pkgs.bun 40 | ]; 41 | 42 | default = import ./nix/default.nix { inherit inputs pkgs rzk rzk-src ghcVersion tools; }; 43 | ghcjs = import ./nix/ghcjs.nix { inherit inputs pkgs scripts rzk rzk-src rzk-js rzk-js-src ghcVersion tools; }; 44 | scripts = import ./nix/scripts.nix { inherit pkgs packages; }; 45 | 46 | 47 | packages = { 48 | default = default.packages.default; 49 | rzk = default.packages.${rzk}; 50 | rzk-ghcjs = ghcjs.packages.${rzk}; 51 | rzk-js = ghcjs.packages.${rzk-js}; 52 | } // scripts; 53 | 54 | devShells = { 55 | default = default.devShells.default; 56 | ghcjs = ghcjs.devShells.default; 57 | release = pkgs.mkShell { 58 | buildInputs = [ scripts.release-rzk-playground ]; 59 | }; 60 | }; 61 | in 62 | { 63 | inherit packages devShells default ghcjs; 64 | }); 65 | 66 | nixConfig = { 67 | extra-substituters = [ 68 | "https://miso-haskell.cachix.org" 69 | "https://nix-community.cachix.org" 70 | "https://cache.iog.io" 71 | ]; 72 | extra-trusted-public-keys = [ 73 | "miso-haskell.cachix.org-1:6N2DooyFlZOHUfJtAx1Q09H0P5XXYzoxxQYiwn6W1e8=" 74 | "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" 75 | "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=" 76 | ]; 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /hie.yaml: -------------------------------------------------------------------------------- 1 | cradle: 2 | stack: 3 | -------------------------------------------------------------------------------- /images/split-demo-render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/images/split-demo-render.png -------------------------------------------------------------------------------- /images/split-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/images/split-demo.png -------------------------------------------------------------------------------- /nix/default.nix: -------------------------------------------------------------------------------- 1 | { inputs, pkgs, ghcVersion, rzk, rzk-src, tools }: 2 | let 3 | inherit (pkgs.haskell.lib) overrideCabal; 4 | # https://nixos.wiki/wiki/Haskell#Overrides 5 | hpkgs = pkgs.haskell.packages.${ghcVersion}.override { 6 | overrides = final: prev: { 7 | ${rzk} = final.callCabal2nix rzk rzk-src { }; 8 | }; 9 | }; 10 | 11 | devShells = { 12 | default = 13 | hpkgs.shellFor { 14 | shellHook = "export LANG=C.utf8"; 15 | packages = ps: [ ps.rzk ]; 16 | nativeBuildInputs = tools ++ [ hpkgs.haskell-language-server ]; 17 | }; 18 | }; 19 | 20 | packages = { 21 | default = pkgs.haskell.lib.justStaticExecutables hpkgs.${rzk}; 22 | rzk = hpkgs.${rzk}; 23 | }; 24 | in 25 | { 26 | inherit hpkgs devShells packages; 27 | } 28 | -------------------------------------------------------------------------------- /nix/ghcjs.nix: -------------------------------------------------------------------------------- 1 | { inputs, pkgs, scripts, rzk, rzk-js, rzk-src, rzk-js-src, ghcVersion, tools }: 2 | let 3 | inherit (pkgs.haskell.lib) overrideCabal; 4 | misoNix = (import "${inputs.miso}/default.nix" { inherit (pkgs) system; }); 5 | pkgsMiso = misoNix.pkgs; 6 | 7 | hpkgs = 8 | pkgsMiso.haskell.packages.ghcjs.override { 9 | overrides = final: prev: { 10 | mkDerivation = args: prev.mkDerivation (args // { 11 | doCheck = false; 12 | doHaddock = false; 13 | }); 14 | hpack = pkgs.hpack; 15 | rzk = ( 16 | (pkgsMiso.haskell.lib.overrideCabal 17 | (prev.callCabal2nix rzk rzk-src { }) 18 | (x: { 19 | isLibrary = true; 20 | isExecutable = false; 21 | buildTarget = "lib:rzk"; 22 | libraryToolDepends = [ pkgs.hpack pkgs.alex pkgs.happy ] ++ (x.libraryToolDepends or [ ]); 23 | testToolDepends = [ pkgs.alex pkgs.happy ] ++ (x.testToolDepends or [ ]); 24 | })) 25 | ).overrideAttrs (x: { 26 | installPhase = builtins.replaceStrings [ "Setup copy" ] [ "Setup copy lib:rzk" ] x.installPhase; 27 | }); 28 | rzk-js = overrideCabal 29 | (final.callCabal2nix rzk-js rzk-js-src { }) 30 | (x: { 31 | postInstall = (x.postInstall or "") + '' 32 | cp $out/bin/${rzk-js} . 33 | rm -r $out 34 | cp ${rzk-js} $out 35 | ''; 36 | }); 37 | }; 38 | }; 39 | 40 | hpkgsGHCJS_8_10_7 = pkgs.haskell.packages.ghcjs810.override ({ 41 | overrides = final: prev: { 42 | integer-gmp = final.integer-gmp_1_1; 43 | rzk = overrideCabal 44 | (final.callCabal2nix rzk rzk-src { }) 45 | (x: { 46 | isLibrary = true; 47 | isExecutable = false; 48 | doCheck = false; 49 | doHaddock = false; 50 | libraryToolDepends = [ pkgs.hpack pkgs.alex pkgs.happy ] ++ (x.libraryToolDepends or [ ]); 51 | testToolDepends = [ pkgs.hpack pkgs.alex pkgs.happy ] ++ (x.testToolDepends or [ ]); 52 | prePatch = "hpack --force"; 53 | }); 54 | rzk-js = overrideCabal 55 | (final.callCabal2nix rzk-js rzk-js-src { inherit (final) rzk; }) 56 | (x: { 57 | postInstall = (x.postInstall or "") + '' 58 | rm -r $out/bin/${rzk-js}.jsexe 59 | ''; 60 | }); 61 | }; 62 | }); 63 | 64 | packages = { 65 | inherit (hpkgs) rzk rzk-js; 66 | 67 | # Currently not buildable 68 | rzk_8_10_7 = hpkgsGHCJS_8_10_7.rzk; 69 | rzk-js_8_10_7 = hpkgsGHCJS_8_10_7; 70 | }; 71 | 72 | devShells = { 73 | default = (hpkgs.shellFor { 74 | packages = _: [ hpkgs.${rzk} hpkgs.${rzk-js} ]; 75 | nativeBuildInputs = tools ++ [ scripts.build-rzk-js ]; 76 | }).overrideAttrs (x: { 77 | buildInputs = builtins.filter (p: (p.name or "") != "ghc-8.6.4") (x.buildInputs or [ ]); 78 | }); 79 | }; 80 | in 81 | { 82 | inherit hpkgs devShells packages hpkgsGHCJS_8_10_7; 83 | } 84 | -------------------------------------------------------------------------------- /nix/js-backend.nix: -------------------------------------------------------------------------------- 1 | # TODO fix builds with JS backend 2 | 3 | { inputs, pkgs, rzk, rzk-js, rzk-src, rzk-js-src, ghcVersion, tools }: 4 | let 5 | inherit (pkgs.haskell.lib) overrideCabal; 6 | overrideJS = { 7 | overrides = self: super: { 8 | jsaddle = super.callCabal2nix "jsaddle" "${inputs.jsaddle.outPath}/jsaddle" { }; 9 | rzk = overrideCabal 10 | (super.callCabal2nix rzk rzk-src { }) 11 | (x: { 12 | isLibrary = true; 13 | isExecutable = false; 14 | doCheck = false; 15 | doHaddock = false; 16 | libraryToolDepends = [ pkgs.hpack pkgs.alex pkgs.happy ] ++ (x.libraryToolDepends or [ ]); 17 | testToolDepends = [ pkgs.hpack pkgs.alex pkgs.happy ] ++ (x.testToolDepends or [ ]); 18 | prePatch = "hpack --force"; 19 | }); 20 | rzk-js = overrideCabal 21 | (super.callCabal2nix rzk-js rzk-js-src { inherit (self) rzk; }) 22 | (x: { 23 | postInstall = (x.postInstall or "") + '' 24 | rm -r $out/bin/${rzk-js}.jsexe 25 | ''; 26 | }); 27 | }; 28 | }; 29 | hpkgs = pkgs.pkgsCross.ghcjs.buildPackages.haskell.packages.${ghcVersion}.override overrideJS; 30 | 31 | # Get all dependencies of local Haskell packages excluding these local packages 32 | # This approach is useful for cases when a local package A depends on a local package B 33 | # In this case, package B won't be built by Nix as a dependency of A 34 | getHaskellPackagesDeps = someHaskellPackages: let l = pkgs.lib.lists; in (l.subtractLists someHaskellPackages (l.concatLists (map (package: l.concatLists (__attrValues package.getCabalDeps)) someHaskellPackages))); 35 | # build a GHC with the dependencies of local Haskell packages 36 | ghcForPackages = hpkgs_: localHaskellPackageNames: hpkgs_.ghcWithPackages (ps: (getHaskellPackagesDeps (map (x: ps.${x}) localHaskellPackageNames) ++ [ ps.haskell-language-server ])); # Why provide HLS here - https://github.com/NixOS/nixpkgs/issues/225895#issuecomment-1509991742 37 | 38 | ghcWithPackages = ghcForPackages hpkgs [ rzk rzk-js ]; 39 | 40 | ghc = pkgs.pkgsCross.ghcjs.buildPackages.haskell.compiler.${ghcVersion}; 41 | 42 | packages = { 43 | # TODO fix doesn't build .js 44 | inherit (hpkgs) rzk rzk-js; 45 | }; 46 | 47 | devShells = { 48 | # This devshell provides a GHC compiler with packages that are dependencies of `rzk` and `rzk-js` 49 | # It should be a GHC with a JS backend, but it's an ordinary GHC for some reason 50 | 51 | default = hpkgs.shellFor { 52 | packages = ps: [ ps.rzk ps.${rzk-js} ]; 53 | nativeBuildInputs = tools; 54 | }; 55 | 56 | # This devshell provides a GHC compiler with packages that are dependencies of `rzk` and `rzk-js` 57 | # It should be a GHC with a JS backend, but it's an ordinary GHC for some reason 58 | 59 | ghcWithPackages = pkgs.mkShell { 60 | buildInputs = [ ghcWithPackages ] ++ tools; 61 | }; 62 | 63 | # This devshell provides a GHC compiler with JS backend and without extra packages 64 | 65 | # GHC fails to build `rzk-js` 66 | # cabal --with-compiler=javascript-unknown-ghcjs-ghc --with-ghc-pkg=javascript-unknown-ghcjs-ghc-pkg build rzk-js 67 | ghcJS = pkgs.mkShell { 68 | buildInputs = [ ghc ] ++ tools; 69 | }; 70 | 71 | 72 | # TODO incremental builds for ghc with js backend 73 | # Incremental builds work for ghc 9.6+ 74 | # https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/haskell.section.md#incremental-builds-haskell-incremental-builds 75 | }; 76 | in 77 | { 78 | inherit hpkgs devShells packages ghc ghcForPackages; 79 | } 80 | -------------------------------------------------------------------------------- /nix/scripts.nix: -------------------------------------------------------------------------------- 1 | { pkgs, packages }: 2 | let scripts = 3 | { 4 | build-rzk-js = pkgs.writeShellApplication { 5 | name = "build-rzk-js"; 6 | text = 7 | let 8 | public = "rzk-playground/public"; 9 | result = "${public}/rzk-js"; 10 | in 11 | '' 12 | cabal install rzk-js --ghcjs --installdir ${result} 13 | rm -f ${public}/rzk.js 14 | 15 | cp ${result}/rzk-js ${public}/rzk.js 16 | printf "Copied ${result}/rzk-js to ${public}/rzk.js\n" 17 | 18 | rm -rf ${result} 19 | printf "Removed ${result}\n" 20 | ''; 21 | }; 22 | 23 | save-flake = pkgs.writeShellApplication { 24 | name = "save-flake"; 25 | runtimeInputs = [ pkgs.jq ]; 26 | text = '' 27 | # save flake inputs - # https://github.com/NixOS/nix/issues/4250#issuecomment-1146878407 28 | 29 | mkdir -p "/nix/var/nix/gcroots/per-user/$USER" 30 | 31 | gc_root_prefix="/nix/var/nix/gcroots/per-user/$USER/$(systemd-escape -p "$PWD")-flake-" 32 | echo "Adding per-user gcroots..." 33 | rm -f "$gc_root_prefix"* 34 | nix flake archive --json 2>/dev/null \ 35 | | jq -r '.inputs | to_entries[] | "ln -fsT "+.value.path+" \"'"$gc_root_prefix"'"+.key+"\""' \ 36 | | while read -r line; \ 37 | do 38 | eval "$line" 39 | done 40 | 41 | # save scripts 42 | 43 | nix profile install --profile "$gc_root_prefix""${scripts.save-flake.name}" .#${scripts.save-flake.name} 44 | nix profile install --profile "$gc_root_prefix""${scripts.release-rzk-playground.name}" .#${scripts.release-rzk-playground.name} 45 | 46 | printf "Entries saved with prefix %s\n" "$gc_root_prefix" 47 | ''; 48 | }; 49 | 50 | release-rzk-playground = pkgs.writeShellApplication { 51 | name = "release-rzk-playground"; 52 | runtimeInputs = [ pkgs.nodejs_18 ]; 53 | text = 54 | let 55 | playground = "rzk-playground"; 56 | playground-rzk-js = "${playground}/public/rzk.js"; 57 | release = "rzk-playground-release"; 58 | in 59 | '' 60 | rm -f ${playground-rzk-js} 61 | mkdir -p "$(dirname ${playground-rzk-js})" 62 | cp ${packages.rzk-js} ${playground-rzk-js} 63 | 64 | ( 65 | cd ${playground} 66 | npm i 67 | ) 68 | 69 | rm -rf ${release} 70 | mkdir ${release} 71 | cp -r ${playground}/dist/* ${release} 72 | 73 | printf "Wrote release files to '${release}'\n" 74 | ''; 75 | }; 76 | }; 77 | in scripts 78 | -------------------------------------------------------------------------------- /rzk-js/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | module Main where 4 | 5 | import qualified GHCJS.Foreign.Callback as GHCJS 6 | import GHCJS.Marshal (fromJSVal, toJSVal) 7 | import GHCJS.Prim (JSVal) 8 | import Data.JSString(JSString, pack) 9 | import JavaScript.Object 10 | import JavaScript.Object.Internal (Object (..), create) 11 | import qualified Rzk.Main as Rzk 12 | import System.IO 13 | 14 | main :: IO () 15 | main = do 16 | putStr "Haskell logic core starting" 17 | hFlush stdout 18 | 19 | -- https://discourse.haskell.org/t/compile-library-with-ghcjs/4727 20 | callback <- GHCJS.syncCallback1 GHCJS.ThrowWouldBlock $ \jsval -> do 21 | let o = Object jsval 22 | rawInput <- getProp "input" o 23 | input <- maybe (Left "Could not turn JSRef to a String") Right <$> fromJSVal rawInput 24 | 25 | case Rzk.typecheckString =<< input of 26 | Left err -> setStringProp "status" "error" o >> setStringProp "result" (pack err) o 27 | Right ok -> setStringProp "status" "ok" o >> setStringProp "result" (pack ok) o 28 | 29 | set_rzk_typecheck_callback callback 30 | 31 | putStr "Haskell logic core callbacks initialized" 32 | 33 | setStringProp :: JSString -> JSString -> Object -> IO () 34 | setStringProp name valueRaw object = do 35 | value <- toJSVal valueRaw 36 | setProp name value object 37 | 38 | foreign import javascript unsafe "rzkTypecheck_ = $1" 39 | set_rzk_typecheck_callback :: GHCJS.Callback (JSVal -> IO ()) -> IO () 40 | -------------------------------------------------------------------------------- /rzk-js/rzk-js.cabal: -------------------------------------------------------------------------------- 1 | name: rzk-js 2 | version: 0.1.0 3 | synopsis: A serverless online version of Rzk proof assistant 4 | category: Web 5 | build-type: Simple 6 | cabal-version: >=1.10 7 | 8 | executable rzk-js 9 | main-is: Main.hs 10 | ghcjs-options: 11 | -dedupe 12 | build-depends: base, rzk 13 | if impl(ghcjs) 14 | build-depends: 15 | ghcjs-base, ghcjs-prim 16 | default-language: Haskell2010 17 | -------------------------------------------------------------------------------- /rzk-playground/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | ignorePatterns: ['dist', '.eslintrc.cjs'], 10 | parser: '@typescript-eslint/parser', 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': [ 14 | 'warn', 15 | { allowConstantExport: true }, 16 | ], 17 | }, 18 | } 19 | -------------------------------------------------------------------------------- /rzk-playground/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | 30 | # vercel 31 | .vercel 32 | 33 | # typescript 34 | *.tsbuildinfo 35 | next-env.d.ts 36 | 37 | public/rzk.js -------------------------------------------------------------------------------- /rzk-playground/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | 10 | ## Expanding the ESLint configuration 11 | 12 | If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: 13 | 14 | - Configure the top-level `parserOptions` property like this: 15 | 16 | ```js 17 | export default { 18 | // other rules... 19 | parserOptions: { 20 | ecmaVersion: 'latest', 21 | sourceType: 'module', 22 | project: ['./tsconfig.json', './tsconfig.node.json'], 23 | tsconfigRootDir: __dirname, 24 | }, 25 | } 26 | ``` 27 | 28 | - Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` 29 | - Optionally add `plugin:@typescript-eslint/stylistic-type-checked` 30 | - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list 31 | -------------------------------------------------------------------------------- /rzk-playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | Try Rzk proof assistant! 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /rzk-playground/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rzk-playground", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "tsc && vite build", 8 | "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", 9 | "preview": "vite preview", 10 | "prepare": "tsc && vite build" 11 | }, 12 | "dependencies": { 13 | "@uiw/react-codemirror": "^4.21.18", 14 | "re-resizable": "^6.9.11", 15 | "react": "^18.2.0", 16 | "react-dom": "^18.2.0", 17 | "react-keybinds": "^1.0.8", 18 | "react-resizable": "^3.0.5", 19 | "rzk-lezer": "./rzk-lezer" 20 | }, 21 | "devDependencies": { 22 | "@types/node": "^20.6.3", 23 | "@types/react": "^18.2.22", 24 | "@types/react-dom": "^18.2.7", 25 | "@typescript-eslint/eslint-plugin": "^6.0.0", 26 | "@typescript-eslint/parser": "^6.0.0", 27 | "@vitejs/plugin-react-swc": "^3.3.2", 28 | "eslint-plugin-react-hooks": "^4.6.0", 29 | "eslint-plugin-react-refresh": "^0.4.3", 30 | "vite": "^4.4.5", 31 | "eslint": "^8.49.0", 32 | "eslint-config-next": "^13.5.2", 33 | "typescript": "^5.2.2", 34 | "@types/react-resizable": "^3.0.4", 35 | "eslint-config-prettier": "^9.0.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /rzk-playground/rzk-lezer/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src/parser* 3 | examples/tree -------------------------------------------------------------------------------- /rzk-playground/rzk-lezer/examples/src/example.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | -- A is contractible there exists x : A such that for any y : A we have x = y. 4 | #def iscontr (A : U) : U 5 | := ∑ (a : A), (x : A) -> a =_{A} x 6 | 7 | -- A is a proposition if for any x, y : A we have x = y 8 | #def isaprop (A : U) : U 9 | := (x : A) -> (y : A) -> x =_{A} y 10 | 11 | -- A is a set if for any x, y : A the type x =_{A} y is a proposition 12 | #def isaset (A : U) : U 13 | := (x : A) -> (y : A) -> isaprop (x =_{A} y) 14 | 15 | -- Non-dependent product of A and B 16 | #def prod (A : U) (B : U) : U 17 | := ∑ (x : A), B 18 | 19 | -- A function f : A -> B is an equivalence 20 | -- if there exists g : B -> A 21 | -- such that for all x : A we have g (f x) = x 22 | -- and for all y : B we have f (g y) = y 23 | #def isweq (A : U) (B : U) (f : A -> B) : U 24 | := ∑ (g : B -> A), prod ((x : A) -> g (f x) =_{A} x) ((y : B) -> f (g y) =_{B} y) 25 | 26 | -- Equivalence of types A and B 27 | #def weq (A : U) (B : U) : U 28 | := ∑ (f : A -> B), isweq A B f 29 | 30 | -- Transport along a path 31 | #def transport 32 | (A : U) 33 | (C : A -> U) 34 | (x y : A) 35 | (p : x =_{A} y) 36 | : C x -> C y 37 | := \cx -> idJ(A, x, (\z q -> C z), cx, y, p) 38 | 39 | -- [RS17, Axiom 4.6] Relative function extensionality. 40 | #def relfunext : U 41 | := (I : CUBE) 42 | -> (psi : I -> TOPE) 43 | -> (phi : psi -> TOPE) 44 | -> (A : psi -> U) 45 | -> ((t : psi) -> iscontr (A t)) 46 | -> (a : (t : phi) -> A t) 47 | -> (t : psi) -> A t [ phi t |-> a t] 48 | 49 | -- [RS17, Proposition 4.8] A (weaker) formulation of function extensionality. 50 | #def relfunext2 : U 51 | := (I : CUBE) 52 | -> (psi : I -> TOPE) 53 | -> (phi : psi -> TOPE) 54 | -> (A : psi -> U) 55 | -> (a : (t : phi) -> A t) 56 | -> (f : (t : psi) -> A t [ phi t |-> a t ]) 57 | -> (g : (t : psi) -> A t [ phi t |-> a t ]) 58 | -> weq (f = g) 59 | ((t : psi) -> (f t =_{A t} g t) [ phi t |-> refl ]) 60 | 61 | -- Restrict extension type to a subshape. 62 | #def restrict 63 | (I : CUBE) 64 | (psi : I -> TOPE) 65 | (phi : I -> TOPE) 66 | (A : {t : I | psi t \/ phi t} -> U) 67 | (a : {t : I | psi t} -> A t) 68 | : {t : I | psi t /\ phi t} -> A t 69 | := \t -> a t 70 | 71 | -- Reformulate extension type as an extension of a restriction. 72 | #def ext-of-restrict 73 | (I : CUBE) 74 | (psi : I -> TOPE) 75 | (phi : I -> TOPE) 76 | (A : {t : I | psi t \/ phi t} -> U) 77 | (a : {t : I | psi t} -> A t) 78 | : (t : psi) -> A t [ psi t /\ phi t |-> restrict I psi phi A a t ] 79 | := a 80 | 81 | -- Transform extension of an identity into an identity of restrictions. 82 | #def restricts-path 83 | (r : relfunext2) 84 | (I : CUBE) 85 | (psi : I -> TOPE) 86 | (phi : I -> TOPE) 87 | (A : {t : I | psi t \/ phi t} -> U) 88 | (a_psi : (t : psi) -> A t) 89 | (a_phi : (t : phi) -> A t) 90 | (e : {t : I | psi t /\ phi t} -> a_psi t = a_phi t) 91 | : restrict I psi phi A a_psi = restrict I phi psi A a_phi 92 | := (first (second (r I 93 | (\t -> psi t /\ phi t) 94 | (\t -> BOT) 95 | (\t -> A t) 96 | (\t -> recBOT) 97 | (\t -> a_psi t) 98 | (\t -> a_phi t)))) e 99 | 100 | -- A weaker version of recOR, demanding only a path between a and b: 101 | -- recOR(psi, phi, a, b) demands that for psi /\ phi we have a == b (definitionally) 102 | -- (recId psi phi a b e) demands that e is the proof that a = b (intensionally) for psi /\ phi 103 | #def recId 104 | (r : relfunext2) 105 | (I : CUBE) 106 | (psi : I -> TOPE) 107 | (phi : I -> TOPE) 108 | (A : {t : I | psi t \/ phi t} -> U) 109 | (a_psi : (t : psi) -> A t) 110 | (a_phi : (t : phi) -> A t) 111 | (e : {t : I | psi t /\ phi t} -> a_psi t = a_phi t) 112 | : {t : I | psi t \/ phi t} -> A t 113 | := \t -> recOR( 114 | psi t |-> transport 115 | ({t : I | psi t /\ phi t} -> A t) 116 | (\ra -> (t : psi) -> A t [ psi t /\ phi t |-> ra t]) 117 | (restrict I psi phi A a_psi) 118 | (restrict I phi psi A a_phi) 119 | (restricts-path r I psi phi A a_psi a_phi e) 120 | (ext-of-restrict I psi phi A a_psi) 121 | t, 122 | phi t |-> ext-of-restrict I phi psi A a_phi t 123 | ) 124 | 125 | -- If two extension types are equal along two subshapes, 126 | -- then they are also equal along their union. 127 | #def id-along-border 128 | (r : relfunext2) 129 | (I : CUBE) 130 | (psi : I -> TOPE) 131 | (phi : I -> TOPE) 132 | (A : {t : I | psi t \/ phi t} -> U) 133 | (a b : {t : I | psi t \/ phi t} -> A t) 134 | (e_psi : (t : psi) -> a t = b t) 135 | (e_phi : (t : phi) -> a t = b t) 136 | (border-is-a-set : {t : I | psi t /\ phi t} -> isaset (A t)) 137 | : {t : I | psi t \/ phi t} -> a t = b t 138 | := recId r I psi phi 139 | (\t -> a t = b t) 140 | e_psi e_phi 141 | (\t -> border-is-a-set t (a t) (b t) (e_psi t) (e_phi t)) -------------------------------------------------------------------------------- /rzk-playground/rzk-lezer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rzk-lezer", 3 | "version": "0.1.0", 4 | "type": "module", 5 | "module": "dist/index.js", 6 | "devDependencies": { 7 | "@lezer-unofficial/printer": "^1.0.1", 8 | "@lezer/generator": "1.7.0", 9 | "@types/node": "^20.12.2", 10 | "tsx": "^4.7.0", 11 | "typescript": "5.4.3" 12 | }, 13 | "dependencies": { 14 | "@lezer/lr": "^1.4.0" 15 | }, 16 | "files": [ 17 | "examples" 18 | ], 19 | "scripts": { 20 | "prepare": "npm run build; npm run tsc", 21 | "build": "lezer-generator src/rzk.grammar -o src/parser.ts --typeScript", 22 | "examples": "tsx src/run-examples.ts", 23 | "tsc": "tsc -p tsconfig.json" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rzk-playground/rzk-lezer/src/run-examples.ts: -------------------------------------------------------------------------------- 1 | import { parser } from "./parser" 2 | import { printTree } from "@lezer-unofficial/printer" 3 | import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync } from "fs" 4 | 5 | const src = "examples/src" 6 | const exampleNames: string[] = readdirSync(src) 7 | 8 | const tree = "examples/tree" 9 | if (!existsSync(tree)) mkdirSync(tree, { recursive: true }) 10 | 11 | exampleNames.map(name => { 12 | const doc = readFileSync(`${src}/${name}`).toString() 13 | writeFileSync(`${tree}/${name}`, printTree(parser.parse(doc), doc)) 14 | }) -------------------------------------------------------------------------------- /rzk-playground/rzk-lezer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext" 5 | ], 6 | "noImplicitReturns": true, 7 | "noUnusedLocals": true, 8 | "strict": true, 9 | "target": "ESNext", 10 | "module": "ESNext", 11 | "newLine": "lf", 12 | "preserveConstEnums": true, 13 | "stripInternal": true, 14 | "moduleResolution": "node", 15 | "outDir": "dist", 16 | "declaration": true 17 | }, 18 | "include": [ 19 | "src" 20 | ] 21 | } -------------------------------------------------------------------------------- /rzk-playground/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useState } from 'react'; 2 | import { Editor } from './editor/Editor'; 3 | import { Resizable } from 're-resizable'; 4 | import * as rzk from './rzk'; 5 | import { KeyBindProvider, ShortcutType } from 'react-keybinds'; 6 | 7 | declare let window: Window & typeof globalThis & { 8 | rzkTypecheck_: (input: { input: string }) => void 9 | }; 10 | 11 | function Root({ typecheckedOnStartState }: 12 | { 13 | typecheckedOnStartState: [boolean, React.Dispatch>] 14 | }) { 15 | const [typecheckedOnStart, setTypecheckedOnStart] = typecheckedOnStartState 16 | const [windowHeight, setWindowHeight] = useState(window.innerHeight) 17 | 18 | useEffect(() => { 19 | const handleWindowResize = () => { 20 | setWindowHeight(window.innerHeight) 21 | }; 22 | 23 | window.addEventListener('resize', handleWindowResize); 24 | 25 | return () => { 26 | window.removeEventListener('resize', handleWindowResize); 27 | }; 28 | }, []); 29 | 30 | const [text, setText] = useState("") 31 | 32 | const [output, setOutput] = useState("Starting..."); 33 | 34 | const typecheck = useCallback(() => { 35 | const result = rzk.typecheck(text) 36 | if (result.status == 'ok') { 37 | setOutput(`Everything is OK!`) 38 | } else { 39 | setOutput(result.result) 40 | } 41 | }, [text]) 42 | 43 | const [rzkTypeCheckAvailable, setRzkTypeCheckAvailable] = useState(false) 44 | 45 | useEffect(() => { 46 | function checkRzkTypecheckAvailable() { 47 | if (!window.rzkTypecheck_) { 48 | window.setTimeout(checkRzkTypecheckAvailable, 100) 49 | } else { 50 | setRzkTypeCheckAvailable(true) 51 | } 52 | } 53 | 54 | checkRzkTypecheckAvailable() 55 | }, [text]) 56 | 57 | // Typecheck when function and text are ready 58 | useEffect(() => { 59 | function checkFlag() { 60 | if (!typecheckedOnStart && (!rzkTypeCheckAvailable || text === '')) { 61 | console.warn("Can't typecheck!") 62 | } else if (!typecheckedOnStart) { 63 | typecheck() 64 | setTypecheckedOnStart(true) 65 | } 66 | } 67 | 68 | if (!typecheckedOnStart) { 69 | checkFlag(); 70 | } 71 | }, [typecheck, rzkTypeCheckAvailable, text, setTypecheckedOnStart, typecheckedOnStart]) 72 | 73 | const [needTypecheck, setNeedTypecheck] = useState(false) 74 | 75 | useEffect(() => { 76 | if (needTypecheck) { 77 | typecheck() 78 | setNeedTypecheck(false) 79 | } 80 | }, [setNeedTypecheck, needTypecheck, typecheck]) 81 | 82 | const KEYBINDINGS: ShortcutType[] = 83 | [ 84 | { 85 | keys: { 86 | Mac: ['Shift', 'Enter'], 87 | Windows: ['Shift', 'Enter'], 88 | Linux: ['Shift', 'Enter'], 89 | }, 90 | label: 'Test command', 91 | callback: () => { 92 | setNeedTypecheck(true) 93 | }, 94 | }, 95 | ] 96 | ; 97 | 98 | 99 | // height of the output panel 100 | const [outputPanelHeight, setOutputHeight] = useState(windowHeight * 30 / 100) 101 | 102 | // visible height of the editor 103 | const [editorHeight, setEditorHeight] = useState(windowHeight * 70 / 100) 104 | 105 | const 106 | minHeight = 100, 107 | maxHeight = windowHeight - 100, 108 | width = '100vw', 109 | height = '100vh', 110 | backgroundColor = '#202028' 111 | 112 | return ( 113 |
114 |
115 | 116 |
117 | 122 |
123 |
131 | { 137 | setOutputHeight(outputPanelHeight + delta.height) 138 | }} 139 | onResize={(_event, _direction, _elementRef, delta) => { 140 | setEditorHeight(window.innerHeight - (outputPanelHeight + delta.height)) 141 | }} 142 | style={{ padding: '20px' }} 143 | > 144 | 147 |
{output}
148 |
149 |
150 |
151 |
152 | ) 153 | } 154 | 155 | 156 | function App() { 157 | return 158 | } 159 | 160 | export default App -------------------------------------------------------------------------------- /rzk-playground/src/editor/Editor.tsx: -------------------------------------------------------------------------------- 1 | import CodeMirror from '@uiw/react-codemirror'; 2 | import { EditorView, keymap } from '@codemirror/view' 3 | import { scrollPastEnd } from '@codemirror/view'; 4 | import { example } from './example'; 5 | import { color, oneDark } from './theme'; 6 | import { Dispatch, SetStateAction, useState } from 'react'; 7 | import { centerCursor } from './cursor-height'; 8 | import { language } from './parser'; 9 | 10 | async function setInitialText(setText: Dispatch>) { 11 | const params = new URLSearchParams(window.location.search); 12 | if (params.has("snippet")) { 13 | setText(params.get("snippet")!); 14 | } else if (params.has("code")) { 15 | setText(params.get("code")!); 16 | } else if (params.has("snippet_url")) { 17 | const url = params.get("snippet_url")!; 18 | const response = await fetch(url, { 19 | method: 'GET', 20 | headers: { 21 | Accept: 'text/plain;charset=UTF-8' 22 | } 23 | }) 24 | 25 | if (!response.ok) { 26 | console.error(`Could not get code from ${url}`) 27 | } 28 | 29 | setText(await response.text()) 30 | } 31 | else { 32 | setText(example) 33 | } 34 | } 35 | 36 | export function Editor({ 37 | textState, 38 | setNeedTypecheck, 39 | editorHeight 40 | }: { 41 | textState: [string, Dispatch>], 42 | setNeedTypecheck: React.Dispatch>, 43 | editorHeight: number 44 | }) { 45 | const [existsSelection, setExistsSelection] = useState(false) 46 | const [text, setText] = textState 47 | 48 | return { 53 | await setInitialText(setText) 54 | 55 | view.dispatch({ effects: EditorView.scrollIntoView(0) }) 56 | }} 57 | onUpdate={(update) => { 58 | if (update.selectionSet) { 59 | const ranges = update.state.selection.ranges.filter(v => { return v.from != v.to }) 60 | setExistsSelection(ranges.length > 0) 61 | } 62 | }} 63 | onChange={(value) => { 64 | setText(value) 65 | }} 66 | theme={oneDark} 67 | extensions={[ 68 | keymap.of([ 69 | { 70 | key: "Shift-Enter", run: () => { 71 | setNeedTypecheck(true) 72 | return true 73 | } 74 | } 75 | ]), 76 | scrollPastEnd(), 77 | centerCursor(editorHeight), 78 | 79 | // dynamic parts of the theme 80 | EditorView.theme({ 81 | "& .cm-scroller": { 82 | maxHeight: `${editorHeight}px !important` 83 | }, 84 | "& .cm-activeLine": { 85 | backgroundColor: `${existsSelection ? "transparent" : color.activeLine} !important` 86 | }, 87 | }), 88 | language 89 | ]} 90 | />; 91 | } 92 | -------------------------------------------------------------------------------- /rzk-playground/src/editor/cursor-height.ts: -------------------------------------------------------------------------------- 1 | import { ViewPlugin, ViewUpdate } from "@uiw/react-codemirror" 2 | 3 | 4 | // https://discuss.codemirror.net/t/cm6-scroll-to-middle/2924/4 5 | export const centerCursor = (editorHeight: number) => ViewPlugin.fromClass(class { 6 | update(update: ViewUpdate) { 7 | if (update.transactions.some(tr => tr.scrollIntoView)) { 8 | const view = update.view 9 | // (Sync with other DOM read/write phases for efficiency) 10 | view.requestMeasure({ 11 | read() { 12 | return { 13 | cursor: view.coordsAtPos(view.state.selection.main.head), 14 | } 15 | }, 16 | write({ cursor }) { 17 | if (cursor) { 18 | const cursorHeight = cursor.bottom - cursor.top 19 | const outputTop = editorHeight 20 | if (cursor.bottom + cursorHeight + 5 > outputTop) 21 | view.scrollDOM.scrollTop += ((cursor.bottom + 5) - outputTop) 22 | } 23 | } 24 | }) 25 | } 26 | } 27 | }) -------------------------------------------------------------------------------- /rzk-playground/src/editor/example.ts: -------------------------------------------------------------------------------- 1 | export const example = `#lang rzk-1 2 | 3 | -- A is contractible there exists x : A such that for any y : A we have x = y. 4 | #def iscontr (A : U) : U 5 | := ∑ (a : A), (x : A) -> a =_{A} x 6 | 7 | -- A is a proposition if for any x, y : A we have x = y 8 | #def isaprop (A : U) : U 9 | := (x : A) -> (y : A) -> x =_{A} y 10 | 11 | -- A is a set if for any x, y : A the type x =_{A} y is a proposition 12 | #def isaset (A : U) : U 13 | := (x : A) -> (y : A) -> isaprop (x =_{A} y) 14 | 15 | -- Non-dependent product of A and B 16 | #def prod (A : U) (B : U) : U 17 | := ∑ (x : A), B 18 | 19 | -- A function f : A -> B is an equivalence 20 | -- if there exists g : B -> A 21 | -- such that for all x : A we have g (f x) = x 22 | -- and for all y : B we have f (g y) = y 23 | #def isweq (A : U) (B : U) (f : A -> B) : U 24 | := ∑ (g : B -> A), prod ((x : A) -> g (f x) =_{A} x) ((y : B) -> f (g y) =_{B} y) 25 | 26 | -- Equivalence of types A and B 27 | #def weq (A : U) (B : U) : U 28 | := ∑ (f : A -> B), isweq A B f 29 | 30 | -- Transport along a path 31 | #def transport 32 | (A : U) 33 | (C : A -> U) 34 | (x y : A) 35 | (p : x =_{A} y) 36 | : C x -> C y 37 | := \\cx -> idJ(A, x, (\\z q -> C z), cx, y, p) 38 | 39 | -- [RS17, Axiom 4.6] Relative function extensionality. 40 | #def relfunext : U 41 | := (I : CUBE) 42 | -> (psi : I -> TOPE) 43 | -> (phi : psi -> TOPE) 44 | -> (A : psi -> U) 45 | -> ((t : psi) -> iscontr (A t)) 46 | -> (a : (t : phi) -> A t) 47 | -> (t : psi) -> A t [ phi t |-> a t] 48 | 49 | -- [RS17, Proposition 4.8] A (weaker) formulation of function extensionality. 50 | #def relfunext2 : U 51 | := (I : CUBE) 52 | -> (psi : I -> TOPE) 53 | -> (phi : psi -> TOPE) 54 | -> (A : psi -> U) 55 | -> (a : (t : phi) -> A t) 56 | -> (f : (t : psi) -> A t [ phi t |-> a t ]) 57 | -> (g : (t : psi) -> A t [ phi t |-> a t ]) 58 | -> weq (f = g) 59 | ((t : psi) -> (f t =_{A t} g t) [ phi t |-> refl ]) 60 | 61 | -- Restrict extension type to a subshape. 62 | #def restrict 63 | (I : CUBE) 64 | (psi : I -> TOPE) 65 | (phi : I -> TOPE) 66 | (A : {t : I | psi t \\/ phi t} -> U) 67 | (a : {t : I | psi t} -> A t) 68 | : {t : I | psi t /\\ phi t} -> A t 69 | := \\t -> a t 70 | 71 | -- Reformulate extension type as an extension of a restriction. 72 | #def ext-of-restrict 73 | (I : CUBE) 74 | (psi : I -> TOPE) 75 | (phi : I -> TOPE) 76 | (A : {t : I | psi t \\/ phi t} -> U) 77 | (a : {t : I | psi t} -> A t) 78 | : (t : psi) -> A t [ psi t /\\ phi t |-> restrict I psi phi A a t ] 79 | := a 80 | 81 | -- Transform extension of an identity into an identity of restrictions. 82 | #def restricts-path 83 | (r : relfunext2) 84 | (I : CUBE) 85 | (psi : I -> TOPE) 86 | (phi : I -> TOPE) 87 | (A : {t : I | psi t \\/ phi t} -> U) 88 | (a_psi : (t : psi) -> A t) 89 | (a_phi : (t : phi) -> A t) 90 | (e : {t : I | psi t /\\ phi t} -> a_psi t = a_phi t) 91 | : restrict I psi phi A a_psi = restrict I phi psi A a_phi 92 | := (first (second (r I 93 | (\\t -> psi t /\\ phi t) 94 | (\\t -> BOT) 95 | (\\t -> A t) 96 | (\\t -> recBOT) 97 | (\\t -> a_psi t) 98 | (\\t -> a_phi t)))) e 99 | 100 | -- A weaker version of recOR, demanding only a path between a and b: 101 | -- recOR(psi, phi, a, b) demands that for psi /\\ phi we have a == b (definitionally) 102 | -- (recId psi phi a b e) demands that e is the proof that a = b (intensionally) for psi /\\ phi 103 | #def recId 104 | (r : relfunext2) 105 | (I : CUBE) 106 | (psi : I -> TOPE) 107 | (phi : I -> TOPE) 108 | (A : {t : I | psi t \\/ phi t} -> U) 109 | (a_psi : (t : psi) -> A t) 110 | (a_phi : (t : phi) -> A t) 111 | (e : {t : I | psi t /\\ phi t} -> a_psi t = a_phi t) 112 | : {t : I | psi t \\/ phi t} -> A t 113 | := \\t -> recOR( 114 | psi t |-> transport 115 | ({t : I | psi t /\\ phi t} -> A t) 116 | (\\ra -> (t : psi) -> A t [ psi t /\\ phi t |-> ra t]) 117 | (restrict I psi phi A a_psi) 118 | (restrict I phi psi A a_phi) 119 | (restricts-path r I psi phi A a_psi a_phi e) 120 | (ext-of-restrict I psi phi A a_psi) 121 | t, 122 | phi t |-> ext-of-restrict I phi psi A a_phi t 123 | ) 124 | 125 | -- If two extension types are equal along two subshapes, 126 | -- then they are also equal along their union. 127 | #def id-along-border 128 | (r : relfunext2) 129 | (I : CUBE) 130 | (psi : I -> TOPE) 131 | (phi : I -> TOPE) 132 | (A : {t : I | psi t \\/ phi t} -> U) 133 | (a b : {t : I | psi t \\/ phi t} -> A t) 134 | (e_psi : (t : psi) -> a t = b t) 135 | (e_phi : (t : phi) -> a t = b t) 136 | (border-is-a-set : {t : I | psi t /\\ phi t} -> isaset (A t)) 137 | : {t : I | psi t \\/ phi t} -> a t = b t 138 | := recId r I psi phi 139 | (\\t -> a t = b t) 140 | e_psi e_phi 141 | (\\t -> border-is-a-set t (a t) (b t) (e_psi t) (e_phi t)) 142 | ` -------------------------------------------------------------------------------- /rzk-playground/src/editor/parser.ts: -------------------------------------------------------------------------------- 1 | import { parser } from 'rzk-lezer/src/parser' 2 | import { styleTags, tags as t } from '@lezer/highlight' 3 | import { LRLanguage } from '@codemirror/language' 4 | 5 | const parserWithMetadata = parser.configure({ 6 | props: [ 7 | styleTags({ 8 | "LineComment!": t.lineComment, 9 | "BlockComment!": t.blockComment, 10 | "String!": t.string, 11 | "#lang": t.moduleKeyword, 12 | "Rzk1!": t.namespace, 13 | "#assume #check #compute-nf \ 14 | #compute-whnf #compute #def #define \ 15 | #end #postulate #section #set-option \ 16 | #unset-option #variable #variables": t.definitionKeyword, 17 | "→ ↦ ∑ × < <= -> =_{ = === > |-> | ∧ ∨ ≡ ≤": t.operatorKeyword, 18 | ":": t.definitionOperator, 19 | "π₁ π₂ Σ ⊤ ⊥ 0_2 0₂ 1_2 1 1₂ 2 \ 20 | as BOT Cube first idJ recBot recOR \ 21 | refl_{ refl second Sigma TOP \ 22 | TOPE U unit Unit uses": t.keyword, 23 | "{ }": t.brace, 24 | "( )": t.paren, 25 | VarIdent: t.variableName 26 | }) 27 | ] 28 | }) 29 | 30 | export const language = LRLanguage.define({ 31 | parser: parserWithMetadata 32 | }) -------------------------------------------------------------------------------- /rzk-playground/src/index.css: -------------------------------------------------------------------------------- 1 | section { 2 | width: 100%; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | background-color: #000; 8 | } 9 | 10 | .row { 11 | display: flex; 12 | justify-content: space-evenly; 13 | margin: 0; 14 | padding: 0; 15 | width: 100%; 16 | } 17 | 18 | .column { 19 | margin-top: 0; 20 | margin-bottom: 0; 21 | width: 100%; 22 | } 23 | 24 | /* CSS for response button from https://getcssscan.com/css-buttons-examples (button 61) */ 25 | #btnTypecheck { 26 | align-items: center; 27 | appearance: none; 28 | border-radius: 4px; 29 | border-style: none; 30 | box-shadow: rgba(0, 0, 0, .2) 0 3px 1px -2px, rgba(0, 0, 0, .14) 0 2px 2px 0, rgba(0, 0, 0, .12) 0 1px 5px 0; 31 | box-sizing: border-box; 32 | color: #fff; 33 | cursor: pointer; 34 | display: inline-flex; 35 | font-family: Roboto, sans-serif; 36 | font-size: .875rem; 37 | font-weight: 500; 38 | height: 36px; 39 | justify-content: center; 40 | letter-spacing: .0892857em; 41 | line-height: normal; 42 | min-width: 64px; 43 | outline: none; 44 | overflow: visible; 45 | padding: 0 16px; 46 | position: relative; 47 | text-align: center; 48 | text-decoration: none; 49 | text-transform: uppercase; 50 | transition: box-shadow 280ms cubic-bezier(.4, 0, .2, 1); 51 | user-select: none; 52 | -webkit-user-select: none; 53 | touch-action: manipulation; 54 | vertical-align: middle; 55 | will-change: transform, opacity; 56 | } 57 | 58 | #btnTypecheck:hover { 59 | box-shadow: rgba(0, 0, 0, .2) 0 2px 4px -1px, rgba(0, 0, 0, .14) 0 4px 5px 0, rgba(0, 0, 0, .12) 0 1px 10px 0; 60 | } 61 | 62 | #btnTypecheck:disabled { 63 | background-color: rgba(0, 0, 0, .12); 64 | box-shadow: rgba(0, 0, 0, .2) 0 0 0 0, rgba(0, 0, 0, .14) 0 0 0 0, rgba(0, 0, 0, .12) 0 0 0 0; 65 | color: rgba(0, 0, 0, .37); 66 | cursor: default; 67 | pointer-events: none; 68 | } 69 | 70 | #btnTypecheck:not(:disabled) { 71 | background-color: #6200ee; 72 | } 73 | 74 | #btnTypecheck:focus { 75 | box-shadow: rgba(0, 0, 0, .2) 0 2px 4px -1px, rgba(0, 0, 0, .14) 0 4px 5px 0, rgba(0, 0, 0, .12) 0 1px 10px 0; 76 | } 77 | 78 | #btnTypecheck:active { 79 | box-shadow: rgba(0, 0, 0, .2) 0 5px 5px -3px, rgba(0, 0, 0, .14) 0 8px 10px 1px, rgba(0, 0, 0, .12) 0 3px 14px 2px; 80 | background: #A46BF5; 81 | } 82 | 83 | #output { 84 | background-color: #1e1f1c; 85 | color: #ffffff; 86 | overflow: scroll; 87 | } 88 | 89 | #output pre { 90 | font-family: Inconsolata, monospace; 91 | } -------------------------------------------------------------------------------- /rzk-playground/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.tsx' 4 | import './index.css' 5 | 6 | ReactDOM.createRoot(document.getElementById('root')!).render( 7 | 8 | 9 | , 10 | ) 11 | -------------------------------------------------------------------------------- /rzk-playground/src/rzk.ts: -------------------------------------------------------------------------------- 1 | export type Result = { status: string, result: string } 2 | 3 | declare function rzkTypecheck_(tmp: { input: string }): void; 4 | 5 | export function typecheck(input: string) { 6 | const tmp = { input } 7 | rzkTypecheck_(tmp) 8 | const result: Result = tmp as unknown as Result 9 | return result 10 | } -------------------------------------------------------------------------------- /rzk-playground/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 6 | "module": "ESNext", 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | "jsx": "react-jsx", 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src", "public/rzk.js"], 24 | "references": [{ "path": "./tsconfig.node.json" }] 25 | } 26 | -------------------------------------------------------------------------------- /rzk-playground/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /rzk-playground/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react-swc' 3 | 4 | const ASSET_URL = process.env.ASSET_URL || '/'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [react()], 9 | base: ASSET_URL 10 | }) 11 | -------------------------------------------------------------------------------- /rzk.yaml: -------------------------------------------------------------------------------- 1 | include: 2 | - docs/docs/en/getting-started/dependent-types.rzk.md 3 | - docs/docs/en/examples/recId.rzk.md 4 | -------------------------------------------------------------------------------- /rzk/.gitignore: -------------------------------------------------------------------------------- 1 | .stack-work/ 2 | *~ 3 | *.bak 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /rzk/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Nikolai Kudasov (c) 2023 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Nikolai Kudasov nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /rzk/Makefile: -------------------------------------------------------------------------------- 1 | syntax: src/Language/Rzk/Syntax/Test 2 | pygments: pygments/setup.py 3 | pdf: doc/Syntax.pdf 4 | 5 | all: syntax pygments pdf 6 | 7 | clean: 8 | cd src && (make --makefile=Language/Rzk/Makefile clean; cd ../) 9 | 10 | src/Language/Rzk/Syntax/Test: src/Language/Rzk/Syntax.cf 11 | cd src/ \ 12 | && bnfc -d Language/Rzk/Syntax.cf -p Language.Rzk --makefile=Language/Rzk/Makefile --generic --functor \ 13 | && make --makefile=Language/Rzk/Makefile \ 14 | && rm Language/Rzk/Syntax/Test.hs ; \ 15 | cd ../ 16 | 17 | pygments/setup.py: src/Language/Rzk/Syntax.cf 18 | bnfc --pygments src/Language/Rzk/Syntax.cf 19 | 20 | doc/Syntax.pdf: doc/Syntax.tex 21 | latexmk -output-directory=doc/ -pdflatex doc/Syntax.tex 22 | 23 | doc/Syntax.tex: src/Language/Rzk/Syntax.cf 24 | bnfc --latex src/Language/Rzk/Syntax.cf -o doc/ 25 | 26 | .PHONY: syntax clean all pygments pdf 27 | -------------------------------------------------------------------------------- /rzk/README.md: -------------------------------------------------------------------------------- 1 | # rzk 2 | 3 | An experimental proof assistant for synthetic ∞-categories. 4 | 5 | See README at https://github.com/rzk-lang/rzk#readme. 6 | -------------------------------------------------------------------------------- /rzk/Setup.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | -- Source: https://github.com/haskell/cabal/issues/6726#issuecomment-918663262 3 | 4 | -- | Custom Setup that runs bnfc to generate the language sub-libraries 5 | -- for the parsers included in Ogma. 6 | module Main (main) where 7 | 8 | import Distribution.Simple (defaultMainWithHooks, 9 | hookedPrograms, postConf, 10 | preBuild, simpleUserHooks) 11 | import Distribution.Simple.Program (Program (..), findProgramVersion, 12 | simpleProgram) 13 | import System.Process (system) 14 | 15 | -- | Run BNFC on the grammar before the actual build step. 16 | -- 17 | -- All options for bnfc are hard-coded here. 18 | main :: IO () 19 | main = defaultMainWithHooks $ simpleUserHooks 20 | { hookedPrograms = [ bnfcProgram ] 21 | , postConf = \args flags packageDesc localBuildInfo -> do 22 | #ifndef mingw32_HOST_OS 23 | _ <- system "bnfc -d -p Language.Rzk --generic --functor -o src/ grammar/Syntax.cf" 24 | #endif 25 | postConf simpleUserHooks args flags packageDesc localBuildInfo 26 | } 27 | 28 | -- | TODO: This should be in Cabal.Distribution.Simple.Program.Builtin. 29 | bnfcProgram :: Program 30 | bnfcProgram = (simpleProgram "bnfc") 31 | { programFindVersion = findProgramVersion "--version" id 32 | } 33 | -------------------------------------------------------------------------------- /rzk/app/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE DeriveAnyClass #-} 3 | {-# LANGUAGE DeriveGeneric #-} 4 | {-# LANGUAGE LambdaCase #-} 5 | {-# LANGUAGE OverloadedStrings #-} 6 | {-# LANGUAGE TupleSections #-} 7 | {-# LANGUAGE NamedFieldPuns #-} 8 | 9 | module Main (main) where 10 | 11 | #ifndef __GHCJS__ 12 | import Main.Utf8 (withUtf8) 13 | #endif 14 | 15 | import Control.Monad (forM, forM_, unless, when, 16 | (>=>)) 17 | import Data.Version (showVersion) 18 | 19 | #ifdef LSP_ENABLED 20 | import Language.Rzk.VSCode.Lsp (runLsp) 21 | #endif 22 | 23 | import Options.Generic 24 | import System.Exit (exitFailure, exitSuccess) 25 | 26 | import Data.Functor (void, (<&>)) 27 | import Paths_rzk (version) 28 | import Rzk.Format (formatFile, formatFileWrite, 29 | isWellFormattedFile) 30 | import Rzk.TypeCheck 31 | import Rzk.Main 32 | 33 | data FormatOptions = FormatOptions 34 | { check :: Bool 35 | , write :: Bool 36 | } deriving (Generic, Show, ParseRecord, Read, ParseField) 37 | 38 | instance ParseFields FormatOptions where 39 | parseFields _ _ _ _ = FormatOptions 40 | <$> parseFields (Just "Check if the files are correctly formatted") (Just "check") (Just 'c') Nothing 41 | <*> parseFields (Just "Write formatted file to disk") (Just "write") (Just 'w') Nothing 42 | 43 | data Command 44 | = Typecheck [FilePath] 45 | | Lsp 46 | | Format FormatOptions [FilePath] 47 | | Version 48 | deriving (Generic, Show, ParseRecord) 49 | 50 | main :: IO () 51 | main = do 52 | #ifndef __GHCJS__ 53 | withUtf8 $ 54 | #endif 55 | getRecord "rzk: an experimental proof assistant for synthetic ∞-categories" >>= \case 56 | Typecheck paths -> do 57 | modules <- parseRzkFilesOrStdin paths 58 | case defaultTypeCheck (typecheckModulesWithLocation modules) of 59 | Left err -> do 60 | putStrLn "An error occurred when typechecking!" 61 | putStrLn $ unlines 62 | [ "Type Error:" 63 | , ppTypeErrorInScopedContext' BottomUp err 64 | ] 65 | exitFailure 66 | Right _decls -> putStrLn "Everything is ok!" 67 | 68 | Lsp -> 69 | #ifdef LSP_ENABLED 70 | void runLsp 71 | #else 72 | error "rzk lsp is not supported with this build" 73 | #endif 74 | 75 | Format (FormatOptions {check, write}) paths -> do 76 | when (check && write) (error "Options --check and --write are mutually exclusive") 77 | expandedPaths <- expandRzkPathsOrYaml paths 78 | case expandedPaths of 79 | [] -> error "No files found" 80 | filePaths -> do 81 | when (not check && not write) $ forM_ filePaths (formatFile >=> putStrLn) 82 | when write $ forM_ filePaths formatFileWrite 83 | when check $ do 84 | results <- forM filePaths $ \path -> isWellFormattedFile path <&> (path,) 85 | let notFormatted = map fst $ filter (not . snd) results 86 | unless (null notFormatted) $ do 87 | putStrLn "Some files are not well formatted:" 88 | forM_ notFormatted $ \path -> putStrLn (" " <> path) 89 | exitFailure 90 | exitSuccess 91 | 92 | Version -> putStrLn (showVersion version) 93 | -------------------------------------------------------------------------------- /rzk/package.yaml: -------------------------------------------------------------------------------- 1 | name: rzk 2 | version: 0.7.5 3 | github: "rzk-lang/rzk" 4 | license: BSD3 5 | author: "Nikolai Kudasov" 6 | maintainer: "nickolay.kudasov@gmail.com" 7 | copyright: "2023-2024 Nikolai Kudasov" 8 | 9 | extra-source-files: 10 | - README.md 11 | - ChangeLog.md 12 | - grammar/Syntax.cf 13 | 14 | synopsis: An experimental proof assistant for synthetic ∞-categories 15 | category: Dependent Types # same as Agda 16 | 17 | # To avoid duplicated efforts in documentation and dealing with the 18 | # complications of embedding Haddock markup inside cabal files, it is 19 | # common to point users to the README.md file. 20 | description: Please see the README on GitHub at 21 | 22 | flags: 23 | lsp: 24 | description: >- 25 | Build with LSP support (only available with GHC, not GHCJS). 26 | manual: true 27 | default: true 28 | 29 | when: 30 | - condition: flag(lsp) && !impl(ghcjs) 31 | cpp-options: -DLSP_ENABLED 32 | 33 | custom-setup: 34 | dependencies: 35 | base: ">= 4.11.0.0 && < 5.0" 36 | Cabal: ">= 2.4.0.1 && < 4.0" 37 | process: ">= 1.6.3.0" 38 | 39 | build-tools: 40 | alex: ">= 3.2.4" 41 | happy: ">= 1.19.9" 42 | BNFC:bnfc: ">= 2.9.4.1" 43 | 44 | dependencies: 45 | array: ">= 0.5.3.0" 46 | base: ">= 4.7 && < 5" 47 | bifunctors: ">= 5.5.3" 48 | bytestring: ">= 0.10.8.2" 49 | directory: ">= 1.2.7.0" 50 | Glob: ">= 0.9.3" 51 | mtl: ">= 2.2.2" 52 | template-haskell: ">= 2.14.0.0" 53 | text: ">= 1.2.3.1" 54 | yaml: ">= 0.11.0.0" 55 | 56 | ghc-options: 57 | - -Wall 58 | - -Wcompat 59 | - -Widentities 60 | - -Wincomplete-record-updates 61 | - -Wincomplete-uni-patterns 62 | # - -Wmissing-export-lists 63 | - -Wmissing-home-modules 64 | - -Wpartial-fields 65 | - -Wredundant-constraints 66 | - -optP-Wno-nonportable-include-path 67 | 68 | library: 69 | source-dirs: src 70 | when: 71 | - condition: false 72 | other-modules: 73 | - Language.Rzk.Syntax.Test 74 | - Language.Rzk.Syntax.ErrM 75 | - Language.Rzk.Syntax.Skel 76 | - condition: flag(lsp) && !impl(ghcjs) 77 | exposed-modules: 78 | - Language.Rzk.VSCode.Config 79 | - Language.Rzk.VSCode.Env 80 | - Language.Rzk.VSCode.Handlers 81 | - Language.Rzk.VSCode.Logging 82 | - Language.Rzk.VSCode.Lsp 83 | - Language.Rzk.VSCode.Tokenize 84 | dependencies: 85 | aeson: ">= 1.4.2.0" 86 | co-log-core: ">= 0.3.2.0" 87 | data-default-class: ">= 0.1.2.0" 88 | filepath: ">= 1.4.2.1" 89 | lens: ">= 4.17" 90 | lsp: ">= 2.2.0.0" 91 | lsp-types: ">= 2.0.2.0" 92 | stm: ">= 2.5.0.0" 93 | 94 | executables: 95 | rzk: 96 | main: Main.hs 97 | source-dirs: app 98 | ghc-options: 99 | - -threaded 100 | - -rtsopts 101 | - -with-rtsopts=-N 102 | dependencies: 103 | - rzk 104 | when: 105 | - condition: "!impl(ghcjs)" 106 | dependencies: 107 | with-utf8: ">= 1.0.2.4" 108 | optparse-generic: ">= 1.4.0" 109 | 110 | tests: 111 | rzk-test: 112 | main: Spec.hs 113 | source-dirs: test 114 | ghc-options: 115 | - -threaded 116 | - -rtsopts 117 | - -with-rtsopts=-N 118 | dependencies: 119 | - rzk 120 | - hspec 121 | - hspec-discover 122 | 123 | doctests: 124 | source-dirs: test 125 | main: doctests.hs 126 | other-modules: [] 127 | dependencies: 128 | - base 129 | - doctest 130 | - Glob 131 | - QuickCheck 132 | - template-haskell 133 | -------------------------------------------------------------------------------- /rzk/rzk.cabal: -------------------------------------------------------------------------------- 1 | cabal-version: 1.24 2 | 3 | -- This file has been generated from package.yaml by hpack version 0.36.0. 4 | -- 5 | -- see: https://github.com/sol/hpack 6 | 7 | name: rzk 8 | version: 0.7.5 9 | synopsis: An experimental proof assistant for synthetic ∞-categories 10 | description: Please see the README on GitHub at 11 | category: Dependent Types 12 | homepage: https://github.com/rzk-lang/rzk#readme 13 | bug-reports: https://github.com/rzk-lang/rzk/issues 14 | author: Nikolai Kudasov 15 | maintainer: nickolay.kudasov@gmail.com 16 | copyright: 2023-2024 Nikolai Kudasov 17 | license: BSD3 18 | license-file: LICENSE 19 | build-type: Custom 20 | extra-source-files: 21 | README.md 22 | ChangeLog.md 23 | grammar/Syntax.cf 24 | 25 | source-repository head 26 | type: git 27 | location: https://github.com/rzk-lang/rzk 28 | 29 | custom-setup 30 | setup-depends: 31 | Cabal >=2.4.0.1 && <4.0 32 | , base >=4.11.0.0 && <5.0 33 | , process >=1.6.3.0 34 | 35 | flag lsp 36 | description: Build with LSP support (only available with GHC, not GHCJS). 37 | manual: True 38 | default: True 39 | 40 | library 41 | exposed-modules: 42 | Free.Scoped 43 | Free.Scoped.TH 44 | Language.Rzk.Free.Syntax 45 | Language.Rzk.Syntax 46 | Language.Rzk.Syntax.Abs 47 | Language.Rzk.Syntax.Layout 48 | Language.Rzk.Syntax.Lex 49 | Language.Rzk.Syntax.Par 50 | Language.Rzk.Syntax.Print 51 | Rzk 52 | Rzk.Format 53 | Rzk.Main 54 | Rzk.Project.Config 55 | Rzk.TypeCheck 56 | other-modules: 57 | Paths_rzk 58 | hs-source-dirs: 59 | src 60 | ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -optP-Wno-nonportable-include-path 61 | build-tools: 62 | alex >=3.2.4 63 | , happy >=1.19.9 64 | build-tool-depends: 65 | BNFC:bnfc >=2.9.4.1 66 | build-depends: 67 | Glob >=0.9.3 68 | , array >=0.5.3.0 69 | , base >=4.7 && <5 70 | , bifunctors >=5.5.3 71 | , bytestring >=0.10.8.2 72 | , directory >=1.2.7.0 73 | , mtl >=2.2.2 74 | , template-haskell >=2.14.0.0 75 | , text >=1.2.3.1 76 | , yaml >=0.11.0.0 77 | default-language: Haskell2010 78 | if flag(lsp) && !impl(ghcjs) 79 | cpp-options: -DLSP_ENABLED 80 | if flag(lsp) && !impl(ghcjs) 81 | exposed-modules: 82 | Language.Rzk.VSCode.Config 83 | Language.Rzk.VSCode.Env 84 | Language.Rzk.VSCode.Handlers 85 | Language.Rzk.VSCode.Logging 86 | Language.Rzk.VSCode.Lsp 87 | Language.Rzk.VSCode.Tokenize 88 | build-depends: 89 | aeson >=1.4.2.0 90 | , co-log-core >=0.3.2.0 91 | , data-default-class >=0.1.2.0 92 | , filepath >=1.4.2.1 93 | , lens >=4.17 94 | , lsp >=2.2.0.0 95 | , lsp-types >=2.0.2.0 96 | , stm >=2.5.0.0 97 | 98 | executable rzk 99 | main-is: Main.hs 100 | other-modules: 101 | Paths_rzk 102 | hs-source-dirs: 103 | app 104 | ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -optP-Wno-nonportable-include-path -threaded -rtsopts -with-rtsopts=-N 105 | build-tools: 106 | alex >=3.2.4 107 | , happy >=1.19.9 108 | build-tool-depends: 109 | BNFC:bnfc >=2.9.4.1 110 | build-depends: 111 | Glob >=0.9.3 112 | , array >=0.5.3.0 113 | , base >=4.7 && <5 114 | , bifunctors >=5.5.3 115 | , bytestring >=0.10.8.2 116 | , directory >=1.2.7.0 117 | , mtl >=2.2.2 118 | , rzk 119 | , template-haskell >=2.14.0.0 120 | , text >=1.2.3.1 121 | , yaml >=0.11.0.0 122 | default-language: Haskell2010 123 | if flag(lsp) && !impl(ghcjs) 124 | cpp-options: -DLSP_ENABLED 125 | if !impl(ghcjs) 126 | build-depends: 127 | optparse-generic >=1.4.0 128 | , with-utf8 >=1.0.2.4 129 | 130 | test-suite doctests 131 | type: exitcode-stdio-1.0 132 | main-is: doctests.hs 133 | hs-source-dirs: 134 | test 135 | ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -optP-Wno-nonportable-include-path 136 | build-tools: 137 | alex >=3.2.4 138 | , happy >=1.19.9 139 | build-tool-depends: 140 | BNFC:bnfc >=2.9.4.1 141 | build-depends: 142 | Glob 143 | , QuickCheck 144 | , array >=0.5.3.0 145 | , base 146 | , bifunctors >=5.5.3 147 | , bytestring >=0.10.8.2 148 | , directory >=1.2.7.0 149 | , doctest 150 | , mtl >=2.2.2 151 | , template-haskell 152 | , text >=1.2.3.1 153 | , yaml >=0.11.0.0 154 | default-language: Haskell2010 155 | if flag(lsp) && !impl(ghcjs) 156 | cpp-options: -DLSP_ENABLED 157 | 158 | test-suite rzk-test 159 | type: exitcode-stdio-1.0 160 | main-is: Spec.hs 161 | other-modules: 162 | Rzk.FormatSpec 163 | Paths_rzk 164 | hs-source-dirs: 165 | test 166 | ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -optP-Wno-nonportable-include-path -threaded -rtsopts -with-rtsopts=-N 167 | build-tools: 168 | alex >=3.2.4 169 | , happy >=1.19.9 170 | build-tool-depends: 171 | BNFC:bnfc >=2.9.4.1 172 | build-depends: 173 | Glob >=0.9.3 174 | , array >=0.5.3.0 175 | , base >=4.7 && <5 176 | , bifunctors >=5.5.3 177 | , bytestring >=0.10.8.2 178 | , directory >=1.2.7.0 179 | , hspec 180 | , hspec-discover 181 | , mtl >=2.2.2 182 | , rzk 183 | , template-haskell >=2.14.0.0 184 | , text >=1.2.3.1 185 | , yaml >=0.11.0.0 186 | default-language: Haskell2010 187 | if flag(lsp) && !impl(ghcjs) 188 | cpp-options: -DLSP_ENABLED 189 | -------------------------------------------------------------------------------- /rzk/src/Free/Scoped.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DeriveFoldable #-} 2 | {-# LANGUAGE DeriveFunctor #-} 3 | {-# LANGUAGE DeriveGeneric #-} 4 | {-# LANGUAGE DeriveTraversable #-} 5 | {-# LANGUAGE LambdaCase #-} 6 | {-# LANGUAGE PatternSynonyms #-} 7 | {-# LANGUAGE QuantifiedConstraints #-} 8 | {-# LANGUAGE RankNTypes #-} 9 | {-# LANGUAGE StandaloneDeriving #-} 10 | {-# LANGUAGE TemplateHaskell #-} 11 | {-# LANGUAGE TypeOperators #-} 12 | {-# LANGUAGE UndecidableInstances #-} 13 | module Free.Scoped where 14 | 15 | import Control.Monad (ap) 16 | import Data.Bifoldable 17 | import Data.Bifunctor 18 | import Data.Bifunctor.TH 19 | import Data.Bitraversable 20 | import Data.Function (on) 21 | import qualified GHC.Generics as GHC 22 | 23 | data Inc var = Z | S var 24 | deriving (Eq, Show, Functor, Foldable, Traversable) 25 | 26 | type Scope term var = term (Inc var) 27 | 28 | instantiate :: Monad f => f a -> f (Inc a) -> f a 29 | instantiate e f = f >>= g 30 | where 31 | g Z = e 32 | g (S x) = return x 33 | 34 | abstract :: (Eq a, Functor f) => a -> f a -> f (Inc a) 35 | abstract x e = k <$> e 36 | where 37 | k y | x == y = Z 38 | | otherwise = S y 39 | 40 | data FS t a 41 | = Pure a 42 | | Free (t (Scope (FS t) a) (FS t a)) 43 | 44 | deriving instance (Eq a, forall x y. (Eq x, Eq y) => Eq (t x y)) => Eq (FS t a) 45 | 46 | instance Bifunctor t => Functor (FS t) where 47 | fmap f (Pure x) = Pure (f x) 48 | fmap f (Free t) = Free 49 | (bimap (fmap (fmap f)) (fmap f) t) 50 | 51 | instance Bifoldable t => Foldable (FS t) where 52 | foldMap f (Pure x) = f x 53 | foldMap f (Free t) = bifoldMap (foldMap (foldMap f)) (foldMap f) t 54 | 55 | instance Bitraversable t => Traversable (FS t) where 56 | traverse f (Pure x) = Pure <$> f x 57 | traverse f (Free t) = Free <$> 58 | bitraverse (traverse (traverse f)) (traverse f) t 59 | 60 | instance Bifunctor t => Applicative (FS t) where 61 | pure = Pure 62 | (<*>) = ap 63 | 64 | instance Bifunctor t => Monad (FS t) where 65 | return = pure 66 | Pure x >>= f = f x 67 | Free t >>= f = Free 68 | (bimap ((>>= traverse f)) (>>= f) t) 69 | 70 | data Sum f g scope term 71 | = InL (f scope term) 72 | | InR (g scope term) 73 | deriving (Functor, Foldable, Traversable, GHC.Generic) 74 | deriveBifunctor ''Sum 75 | deriveBifoldable ''Sum 76 | deriveBitraversable ''Sum 77 | 78 | type (:+:) = Sum 79 | 80 | data Empty scope term 81 | deriving (Functor, Foldable, Traversable) 82 | deriveBifunctor ''Empty 83 | deriveBifoldable ''Empty 84 | deriveBitraversable ''Empty 85 | 86 | data AnnF ann term scope typedTerm = AnnF 87 | { annF :: ann typedTerm 88 | , termF :: term scope typedTerm 89 | } deriving (Show, Functor) 90 | 91 | -- | Important: does not compare the `annF` component! 92 | instance Eq (term scope typedTerm) => Eq (AnnF ann term scope typedTerm) where 93 | (==) = (==) `on` termF 94 | 95 | instance (Functor ann, Bifunctor term) => Bifunctor (AnnF ann term) where 96 | bimap f g (AnnF t x) = AnnF (fmap g t) (bimap f g x) 97 | 98 | -- | Important: does not fold over the 'annF' component! 99 | instance Bifoldable term => Bifoldable (AnnF ann term) where 100 | bifoldMap f g (AnnF _ty x) = {- g ty <> -} bifoldMap f g x 101 | 102 | instance (Traversable ann, Bitraversable term) => Bitraversable (AnnF ann term) where 103 | bitraverse f g (AnnF t x) = AnnF <$> traverse g t <*> bitraverse f g x 104 | 105 | transFS 106 | :: (Bifunctor term) 107 | => (forall s t. term s t -> term' s t) 108 | -> FS term a -> FS term' a 109 | transFS phi = \case 110 | Pure x -> Pure x 111 | Free t -> Free (phi (bimap (transFS phi) (transFS phi) t)) 112 | 113 | untyped :: (Functor ann, Bifunctor term) => FS (AnnF ann term) a -> FS term a 114 | untyped = transFS termF 115 | 116 | pattern ExtE :: ext (Scope (FS (t :+: ext)) a) (FS (t :+: ext) a) -> FS (t :+: ext) a 117 | pattern ExtE t = Free (InR t) 118 | 119 | substitute :: Bifunctor t => FS t a -> Scope (FS t) a -> FS t a 120 | substitute t = (>>= f) 121 | where 122 | f Z = t 123 | f (S y) = Pure y 124 | -------------------------------------------------------------------------------- /rzk/src/Free/Scoped/TH.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE CPP #-} 2 | {-# LANGUAGE LambdaCase #-} 3 | {-# LANGUAGE TemplateHaskell #-} 4 | module Free.Scoped.TH where 5 | 6 | import Control.Monad (replicateM) 7 | import Free.Scoped 8 | import Language.Haskell.TH 9 | 10 | mkConP :: Name -> [Pat] -> Pat 11 | #if __GLASGOW_HASKELL__ >= 902 12 | mkConP name pats = ConP name [] pats 13 | #else 14 | mkConP name pats = ConP name pats 15 | #endif 16 | 17 | makePatternsAll :: Name -> Q [Dec] 18 | makePatternsAll ty = do 19 | TyConI tyCon <- reify ty 20 | case tyCon of 21 | DataD _ _ _ _ cs _ -> concat <$> do 22 | xs <- mapM makePatternFor cs 23 | xs' <- makeCompletePragma cs 24 | ys <- mapM makePatternEFor cs 25 | ys' <- makeCompletePragmaE cs 26 | zs <- mapM makePatternTFor cs 27 | zs' <- makeCompletePragmaT cs 28 | ws <- mapM makePatternTEFor cs 29 | ws' <- makeCompletePragmaTE cs 30 | return (xs ++ [xs'] ++ ys ++ [ys'] ++ zs ++ [zs'] ++ ws ++ [ws']) 31 | 32 | _ -> fail "Can only make patterns for data types." 33 | 34 | 35 | makeCompletePragma :: [Con] -> Q [Dec] 36 | makeCompletePragma cs = do 37 | DataConI varName _ _ <- reify 'Pure 38 | let names = [mkName (removeF (nameBase name)) | NormalC name _ <- cs] 39 | return [PragmaD (CompleteP (varName : names) Nothing)] 40 | where 41 | removeF s = take (length s - 1) s 42 | 43 | makeCompletePragmaE :: [Con] -> Q [Dec] 44 | makeCompletePragmaE cs = do 45 | DataConI varName _ _ <- reify 'Pure 46 | PatSynI extName _ <- reify 'ExtE 47 | let names = [mkName (removeF (nameBase name)) | NormalC name _ <- cs] 48 | return [PragmaD (CompleteP (varName : extName : names) Nothing)] 49 | where 50 | removeF s = take (length s - 1) s <> "E" 51 | 52 | makeCompletePragmaT :: [Con] -> Q [Dec] 53 | makeCompletePragmaT cs = do 54 | DataConI varName _ _ <- reify 'Pure 55 | let names = [mkName (removeF (nameBase name)) | NormalC name _ <- cs] 56 | return [PragmaD (CompleteP (varName : names) Nothing)] 57 | where 58 | removeF s = take (length s - 1) s <> "T" 59 | 60 | makeCompletePragmaTE :: [Con] -> Q [Dec] 61 | makeCompletePragmaTE cs = do 62 | DataConI varName _ _ <- reify 'Pure 63 | let names = [mkName (removeF (nameBase name)) | NormalC name _ <- cs] 64 | return [PragmaD (CompleteP (varName : names) Nothing)] 65 | where 66 | removeF s = take (length s - 1) s <> "TE" 67 | 68 | makePatternFor :: Con -> Q [Dec] 69 | makePatternFor = \case 70 | NormalC name xs -> do 71 | args <- replicateM (length xs) (newName "x") 72 | let patName = mkName (removeF (nameBase name)) 73 | patArgs = PrefixPatSyn args 74 | dir = ImplBidir 75 | pat <- [p| Free $(pure (mkConP name (VarP <$> args))) |] 76 | return [PatSynD patName patArgs dir pat] 77 | _ -> fail "Can only make patterns for NormalC constructors" 78 | where 79 | removeF s = take (length s - 1) s 80 | 81 | makePatternEFor :: Con -> Q [Dec] 82 | makePatternEFor = \case 83 | NormalC name xs -> do 84 | args <- replicateM (length xs) (newName "x") 85 | let patName = mkName (removeF (nameBase name)) 86 | patArgs = PrefixPatSyn args 87 | dir = ImplBidir 88 | pat <- [p| Free (InL $(pure (mkConP name (VarP <$> args)))) |] 89 | return [PatSynD patName patArgs dir pat] 90 | _ -> fail "Can only make patterns for NormalC constructors" 91 | where 92 | removeF s = take (length s - 1) s <> "E" 93 | 94 | makePatternTFor :: Con -> Q [Dec] 95 | makePatternTFor = \case 96 | NormalC name xs -> do 97 | t <- newName "type_" 98 | args <- replicateM (length xs) (newName "x") 99 | let patName = mkName (removeF (nameBase name)) 100 | patArgs = PrefixPatSyn (t : args) 101 | dir = ImplBidir 102 | pat <- [p| Free (AnnF $(pure (VarP t)) $(pure (mkConP name (VarP <$> args)))) |] 103 | return [PatSynD patName patArgs dir pat] 104 | _ -> fail "Can only make patterns for NormalC constructors" 105 | where 106 | removeF s = take (length s - 1) s <> "T" 107 | 108 | makePatternTEFor :: Con -> Q [Dec] 109 | makePatternTEFor = \case 110 | NormalC name xs -> do 111 | t <- newName "type_" 112 | args <- replicateM (length xs) (newName "x") 113 | let patName = mkName (removeF (nameBase name)) 114 | patArgs = PrefixPatSyn (t : args) 115 | dir = ImplBidir 116 | pat <- [p| Free (InL (AnnF $(pure (VarP t)) $(pure (mkConP name (VarP <$> args))))) |] 117 | return [PatSynD patName patArgs dir pat] 118 | _ -> fail "Can only make patterns for NormalC constructors" 119 | where 120 | removeF s = take (length s - 1) s <> "TE" 121 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/Makefile: -------------------------------------------------------------------------------- 1 | ## File generated by the BNF Converter (bnfc 2.9.4.1). 2 | 3 | # Makefile for building the parser and test program. 4 | 5 | GHC = ghc 6 | HAPPY = happy 7 | HAPPY_OPTS = --array --info --ghc --coerce 8 | ALEX = alex 9 | ALEX_OPTS = --ghc 10 | 11 | # List of goals not corresponding to file names. 12 | 13 | .PHONY : all clean distclean 14 | 15 | # Default goal. 16 | 17 | all : Language/Rzk/Syntax/Test 18 | 19 | # Rules for building the parser. 20 | 21 | Language/Rzk/Syntax/Abs.hs Language/Rzk/Syntax/Layout.hs Language/Rzk/Syntax/Lex.x Language/Rzk/Syntax/Par.y Language/Rzk/Syntax/Print.hs Language/Rzk/Syntax/Test.hs : Language/Rzk/Syntax.cf 22 | bnfc --haskell -p Language.Rzk -d --functor --generic Language/Rzk/Syntax.cf 23 | 24 | %.hs : %.y 25 | ${HAPPY} ${HAPPY_OPTS} $< 26 | 27 | %.hs : %.x 28 | ${ALEX} ${ALEX_OPTS} $< 29 | 30 | Language/Rzk/Syntax/Test : Language/Rzk/Syntax/Abs.hs Language/Rzk/Syntax/Layout.hs Language/Rzk/Syntax/Lex.hs Language/Rzk/Syntax/Par.hs Language/Rzk/Syntax/Print.hs Language/Rzk/Syntax/Test.hs 31 | ${GHC} ${GHC_OPTS} $@ 32 | 33 | # Rules for cleaning generated files. 34 | 35 | clean : 36 | -rm -f Language/Rzk/Syntax/*.hi Language/Rzk/Syntax/*.o Language/Rzk/Syntax/*.log Language/Rzk/Syntax/*.aux Language/Rzk/Syntax/*.dvi 37 | 38 | distclean : clean 39 | -rm -f Language/Rzk/Syntax/Abs.hs Language/Rzk/Syntax/Abs.hs.bak Language/Rzk/Syntax/ComposOp.hs Language/Rzk/Syntax/ComposOp.hs.bak Language/Rzk/Syntax/Doc.txt Language/Rzk/Syntax/Doc.txt.bak Language/Rzk/Syntax/ErrM.hs Language/Rzk/Syntax/ErrM.hs.bak Language/Rzk/Syntax/Layout.hs Language/Rzk/Syntax/Layout.hs.bak Language/Rzk/Syntax/Lex.x Language/Rzk/Syntax/Lex.x.bak Language/Rzk/Syntax/Par.y Language/Rzk/Syntax/Par.y.bak Language/Rzk/Syntax/Print.hs Language/Rzk/Syntax/Print.hs.bak Language/Rzk/Syntax/Skel.hs Language/Rzk/Syntax/Skel.hs.bak Language/Rzk/Syntax/Test.hs Language/Rzk/Syntax/Test.hs.bak Language/Rzk/Syntax/XML.hs Language/Rzk/Syntax/XML.hs.bak Language/Rzk/Syntax/AST.agda Language/Rzk/Syntax/AST.agda.bak Language/Rzk/Syntax/Parser.agda Language/Rzk/Syntax/Parser.agda.bak Language/Rzk/Syntax/IOLib.agda Language/Rzk/Syntax/IOLib.agda.bak Language/Rzk/Syntax/Main.agda Language/Rzk/Syntax/Main.agda.bak Language/Rzk/Syntax/Syntax.dtd Language/Rzk/Syntax/Syntax.dtd.bak Language/Rzk/Syntax/Test Language/Rzk/Syntax/Lex.hs Language/Rzk/Syntax/Par.hs Language/Rzk/Syntax/Par.info Language/Rzk/Syntax/ParData.hs Language/Rzk/Makefile 40 | -rmdir -p Language/Rzk/Syntax/ 41 | 42 | # EOF 43 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/Syntax/ErrM.hs: -------------------------------------------------------------------------------- 1 | -- File generated by the BNF Converter (bnfc 2.9.5). 2 | 3 | {-# LANGUAGE CPP #-} 4 | 5 | #if __GLASGOW_HASKELL__ >= 708 6 | --------------------------------------------------------------------------- 7 | -- Pattern synonyms exist since ghc 7.8. 8 | 9 | -- | BNF Converter: Error Monad. 10 | -- 11 | -- Module for backwards compatibility. 12 | -- 13 | -- The generated parser now uses @'Either' String@ as error monad. 14 | -- This module defines a type synonym 'Err' and pattern synonyms 15 | -- 'Bad' and 'Ok' for 'Left' and 'Right'. 16 | 17 | {-# LANGUAGE PatternSynonyms #-} 18 | {-# LANGUAGE FlexibleInstances #-} 19 | 20 | module Language.Rzk.Syntax.ErrM where 21 | 22 | import Prelude (id, const, Either(..), String) 23 | 24 | import Control.Monad (MonadPlus(..)) 25 | import Control.Applicative (Alternative(..)) 26 | #if __GLASGOW_HASKELL__ >= 808 27 | import Control.Monad (MonadFail(..)) 28 | #endif 29 | 30 | -- | Error monad with 'String' error messages. 31 | type Err = Either String 32 | 33 | pattern Bad msg = Left msg 34 | pattern Ok a = Right a 35 | 36 | #if __GLASGOW_HASKELL__ >= 808 37 | instance MonadFail Err where 38 | fail = Bad 39 | #endif 40 | 41 | instance Alternative Err where 42 | empty = Left "Err.empty" 43 | (<|>) Left{} = id 44 | (<|>) x@Right{} = const x 45 | 46 | instance MonadPlus Err where 47 | mzero = empty 48 | mplus = (<|>) 49 | 50 | #else 51 | --------------------------------------------------------------------------- 52 | -- ghc 7.6 and before: use old definition as data type. 53 | 54 | -- | BNF Converter: Error Monad 55 | 56 | -- Copyright (C) 2004 Author: Aarne Ranta 57 | -- This file comes with NO WARRANTY and may be used FOR ANY PURPOSE. 58 | 59 | module Language.Rzk.Syntax.ErrM where 60 | 61 | -- the Error monad: like Maybe type with error msgs 62 | 63 | import Control.Applicative (Applicative(..), Alternative(..)) 64 | import Control.Monad (MonadPlus(..), liftM) 65 | 66 | data Err a = Ok a | Bad String 67 | deriving (Read, Show, Eq, Ord) 68 | 69 | instance Monad Err where 70 | return = Ok 71 | Ok a >>= f = f a 72 | Bad s >>= _ = Bad s 73 | 74 | instance Applicative Err where 75 | pure = Ok 76 | (Bad s) <*> _ = Bad s 77 | (Ok f) <*> o = liftM f o 78 | 79 | instance Functor Err where 80 | fmap = liftM 81 | 82 | instance MonadPlus Err where 83 | mzero = Bad "Err.mzero" 84 | mplus (Bad _) y = y 85 | mplus x _ = x 86 | 87 | instance Alternative Err where 88 | empty = mzero 89 | (<|>) = mplus 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/Syntax/Test.hs: -------------------------------------------------------------------------------- 1 | -- File generated by the BNF Converter (bnfc 2.9.5). 2 | 3 | -- | Program to test parser. 4 | 5 | module Main where 6 | 7 | import Prelude 8 | ( ($), (.) 9 | , Bool(..) 10 | , Either(..) 11 | , Int, (>) 12 | , String, (++), concat, unlines 13 | , Show, show 14 | , IO, (>>), (>>=), mapM_, putStrLn 15 | , FilePath 16 | , getContents, readFile 17 | ) 18 | import System.Environment ( getArgs ) 19 | import System.Exit ( exitFailure ) 20 | import Control.Monad ( when ) 21 | 22 | import Language.Rzk.Syntax.Abs () 23 | import Language.Rzk.Syntax.Layout ( resolveLayout ) 24 | import Language.Rzk.Syntax.Lex ( Token, mkPosToken ) 25 | import Language.Rzk.Syntax.Par ( pModule, myLexer ) 26 | import Language.Rzk.Syntax.Print ( Print, printTree ) 27 | import Language.Rzk.Syntax.Skel () 28 | 29 | type Err = Either String 30 | type ParseFun a = [Token] -> Err a 31 | type Verbosity = Int 32 | 33 | putStrV :: Verbosity -> String -> IO () 34 | putStrV v s = when (v > 1) $ putStrLn s 35 | 36 | runFile :: (Print a, Show a) => Verbosity -> ParseFun a -> FilePath -> IO () 37 | runFile v p f = putStrLn f >> readFile f >>= run v p 38 | 39 | run :: (Print a, Show a) => Verbosity -> ParseFun a -> String -> IO () 40 | run v p s = 41 | case p ts of 42 | Left err -> do 43 | putStrLn "\nParse Failed...\n" 44 | putStrV v "Tokens:" 45 | mapM_ (putStrV v . showPosToken . mkPosToken) ts 46 | putStrLn err 47 | exitFailure 48 | Right tree -> do 49 | putStrLn "\nParse Successful!" 50 | showTree v tree 51 | where 52 | ts = resolveLayout True $ myLexer s 53 | showPosToken ((l,c),t) = concat [ show l, ":", show c, "\t", show t ] 54 | 55 | showTree :: (Show a, Print a) => Int -> a -> IO () 56 | showTree v tree = do 57 | putStrV v $ "\n[Abstract Syntax]\n\n" ++ show tree 58 | putStrV v $ "\n[Linearized tree]\n\n" ++ printTree tree 59 | 60 | usage :: IO () 61 | usage = do 62 | putStrLn $ unlines 63 | [ "usage: Call with one of the following argument combinations:" 64 | , " --help Display this help message." 65 | , " (no arguments) Parse stdin verbosely." 66 | , " (files) Parse content of files verbosely." 67 | , " -s (files) Silent mode. Parse content of files silently." 68 | ] 69 | 70 | main :: IO () 71 | main = do 72 | args <- getArgs 73 | case args of 74 | ["--help"] -> usage 75 | [] -> getContents >>= run 2 pModule 76 | "-s":fs -> mapM_ (runFile 0 pModule) fs 77 | fs -> mapM_ (runFile 2 pModule) fs 78 | 79 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/VSCode/Config.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | {-# LANGUAGE RecordWildCards #-} 3 | 4 | module Language.Rzk.VSCode.Config ( 5 | ServerConfig(..), 6 | ) where 7 | 8 | import Data.Aeson 9 | import Data.Default.Class (Default, def) 10 | 11 | data ServerConfig = ServerConfig 12 | { formatEnabled :: Bool 13 | } deriving Show 14 | 15 | instance Default ServerConfig where 16 | def = ServerConfig 17 | { formatEnabled = True 18 | } 19 | 20 | -- We need to derive the FromJSON instance manually in order to provide defaults 21 | -- for absent fields. 22 | instance FromJSON ServerConfig where 23 | -- Note: "configSection" in ServerDefinition already filters by the "rzk." prefix 24 | parseJSON = withObject "rzkSettings" $ \rzkSettings -> do 25 | formatSettings <- rzkSettings .: "format" -- TODO: how to make this optional? 26 | formatEnabled <- formatSettings .:? "enable" .!= formatEnabled def 27 | return ServerConfig { .. } 28 | 29 | instance ToJSON ServerConfig where 30 | toJSON (ServerConfig { .. }) = object 31 | [ "format" .= object 32 | [ "enable" .= formatEnabled 33 | ] 34 | ] 35 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/VSCode/Env.hs: -------------------------------------------------------------------------------- 1 | module Language.Rzk.VSCode.Env where 2 | 3 | import Control.Concurrent.STM 4 | import Control.Monad.Reader 5 | import Language.LSP.Server 6 | import Language.Rzk.Free.Syntax (VarIdent) 7 | import Language.Rzk.VSCode.Config (ServerConfig) 8 | import Rzk.TypeCheck (Decl', TypeErrorInScopedContext) 9 | 10 | data RzkCachedModule = RzkCachedModule 11 | { cachedModuleDecls :: [Decl'] 12 | , cachedModuleErrors :: [TypeErrorInScopedContext VarIdent] 13 | } 14 | 15 | type RzkTypecheckCache = [(FilePath, RzkCachedModule)] 16 | 17 | newtype RzkEnv = RzkEnv 18 | { rzkEnvTypecheckCache :: TVar RzkTypecheckCache 19 | } 20 | 21 | defaultRzkEnv :: IO RzkEnv 22 | defaultRzkEnv = do 23 | typecheckCache <- newTVarIO [] 24 | return RzkEnv 25 | { rzkEnvTypecheckCache = typecheckCache } 26 | 27 | type LSP = LspT ServerConfig (ReaderT RzkEnv IO) 28 | 29 | -- | Override the cache with given typechecked modules. 30 | cacheTypecheckedModules :: RzkTypecheckCache -> LSP () 31 | cacheTypecheckedModules cache = lift $ do 32 | typecheckCache <- asks rzkEnvTypecheckCache 33 | liftIO $ atomically $ do 34 | writeTVar typecheckCache cache 35 | 36 | -- | Completely invalidate the cache of typechecked files. 37 | resetCacheForAllFiles :: LSP () 38 | resetCacheForAllFiles = cacheTypecheckedModules [] 39 | 40 | -- | Invalidate the cache for a list of file paths. 41 | resetCacheForFiles :: [FilePath] -> LSP () 42 | resetCacheForFiles paths = lift $ do 43 | typecheckCache <- asks rzkEnvTypecheckCache 44 | liftIO $ atomically $ do 45 | modifyTVar typecheckCache (takeWhile ((`notElem` paths) . fst)) 46 | 47 | -- | Get the current state of the cache. 48 | getCachedTypecheckedModules :: LSP RzkTypecheckCache 49 | getCachedTypecheckedModules = lift $ do 50 | typecheckCache <- asks rzkEnvTypecheckCache 51 | liftIO $ readTVarIO typecheckCache 52 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/VSCode/Logging.hs: -------------------------------------------------------------------------------- 1 | module Language.Rzk.VSCode.Logging where 2 | 3 | import Colog.Core (Severity (..), WithSeverity (..), (<&)) 4 | import qualified Data.Text as T 5 | import Language.LSP.Logging (defaultClientLogger) 6 | import Language.LSP.Server (MonadLsp) 7 | 8 | 9 | logDebug :: MonadLsp c m => String -> m () 10 | logDebug msg = defaultClientLogger <& T.pack msg `WithSeverity` Debug 11 | 12 | logInfo :: MonadLsp c m => String -> m () 13 | logInfo msg = defaultClientLogger <& T.pack msg `WithSeverity` Info 14 | 15 | logWarning :: MonadLsp c m => String -> m () 16 | logWarning msg = defaultClientLogger <& T.pack msg `WithSeverity` Warning 17 | 18 | -- | Error logs will also be shown to the user via `window/showMessage` 19 | logError :: MonadLsp c m => String -> m () 20 | logError msg = defaultClientLogger <& T.pack msg `WithSeverity` Error 21 | -------------------------------------------------------------------------------- /rzk/src/Language/Rzk/VSCode/Lsp.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DuplicateRecordFields #-} 2 | {-# LANGUAGE OverloadedStrings #-} 3 | 4 | module Language.Rzk.VSCode.Lsp where 5 | 6 | import Control.Monad.IO.Class 7 | import Control.Monad.Reader 8 | import Data.Default.Class (Default (def)) 9 | import qualified Data.Text as T 10 | import Language.LSP.Protocol.Message 11 | import Language.LSP.Protocol.Types 12 | import Language.LSP.Server 13 | 14 | import Data.Aeson (Result (Error, Success), 15 | fromJSON) 16 | import Language.Rzk.VSCode.Config (ServerConfig (..)) 17 | import Language.Rzk.VSCode.Env 18 | import Language.Rzk.VSCode.Handlers 19 | 20 | -- | The maximum number of diagnostic messages to send to the client 21 | maxDiagnosticCount :: Int 22 | maxDiagnosticCount = 100 23 | 24 | handlers :: Handlers LSP 25 | handlers = 26 | mconcat 27 | [ notificationHandler SMethod_Initialized $ const typecheckFromConfigFile 28 | -- TODO: add logging 29 | -- Empty handlers to silence the errors 30 | , notificationHandler SMethod_TextDocumentDidOpen $ \_msg -> pure () 31 | , notificationHandler SMethod_TextDocumentDidChange $ \_msg -> pure () 32 | , notificationHandler SMethod_TextDocumentDidClose $ \_msg -> pure () 33 | , notificationHandler SMethod_WorkspaceDidChangeWatchedFiles handleFilesChanged 34 | , notificationHandler SMethod_TextDocumentDidSave $ \_msg -> do 35 | -- TODO: check if the file is included in the config's `include` list. 36 | -- If not (and not in `exclude`) either, issue a warning. 37 | return () -- FIXME: typecheck standalone files (if they are not a part of the project) 38 | -- An empty hadler is needed to silence the error since it is already handled by the LSP package 39 | , notificationHandler SMethod_WorkspaceDidChangeConfiguration $ const $ pure () 40 | -- , requestHandler SMethod_TextDocumentHover $ \req responder -> do 41 | -- TODO: Read from the list of symbols that is supposed to be cached by the typechecker 42 | -- let TRequestMessage _ _ _ (HoverParams _doc pos _workDone) = req 43 | -- Position _l _c' = pos 44 | -- rsp = Hover (InL ms) (Just range') 45 | -- ms = mkMarkdown "Hello world" 46 | -- range' = Range pos pos 47 | -- responder (Right $ InL rsp) 48 | , requestHandler SMethod_TextDocumentCompletion provideCompletions 49 | , requestHandler SMethod_TextDocumentSemanticTokensFull provideSemanticTokens 50 | , requestHandler SMethod_TextDocumentFormatting formatDocument 51 | ] 52 | 53 | 54 | syncOptions :: TextDocumentSyncOptions 55 | syncOptions = TextDocumentSyncOptions 56 | { _openClose = Just True 57 | , _change = Just TextDocumentSyncKind_Full 58 | , _willSave = Just False 59 | , _willSaveWaitUntil = Just False 60 | , _save = Just $ InR $ SaveOptions { _includeText = Just True } 61 | } 62 | 63 | runLsp :: IO Int 64 | runLsp = do 65 | rzkEnv <- defaultRzkEnv 66 | runServer $ 67 | ServerDefinition 68 | { configSection = "rzk" 69 | , parseConfig = \_oldConfig newObject -> case fromJSON newObject of 70 | -- TODO: handle partial config updates from VS Code by updating oldConfig rather than parsing from scratch 71 | Error err -> Left $ T.pack err 72 | Success rzkConfig -> Right rzkConfig 73 | , onConfigChange = const $ pure () 74 | , doInitialize = const . pure . Right 75 | , staticHandlers = const handlers 76 | , interpretHandler = \env -> Iso (flip runReaderT rzkEnv . runLspT env) liftIO 77 | , options = defaultOptions { optTextDocumentSync = Just syncOptions } 78 | , defaultConfig = def :: ServerConfig 79 | } 80 | -------------------------------------------------------------------------------- /rzk/src/Rzk.hs: -------------------------------------------------------------------------------- 1 | module Rzk where 2 | -------------------------------------------------------------------------------- /rzk/src/Rzk/Main.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE LambdaCase #-} 2 | {-# LANGUAGE OverloadedStrings #-} 3 | {-# LANGUAGE RecordWildCards #-} 4 | {-# LANGUAGE TypeApplications #-} 5 | 6 | module Rzk.Main where 7 | 8 | import Control.Monad (forM, when) 9 | import Data.List (sort) 10 | import qualified Data.Yaml as Yaml 11 | import System.Directory (doesPathExist) 12 | import System.FilePath.Glob (glob) 13 | 14 | import qualified Language.Rzk.Syntax as Rzk 15 | import Rzk.Project.Config 16 | import Rzk.TypeCheck 17 | 18 | 19 | 20 | parseStdin :: IO Rzk.Module 21 | parseStdin = do 22 | result <- Rzk.parseModule <$> getContents 23 | case result of 24 | Left err -> do 25 | putStrLn ("An error occurred when parsing stdin") 26 | error err 27 | Right rzkModule -> return rzkModule 28 | 29 | -- | Finds matches to the given pattern in the current working directory. 30 | -- **NOTE:** throws exception when 'glob' returns an empty list. 31 | globNonEmpty :: FilePath -> IO [FilePath] 32 | globNonEmpty path = do 33 | glob path >>= \case 34 | [] -> error ("File(s) not found at " <> path) 35 | paths -> return (sort paths) 36 | 37 | extractFilesFromRzkYaml :: FilePath -> IO [FilePath] 38 | extractFilesFromRzkYaml rzkYamlPath = do 39 | eitherConfig <- Yaml.decodeFileEither @ProjectConfig rzkYamlPath 40 | case eitherConfig of 41 | Left err -> do 42 | error ("Invalid or missing rzk.yaml: " ++ Yaml.prettyPrintParseException err) 43 | Right ProjectConfig{..} -> do 44 | return include 45 | 46 | -- | Given a list of file paths (possibly including globs), expands the globs (if any) 47 | -- or tries to read the list of files from the rzk.yaml file (if no paths are given). 48 | -- Glob patterns in rzk.yaml are also expanded. 49 | expandRzkPathsOrYaml :: [FilePath] -> IO [FilePath] 50 | expandRzkPathsOrYaml = \case 51 | [] -> do 52 | let rzkYamlPath = "rzk.yaml" 53 | rzkYamlExists <- doesPathExist rzkYamlPath 54 | if rzkYamlExists 55 | then do 56 | paths <- extractFilesFromRzkYaml rzkYamlPath 57 | when (null paths) (error $ "No files found in " <> rzkYamlPath) 58 | expandRzkPathsOrYaml paths 59 | else error ("No paths given and no " <> rzkYamlPath <> " found") 60 | paths -> foldMap globNonEmpty paths 61 | 62 | parseRzkFilesOrStdin :: [FilePath] -> IO [(FilePath, Rzk.Module)] 63 | parseRzkFilesOrStdin = \case 64 | -- if no paths are given — read from stdin 65 | -- TODO: reuse the `expandRzkPathsOrYaml` function 66 | [] -> do 67 | let rzkYamlPath = "rzk.yaml" 68 | rzkYamlExists <- doesPathExist rzkYamlPath 69 | if rzkYamlExists 70 | then do 71 | putStrLn ("Using Rzk project stucture specified in " <> rzkYamlPath) 72 | paths <- extractFilesFromRzkYaml rzkYamlPath 73 | when (null paths) (error $ "No Rzk files specified in the config file at " <> rzkYamlPath) 74 | parseRzkFilesOrStdin paths 75 | else do 76 | rzkModule <- parseStdin 77 | return [("", rzkModule)] 78 | -- otherwise — parse all given files in given order 79 | paths -> do 80 | expandedPaths <- foldMap globNonEmpty paths 81 | forM expandedPaths $ \path -> do 82 | putStrLn ("Loading file " <> path) 83 | result <- Rzk.parseModule <$> readFile path 84 | case result of 85 | Left err -> do 86 | putStrLn ("An error occurred when parsing file " <> path) 87 | error err 88 | Right rzkModule -> return (path, rzkModule) 89 | 90 | typecheckString :: String -> Either String String 91 | typecheckString moduleString = do 92 | rzkModule <- Rzk.parseModule moduleString 93 | case defaultTypeCheck (typecheckModules [rzkModule]) of 94 | Left err -> Left $ unlines 95 | [ "An error occurred when typechecking!" 96 | , "Rendering type error... (this may take a few seconds)" 97 | , unlines 98 | [ "Type Error:" 99 | , ppTypeErrorInScopedContext' BottomUp err 100 | ] 101 | ] 102 | Right _ -> pure "Everything is ok!" 103 | -------------------------------------------------------------------------------- /rzk/src/Rzk/Project/Config.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE OverloadedStrings #-} 2 | 3 | module Rzk.Project.Config where 4 | 5 | import Data.Yaml (FromJSON (..), (.!=), (.:), (.:?)) 6 | import qualified Data.Yaml as Y 7 | 8 | data ProjectConfig = ProjectConfig 9 | { include :: [FilePath] 10 | , exclude :: [FilePath] 11 | } deriving (Eq, Show) 12 | 13 | instance FromJSON ProjectConfig where 14 | parseJSON (Y.Object v) = 15 | ProjectConfig <$> 16 | v .: "include" <*> 17 | v .:? "exclude" .!= [] 18 | parseJSON _ = fail "Expected config value to be an object" 19 | -------------------------------------------------------------------------------- /rzk/test/Rzk/FormatSpec.hs: -------------------------------------------------------------------------------- 1 | {-| 2 | Module : FormatterSpec 3 | Description : Tests related to the formatter module 4 | -} 5 | module Rzk.FormatSpec where 6 | 7 | import Test.Hspec 8 | 9 | import Rzk.Format (format, isWellFormatted) 10 | 11 | formatsTo :: FilePath -> FilePath -> Expectation 12 | formatsTo beforePath afterPath = do 13 | beforeSrc <- readFile ("test/files/" ++ beforePath) 14 | afterSrc <- readFile ("test/files/" ++ afterPath) 15 | format beforeSrc `shouldBe` afterSrc 16 | isWellFormatted afterSrc `shouldBe` True -- idempotency 17 | 18 | formats :: FilePath -> Expectation 19 | formats path = (path ++ "-bad.rzk") `formatsTo` (path ++ "-good.rzk") 20 | 21 | 22 | spec :: Spec 23 | spec = do 24 | describe "Formatter" $ do 25 | it "Puts definition assumptions, conclusion, and construction on separate lines" $ do 26 | -- formats "definition-structure" 27 | pendingWith "Doesn't currently place assumptions on a new line" 28 | 29 | it "Replaces common ASCII sequences with their unicode equivalent" $ do 30 | formats "unicode" 31 | 32 | it "Formats Rzk blocks in Literate Rzk Markdown" $ do 33 | "literate-bad.rzk.md" `formatsTo` "literate-good.rzk.md" 34 | 35 | it "Preserves comments" $ do 36 | formats "comments" 37 | 38 | it "Moves trailing binary operators to next line (except lambda arrow)" $ do 39 | formats "bin-ops" 40 | 41 | it "Adds relevant spaces to structure constructions like a tree" $ do 42 | formats "tree-structure" 43 | 44 | it "Doesn't fail on empty inputs" $ do 45 | formats "empty" 46 | 47 | it "Fixes indentation" pending 48 | 49 | it "Wraps long lines" pending 50 | -------------------------------------------------------------------------------- /rzk/test/Spec.hs: -------------------------------------------------------------------------------- 1 | {-# OPTIONS_GHC -F -pgmF hspec-discover #-} 2 | -------------------------------------------------------------------------------- /rzk/test/doctests.hs: -------------------------------------------------------------------------------- 1 | -- doctests/Main.hs 2 | 3 | import Test.DocTest 4 | 5 | -- This test suite exists only to add dependencies 6 | main :: IO () 7 | main = doctest ["src"] 8 | -------------------------------------------------------------------------------- /rzk/test/files/bin-ops-bad.rzk: -------------------------------------------------------------------------------- 1 | #def function 2 | ( parameter-1 : type-1) 3 | ( parameter-2 : type-2) 4 | : type-with-a-name-3 → 5 | type-with-a-longer-name-4 -> 6 | short-type-5 7 | := undefined 8 | 9 | #def is-contr-map-has-retraction uses (is-contr-f) 10 | : has-retraction A B f 11 | := 12 | ( is-contr-map-inverse , 13 | \ a 14 | → ( ap (fib A B f (f a)) A 15 | ( is-contr-map-data-in-fiber a) 16 | ( (a , refl)) 17 | ( ( a , refl)) 18 | ( \ u → first u) 19 | ( is-contr-map-path-in-fiber a))) 20 | -------------------------------------------------------------------------------- /rzk/test/files/bin-ops-good.rzk: -------------------------------------------------------------------------------- 1 | #def function 2 | ( parameter-1 : type-1) 3 | ( parameter-2 : type-2) 4 | : type-with-a-name-3 5 | → type-with-a-longer-name-4 6 | → short-type-5 7 | := undefined 8 | 9 | #def is-contr-map-has-retraction uses (is-contr-f) 10 | : has-retraction A B f 11 | := 12 | ( is-contr-map-inverse 13 | , \ a → 14 | ( ap (fib A B f (f a)) A 15 | ( is-contr-map-data-in-fiber a) 16 | ( ( a , refl)) 17 | ( ( a , refl)) 18 | ( \ u → first u) 19 | ( is-contr-map-path-in-fiber a))) 20 | -------------------------------------------------------------------------------- /rzk/test/files/comments-bad.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | -- Flipping the arguments of a function. 4 | #define flip 5 | (A B : U) -- For any types A and B 6 | (C : (x : A) -> (y : B) -> U) -- and a type family C 7 | (f : (x : A) -> (y : B) -> C x y) -- given a function f : A -> B -> C 8 | : (y : B) -> (x : A) -> C x y -- we construct a function of type B -> A -> C 9 | := \y x -> f x y -- by swapping the arguments 10 | -------------------------------------------------------------------------------- /rzk/test/files/comments-good.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | -- Flipping the arguments of a function. 4 | #define flip 5 | ( A B : U) -- For any types A and B 6 | ( C : (x : A) → (y : B) → U) -- and a type family C 7 | ( f : (x : A) → (y : B) → C x y) -- given a function f : A -> B -> C 8 | : ( y : B) → (x : A) → C x y -- we construct a function of type B -> A -> C 9 | := \ y x → f x y -- by swapping the arguments 10 | -------------------------------------------------------------------------------- /rzk/test/files/definition-structure-bad.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | #define id ( A : U) : A → A := \ x → x 4 | 5 | #define swap 6 | ( A B C : U) 7 | : ( A → B → C) → (B → A → C) := \ f y x → f x y 8 | -------------------------------------------------------------------------------- /rzk/test/files/definition-structure-good.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | #define id 4 | ( A : U) 5 | : A → A 6 | := \ x → x 7 | 8 | #define swap 9 | ( A B C : U) 10 | : ( A → B → C) → (B → A → C) 11 | := \ f y x → f x y 12 | -------------------------------------------------------------------------------- /rzk/test/files/empty-bad.rzk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/rzk/test/files/empty-bad.rzk -------------------------------------------------------------------------------- /rzk/test/files/empty-good.rzk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rzk-lang/rzk/3ea72b85e099e785e116a0877d37bca56cc77b7c/rzk/test/files/empty-good.rzk -------------------------------------------------------------------------------- /rzk/test/files/literate-bad.rzk.md: -------------------------------------------------------------------------------- 1 | # 1.4 Dependent function types ($\Pi$-types) 2 | 3 | This is a literate Rzk file: 4 | 5 | ```rzk 6 | #lang rzk-1 7 | ``` 8 | 9 | A polymorphic function is one which takes a type as one of its arguments, 10 | and then acts on elements of that type (or of other types constructed from it). 11 | An example is the polymorphic identity function: 12 | 13 | ```rzk 14 | #define id 15 | (A : U) : A -> A 16 | := \ x → x 17 | ``` 18 | 19 | Another, less trivial, example of a polymorphic function is the "swap" operation 20 | that switches the order of the arguments of a (curried) two-argument function: 21 | 22 | ```rzk 23 | #define swap 24 | (A B C : U) 25 | : (A → B → C) -> (B → A → C) 26 | :=\f y x → f x y 27 | ``` 28 | -------------------------------------------------------------------------------- /rzk/test/files/literate-good.rzk.md: -------------------------------------------------------------------------------- 1 | # 1.4 Dependent function types ($\Pi$-types) 2 | 3 | This is a literate Rzk file: 4 | 5 | ```rzk 6 | #lang rzk-1 7 | ``` 8 | 9 | A polymorphic function is one which takes a type as one of its arguments, 10 | and then acts on elements of that type (or of other types constructed from it). 11 | An example is the polymorphic identity function: 12 | 13 | ```rzk 14 | #define id 15 | ( A : U) 16 | : A → A 17 | := \ x → x 18 | ``` 19 | 20 | Another, less trivial, example of a polymorphic function is the "swap" operation 21 | that switches the order of the arguments of a (curried) two-argument function: 22 | 23 | ```rzk 24 | #define swap 25 | ( A B C : U) 26 | : ( A → B → C) → (B → A → C) 27 | := \ f y x → f x y 28 | ``` 29 | -------------------------------------------------------------------------------- /rzk/test/files/tree-structure-bad.rzk: -------------------------------------------------------------------------------- 1 | #def is-segal-is-local-horn-inclusion 2 | (A : U) 3 | (is-local-horn-inclusion-A : is-local-horn-inclusion A) 4 | : is-segal A 5 | := 6 | \ x y z f g → 7 | contractible-fibers-is-equiv-projection 8 | ( Λ → A) 9 | (\ k → 10 | Σ (h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 11 | , ( hom2 A 12 | ( k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 13 | ( \ t → k (t , 0₂)) 14 | ( \t → k (1₂ , t)) 15 | (h))) 16 | (second 17 | ( equiv-comp 18 | ( Σ ( k : Λ → A) 19 | , Σ (h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 20 | , (hom2 A 21 | ( k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 22 | (\ t → k (t , 0₂)) 23 | (\ t → k (1₂ , t)) 24 | (h))) 25 | (Δ² → A) 26 | ( Λ → A) 27 | ( inv-equiv 28 | ( Δ² → A) 29 | ( Σ ( k : Λ → A) 30 | , Σ ( h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 31 | , (hom2 A 32 | (k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 33 | (\ t → k (t , 0₂)) 34 | (\ t → k (1₂ , t)) 35 | (h))) 36 | ( equiv-horn-restriction A)) 37 | (horn-restriction A , is-local-horn-inclusion-A))) 38 | (horn A x y z f g) 39 | -------------------------------------------------------------------------------- /rzk/test/files/tree-structure-good.rzk: -------------------------------------------------------------------------------- 1 | #def is-segal-is-local-horn-inclusion 2 | ( A : U) 3 | ( is-local-horn-inclusion-A : is-local-horn-inclusion A) 4 | : is-segal A 5 | := 6 | \ x y z f g → 7 | contractible-fibers-is-equiv-projection 8 | ( Λ → A) 9 | ( \ k → 10 | Σ ( h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 11 | , ( hom2 A 12 | ( k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 13 | ( \ t → k (t , 0₂)) 14 | ( \ t → k (1₂ , t)) 15 | ( h))) 16 | ( second 17 | ( equiv-comp 18 | ( Σ ( k : Λ → A) 19 | , Σ ( h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 20 | , ( hom2 A 21 | ( k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 22 | ( \ t → k (t , 0₂)) 23 | ( \ t → k (1₂ , t)) 24 | ( h))) 25 | ( Δ² → A) 26 | ( Λ → A) 27 | ( inv-equiv 28 | ( Δ² → A) 29 | ( Σ ( k : Λ → A) 30 | , Σ ( h : hom A (k (0₂ , 0₂)) (k (1₂ , 1₂))) 31 | , ( hom2 A 32 | ( k (0₂ , 0₂)) (k (1₂ , 0₂)) (k (1₂ , 1₂)) 33 | ( \ t → k (t , 0₂)) 34 | ( \ t → k (1₂ , t)) 35 | ( h))) 36 | ( equiv-horn-restriction A)) 37 | ( horn-restriction A , is-local-horn-inclusion-A))) 38 | ( horn A x y z f g) 39 | -------------------------------------------------------------------------------- /rzk/test/files/unicode-bad.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | #define weird 4 | ( A : U) 5 | ( I : A -> CUBE) 6 | ( x y : A) 7 | : CUBE 8 | := I x * I y 9 | 10 | #define iscontr 11 | ( A : U) 12 | : U 13 | := Sigma (a : A) , (x : A) -> a =_{A} x 14 | 15 | #def ∂Δ¹ 16 | : Δ¹ -> TOPE 17 | := \ t -> (t === 0_2 \/ t === 1_2) 18 | -------------------------------------------------------------------------------- /rzk/test/files/unicode-good.rzk: -------------------------------------------------------------------------------- 1 | #lang rzk-1 2 | 3 | #define weird 4 | ( A : U) 5 | ( I : A → CUBE) 6 | ( x y : A) 7 | : CUBE 8 | := I x × I y 9 | 10 | #define iscontr 11 | ( A : U) 12 | : U 13 | := Σ (a : A) , (x : A) → a =_{A} x 14 | 15 | #def ∂Δ¹ 16 | : Δ¹ → TOPE 17 | := \ t → (t ≡ 0₂ ∨ t ≡ 1₂) 18 | -------------------------------------------------------------------------------- /shell.nix: -------------------------------------------------------------------------------- 1 | let t = (import 2 | ( 3 | let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in 4 | fetchTarball { 5 | url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; 6 | sha256 = lock.nodes.flake-compat.locked.narHash; 7 | } 8 | ) 9 | { src = ./.; } 10 | ).shellNix; in t // t.devShells.${builtins.currentSystem} -------------------------------------------------------------------------------- /stack.yaml: -------------------------------------------------------------------------------- 1 | resolver: nightly-2024-08-17 2 | packages: 3 | - rzk 4 | -------------------------------------------------------------------------------- /stack.yaml.lock: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by Stack. 2 | # You should not edit this file by hand. 3 | # For more information, please see the documentation at: 4 | # https://docs.haskellstack.org/en/stable/lock_files 5 | 6 | packages: [] 7 | snapshots: 8 | - completed: 9 | sha256: c93fb97219f317bdba82c69b4388665268c1964d9636a6ecdc9a58f8771f0bc0 10 | size: 658092 11 | url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/nightly/2024/8/17.yaml 12 | original: nightly-2024-08-17 13 | --------------------------------------------------------------------------------