# Proof Assistant Bot 1. [Description](#descriprion) 2. [Installation](#installation) 1. [Coq](#coq) 2. [Agda](#agda) 3. [Idris 2](#idris-2) 4. [Lean](#lean) 5. [Arend](#arend) 6. [Rzk](#rzk) 3. [Usage](#usage) 4. [Available instances](#available-instances) 5. [Acknowledgements](#acknowledgements) ## Description This bot provides limited Telegram interfaces to following proof assistant programs (in order of implementation): - Coq - Agda - Idris 2 - Lean - Arend - Rzk ## Installation 1. Bot could be built via following commands: ```bash cabal update cabal build cabal install --overwrite-policy=always ``` 2. To launch bot you need to set environmental variables, see `./config/settings.dhall` for more details. One of them is `PROOF_ASSISTANT_BOT_TOKEN`. Obtain it via `@BotFather` and set it: ``` export PROOF_ASSISTANT_BOT_TOKEN="..." ``` ### Coq 1. Install `opam >= 2.1.0`, e.g. [from here](https://ocaml.org/docs/up-and-running#installation-for-unix). ```bash cd $HOME opam --version 2.1.3 ``` 2. Install `Coq`. ```bash cd $HOME opam init eval $(opam env) opam pin add coq 8.16.1 ``` 3. Locate `coqtop` and set enviromental variable. Should be similar to: ``` export COQ_BIN_PATH="$HOME/.opam/default/bin/coqtop" ``` ### Agda We do not need to worry about `Agda` since it is included in package dependencies. It will be installed automatically. Meantime, Agda standard library should be installed manually. 1. Get `agda-stdlib` from [Github](https://github.com/agda/agda-stdlib/releases/tag/v1.7.1). 2. Unpack archive. ``` mkdir -p $PROOF_ASSISTANT_BOT_DIR/agda cp agda-stdlib-1.7.1.tar.gz $PROOF_ASSISTANT_BOT_DIR/agda cd $PROOF_ASSISTANT_BOT_DIR/agda tar -xzvf agda-stdlib-1.7.1.tar.gz export AGDA_STDLIB_PATH=$PROOF_ASSISTANT_BOT_DIR/agda/agda-stdlib-1.7.1 ``` 3. Create file `$HOME/.agda/defaults` with following content: ``` standard-library ``` 4. Create file `$HOME/.agda/libraries` with following content: ``` $AGDA_STDLIB_PATH/standard-library.agda-lib ``` ### Idris 2 1. Get `nix` from [nixos.org](https://nixos.org/download.html#download-nix). 2. Install `idris2` via `nix`: ```bash nix-env -i idris2 ``` 3. Set environmental variable: ```bash export IDRIS2_BIN_PATH="$HOME/.nix-profile/bin/idris2" ``` ### Lean 1. Get `nix` from [nixos.org](https://nixos.org/download.html#download-nix). 2. Install `lean` via `nix`: ```bash nix-env -i lean ``` 3. Install `leanproject` via `nix`: ```bash nix-env -i mathlibtools ``` 4. Run `leanproject new lean`. 5. Set `LEAN_BIN_PATH` environmental variable: ```bash export LEAN_BIN_PATH="$HOME/.nix-profile/bin/lean" ``` 6. Set `LEAN_PROJECT_PATH` to the newly created project directory. ### Arend 1. Get `nix` from [nixos.org](https://nixos.org/download.html#download-nix). 2. Get `java` and `openjdk17` via `nix`: ```bash nix-env -i openjdk-17.0.4+8 ``` 3. Set `JAVA_HOME` environment variable to your openjdk location. You can use `readlink $HOME/.nix-profile/bin/java` and strip `/bin/java` from the end. 4. Create project directory to store arend projects (for different Telegram chats) and set `AREND_ROOT_PROJECT_DIR`. 5. Get Arend standard library from [the official site](https://arend-lang.github.io/download#standard-library) and store in `${AREND_ROOT_PROJECT_DIR}/libs`. 6. Point `AREND_STDLIB_PATH` environment variable to the same location as `AREND_ROOT_PROJECT_DIR`. 7. Download [`Arend.jar`](https://github.com/JetBrains/Arend/releases/latest/download/Arend.jar) and set `AREND_PATH` environment variable to its location, e.g. ```bash export AREND_PATH="${AREND_ROOT_PROJECT_DIR}/Arend.jar" ``` ### Rzk No actions required. See `cabal.project` for more details. ## Usage - Coq supports only typecheck of the user input via `/coq` command. Example: ```coq /coq Inductive day : Type := | monday | tuesday | wednesday | thursday | friday | saturday | sunday. Definition next_weekday (d:day) : day := match d with | monday => tuesday | tuesday => wednesday | wednesday => thursday | thursday => friday | friday => monday | saturday => monday | sunday => monday end. Compute (next_weekday friday). Compute (next_weekday (next_weekday saturday)). Example test_next_weekday: (next_weekday (next_weekday saturday)) = tuesday. Proof. simpl. reflexivity. Qed. ``` - Agda is available via `/agda` command. Bot supports several subcommands for Agda: - `/agda /load `. E.g. ```agda /agda /load import Relation.Binary.PropositionalEquality as Eq open Eq using (_≡_; refl) open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; _∎) data ℕ : Set where zero : ℕ suc : ℕ → ℕ {-# BUILTIN NATURAL ℕ #-} _+_ : ℕ → ℕ → ℕ zero + n = n (suc m) + n = suc (m + n) _ : 2 + 3 ≡ 5 _ = begin 2 + 3 ≡⟨⟩ -- is shorthand for (suc (suc zero)) + (suc (suc (suc zero))) ≡⟨⟩ -- inductive case suc ((suc zero) + (suc (suc (suc zero)))) ≡⟨⟩ -- inductive case suc (suc (zero + (suc (suc (suc zero))))) ≡⟨⟩ -- base case suc (suc (suc (suc (suc zero)))) ≡⟨⟩ -- is longhand for 5 ∎ ``` - `/agda /reload` - `/agda /typeOf `. E.g. `/agda /typeOf suc`. - `/agda `. E.g. `/agda suc zero + suc zero`. - Idris 2 via `/idris2` command. Bot supports several subcommands for Idris 2: - `/idris2 /load `. E.g. ```idris /idris2 /load module Main import System.File.ReadWrite tryPrint : Either FileError String -> IO () tryPrint (Left _) = putStrLn "error" tryPrint (Right r) = putStrLn r main : IO () main = do c <- readFile "hello.idr" tryPrint c ``` - `/idris2 /typeOf `. E.g. `/idris2 /typeOf Nat`. - `/idris2 `. E.g. `/idris2 2 + 3`. - Lean is available via `/lean` command. Typecheck supported for the user input. Only several modes were tested (calc mode, conv mode, simplifier). - Example 1: ```lean /lean import data.nat.basic variables (a b c d e : ℕ) variable h1 : a = b variable h2 : b = c + 1 variable h3 : c = d variable h4 : e = 1 + d theorem T : a = e := calc a = b : h1 ... = c + 1 : h2 ... = d + 1 : congr_arg _ h3 ... = 1 + d : add_comm d (1 : ℕ) ... = e : eq.symm h4 ``` - Example 2: ```lean /lean import topology.basic #check topological_space ``` - Example 3: ```lean /lean import algebra.group.defs variables (G : Type) [group G] (a b c : G) example : a * a⁻¹ * 1 * b = b * c * c⁻¹ := begin simp end ``` - Arend is available via `/arend` command. Only typecheck supported. - Example: ```arend /arend \func f => 0 ``` - Rzk is available via `/rzk` command. Typechecker supported for every language. - Example: ```rzk /rzk #lang rzk-1 #def prod : (A : U) -> (B : U) -> U := \A -> \B -> ∑ (x : A), B #def isweq : (A : U) -> (B : U) -> (f : (_ : A) -> B) -> U := \A -> \B -> \f -> ∑ (g : (_ : B) -> A), prod ((x : A) -> g (f x) =_{A} x) ((y : B) -> f (g y) =_{B} y) #def weq : (A : U) -> (B : U) -> U := \A -> \B -> ∑ (f : (_ : A) -> B), isweq A B f #def Theorem-4.1 : (I : CUBE) -> (psi : (t : I) -> TOPE) -> (phi : {(t : I) | psi t} -> TOPE) -> (X : U) -> (Y : <{t : I | psi t} -> (x : X) -> U >) -> (f : <{t : I | phi t} -> (x : X) -> Y t x >) -> weq <{t : I | psi t} -> (x : X) -> Y t x [phi t |-> f t]> ((x : X) -> <{t : I | psi t} -> Y t x [phi t |-> f t x]>) := \I -> \psi -> \phi -> \X -> \Y -> \f -> (\k -> \x -> \t -> k t x, (\k -> \{t : I | psi t} -> \x -> (k x) t, (\k -> refl_{k}, \k -> refl_{k}))) #def Theorem-4.2_uncurry_ext : (I : CUBE) -> (J : CUBE) -> (psi : (t : I) -> TOPE) -> (zeta : (s : J) -> TOPE) -> (X : <{t : I | psi t} -> <{s : J | zeta s} -> U> >) -> (chi : {(t : I) | psi t} -> TOPE) -> (phi : {(s : J) | zeta s} -> TOPE) -> (f : <{(t, s) : I * J | psi t /\ zeta s} -> X t s >) -> (_ : <{t : I | psi t} -> <{s : J | zeta s} -> X t s [chi s |-> f (t, s)]> [phi t |-> \s -> f (t, s)]>) -> <{(t, s) : I * J | psi t /\ zeta s} -> X t s [(phi t /\ zeta s) \/ (psi t /\ chi s) |-> f (t, s)]> := \I -> \J -> \psi -> \zeta -> \X -> \chi -> \phi -> \f -> \k -> \(t, s) -> k t s ``` ## Available instances 1. [@ProofBot](https://t.me/ProofAssistantBot) (online) 2. [@ProofDebugBot](https://t.me/ProofDebugBot) (for debug purpose, offline most of the time) ## Acknowledgements - PLTT Community - Nikolay Kudasov - Andrey Borzenkov - Matúš Tejiščák - My wife