├── .gitattributes ├── .gitignore ├── CNAME ├── HACKING.md ├── LICENSE ├── README.md ├── doc ├── Makefile ├── henk.pdf ├── henk.tex ├── pts.bbl ├── pts.bib ├── pts.blg ├── pts_ua.bib ├── pts_ua.pdf ├── pts_ua.tex ├── stages.png ├── static.png └── structure.png ├── footer.pug ├── framework.js ├── header.pug ├── img └── Henk Barendregt.jpg ├── index.html ├── index.pug ├── main.css ├── package.json └── src ├── elixir ├── encodings │ ├── ch.erl │ ├── cps.erl │ └── parigot.erl ├── extractor │ ├── om_erase.erl │ └── om_extract.erl ├── henk.app.src ├── henk.erl ├── lib │ ├── app.ex │ └── syntax │ │ └── automath.ex ├── mix.exs ├── om.erl ├── om_help.erl ├── om_io.erl ├── priv │ ├── AUT-68 │ │ └── List │ │ │ ├── @.aut │ │ │ ├── Cons.aut │ │ │ └── Nil.aut │ └── Morte │ │ ├── Bool │ │ ├── @ │ │ ├── False │ │ ├── True │ │ ├── [&&] │ │ ├── [||] │ │ ├── and │ │ ├── eif │ │ ├── eiff │ │ ├── if │ │ ├── iff │ │ ├── induction_on.type │ │ ├── not │ │ └── or │ │ ├── Cmd │ │ ├── @ │ │ ├── Bind │ │ ├── Monad │ │ ├── Monad.old │ │ ├── Pure │ │ ├── [>>=] │ │ ├── embed │ │ ├── lift │ │ ├── map │ │ └── sequence_ │ │ ├── Eq │ │ ├── Equ │ │ ├── @ │ │ └── Refl │ │ ├── Frege │ │ ├── @ │ │ └── intro │ │ ├── IO │ │ ├── @ │ │ ├── [>>=] │ │ ├── [>>=].Aut │ │ ├── [>>] │ │ ├── data │ │ ├── getLine │ │ ├── pure │ │ ├── putLine │ │ └── replicateM │ │ ├── IOI │ │ ├── @ │ │ ├── F │ │ ├── MkIO │ │ ├── data │ │ ├── getLine │ │ ├── putLine │ │ └── return │ │ ├── Lazy │ │ ├── @ │ │ ├── delay │ │ └── force │ │ ├── Leibnitz │ │ ├── @ │ │ ├── refl │ │ └── theorem │ │ ├── List │ │ ├── @ │ │ ├── Cons │ │ ├── Nil │ │ ├── [++] │ │ ├── [<=<] │ │ ├── [<|>] │ │ ├── [=<<] │ │ ├── [>=>] │ │ ├── [>>=] │ │ ├── all │ │ ├── any │ │ ├── concat │ │ ├── cond │ │ ├── empty │ │ ├── filter │ │ ├── flip │ │ ├── head │ │ ├── length │ │ ├── map │ │ ├── match │ │ ├── match.test │ │ ├── match.test2 │ │ ├── null │ │ ├── pure │ │ ├── replicate │ │ ├── reverse │ │ └── tail │ │ ├── Maybe │ │ ├── 0 │ │ ├── @ │ │ ├── Just │ │ ├── Nothing │ │ ├── [<=<] │ │ ├── [<|>] │ │ ├── [=<<] │ │ ├── [>=>] │ │ ├── [>>=] │ │ ├── empty │ │ ├── map │ │ ├── maybe │ │ └── pure │ │ ├── Mon │ │ ├── @ │ │ ├── Eq │ │ ├── Make │ │ └── get │ │ ├── Monad │ │ ├── @ │ │ ├── [<=<] │ │ ├── [=<<] │ │ ├── [>=>] │ │ ├── [>>=] │ │ ├── forM │ │ ├── forM_ │ │ ├── join │ │ ├── mapM │ │ ├── mapM_ │ │ ├── replicateM │ │ ├── replicateM_ │ │ ├── sequence │ │ └── sequence_ │ │ ├── Monoid │ │ ├── @ │ │ ├── mappend │ │ └── mempty │ │ ├── Morte │ │ ├── corecursive │ │ └── recursive │ │ ├── Nat │ │ ├── @ │ │ ├── Eight │ │ ├── Five │ │ ├── Four │ │ ├── Hundreed │ │ ├── Nine │ │ ├── One │ │ ├── Seven │ │ ├── Six │ │ ├── Succ │ │ ├── Succ2 │ │ ├── Ten │ │ ├── Test │ │ ├── Thousand │ │ ├── Three │ │ ├── Two │ │ ├── Zero │ │ ├── [*] │ │ ├── [+] │ │ ├── fold │ │ ├── odd │ │ ├── product │ │ └── sum │ │ ├── Path │ │ ├── @ │ │ ├── End │ │ └── Step │ │ ├── Prod │ │ ├── @ │ │ ├── Eq │ │ ├── Make │ │ ├── fst │ │ └── snd │ │ ├── Prop │ │ ├── @ │ │ ├── Exists │ │ ├── Exists.proof │ │ ├── False │ │ ├── Proof1 │ │ ├── Theorem1 │ │ ├── True │ │ ├── True.type │ │ └── id │ │ ├── Sigma │ │ ├── @ │ │ ├── Intro │ │ ├── fst │ │ ├── snd │ │ ├── test │ │ ├── test.first │ │ └── test.second │ │ ├── Simple │ │ ├── @ │ │ └── intro │ │ ├── String │ │ └── @ │ │ ├── Unit │ │ ├── @ │ │ ├── Eq │ │ └── Make │ │ ├── Vector │ │ ├── @ │ │ └── Nil │ │ ├── [.] │ │ ├── find │ │ └── id ├── rebar.config ├── syntax │ └── morte │ │ ├── om_parse.erl │ │ └── om_tok.erl └── typechecker │ ├── om_cache.erl │ └── om_type.erl ├── ocaml └── henk.ml └── rust ├── Cargo.toml ├── build.rs └── src ├── ast.rs ├── grammar.lalrpop └── main.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | Makefile linguist-detectable=false 2 | *.html linguist-detectable=false 3 | *.js linguist-detectable=false 4 | *.pug linguist-detectable=false 5 | *.erl linguist-detectable=true 6 | *.hrl linguist-detectable=false 7 | *.app.src linguist-detectable=false 8 | rebar.config linguist-detectable=false 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | package-lock.json 3 | header.html 4 | footer.html 5 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | henk.groupoid.space 2 | -------------------------------------------------------------------------------- /HACKING.md: -------------------------------------------------------------------------------- 1 | Henk Hacking 2 | ============ 3 | 4 | Developers 5 | ---------- 6 | 7 | ``` 8 | $ git clone git://github.com/groupoid/henk && cd henk 9 | $ curl -fsSL https://raw.github.com/synrc/mad/master/mad > mad 10 | $ chmod +x mad" 11 | $ ./mad dep com pla bun henk 12 | $ ./henk 13 | ``` 14 | 15 | Session example with Henk: 16 | 17 | ```erlang 18 | > om:all(). 19 | > om:scan(). 20 | > om:modes(). 21 | ["posets","normal","setoids"] 22 | > om:extract("normal"). 23 | > ch:main(). 24 | Zero: 0 25 | Cons/Nil: [2,1] 26 | Test Big List: [2,3,5,8,11,19] 27 | Two: 2 28 | ok 29 | Pack/Unpack 1 000 000 Inductive List: {714483,'_'} 30 | Pack/Unpack 1 000 000 Inductive Nat: {743755,1000000} 31 | ``` 32 | 33 | ## Extract IO Sample 34 | 35 | ``` 36 | > om:rec(). 37 | > 12 38 | : 12 39 | > 2341414 40 | : 2341414 41 | > kjhfjkashdfk 42 | : kjhfjkashdfk 43 | > 13 44 | : 13 45 | > 132 46 | : 132 47 | #Fun 48 | 49 | > om:corec(). 50 | > 1 51 | : 1 52 | > 0 53 | : 0 54 | #Fun 55 | 56 | ``` 57 | 58 | ## Parser Term Specification 59 | 60 | This information is subject to change. 61 | 62 | ### Result AST 63 | 64 | ```erlang 65 | data pts 66 | = star (n: nat) 67 | | var (n: name) (n: nat) 68 | | remote (n: name) (n: nat) 69 | | app (f a: pts) 70 | | lambda (x: name) (d c: pts) 71 | | arrow (d c: pts) 72 | | pi (x: name) (d c: pts) 73 | ``` 74 | 75 | ## Commands 76 | 77 | ### mode 78 | 79 | Set the environment folder: 80 | 81 | ```erlang 82 | > om:modes(). 83 | ["normal","setoids","posets"] 84 | > om:mode("normal"). 85 | ok 86 | ``` 87 | 88 | ### a 89 | 90 | Inline some terms: 91 | 92 | ```erlang 93 | > om:a("\\(x:*)->\\(y:#List/pure)->y"). 94 | ``` 95 | 96 | ### norm 97 | 98 | Normalization expand remote terms: 99 | 100 | ```erlang 101 | 11> om:a("#List/map"). 102 | 12> om:norm(om:a("#List/map")). 103 | ``` 104 | 105 | ### show 106 | 107 | Use internal functions: 108 | 109 | ```erlang 110 | > om:show("List/@"). 111 | ``` 112 | 113 | ### parse, str 114 | 115 | Wrong Typecheck Example: 116 | 117 | ```erlang 118 | > A = om:str("∀ (a: *) → λ (b: * → * → *) → λ (c: * → a) → (((b (c a)) a) a))"). 119 | > B = om:parse(A). 120 | > om:type(om:snd(B)). 121 | ** exception error: no match of right hand side value {error,{"==",{star,1},{var,{a,0}}}} 122 | ``` 123 | 124 | ### extract 125 | 126 | Extract Erlang Modules: 127 | 128 | ```erlang 129 | > om_extract:extract("priv/normal/List"). 130 | ok 131 | > om_extract:extract("priv/normal"). 132 | ok 133 | > 134 | ``` 135 | 136 | ### main 137 | 138 | Sandbox for testing from bare Erlang. 139 | Example of usage of compiled modules `List` and `Nat`: 140 | 141 | ```erlang 142 | > ch:main(). 143 | Zero: 0 144 | Cons/Nil: [2,1] 145 | Test Big List: [2,3,5,8,11,19] 146 | Two: 2 147 | ok 148 | Pack/Unpack 1 000 000 Inductive List: {733256,'_'} 149 | Pack/Unpack 1 000 000 Inductive Nat: {748433,1000000} 150 | ``` 151 | 152 | `foldl` version of `stdlib` (for comparison): 153 | 154 | ```erlang 155 | > timer:tc(lists,foldl,[fun(X,A) -> A end,0,lists:seq(1,1000000)]). 156 | {735410,0} 157 | ``` 158 | 159 | ### type 160 | 161 | Typechecking: 162 | 163 | ```erlang 164 | > om:type(om:a("#IO/[>>=]")). 165 | ``` 166 | 167 | ### scan 168 | 169 | Scan modules in current mode: 170 | 171 | ```erlang 172 | > om:mode("normal"). 173 | ok 174 | > om:scan(). 175 | ok 176 | ``` 177 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DHARMA License 2 | 3 | Copyright (c) 2016—2022 Groupoid Infinity 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | YOU CANNOT USE THIS SOFTWARE IN ANY (PROVABLE BY MONEY TRACE) 10 | PROCESS CHAIN OF EXTERMINATING UKRAINIANS BY ANY MEANS OF FASCIST 11 | ACTIONS AGAINST OUR TERRITORIAL INTEGRITY, CULTURAL DIVERSITY BY 12 | APPLYING MILITARY INVASIONS, ECONOMICAL WARS, HUMANITARIAN DISASTERS, 13 | ARTFICIAL HOLODOMORS, GENOCIDE, RAPING, LOOTING, ROBBERIES, SPREADING 14 | FAKE INFORMATION, AND OTHER CONTEMPORARY WEAPONS OF WAR AT SCALE 15 | OR IN INVIDIVUAL MANNER. 16 | 17 | YOU CANNOT USE THIS SOFTWARE BY ANY MEANS IN INTEREST OF LEGAL 18 | ENTITIES OR INDIVIDUALS WHO IS SUPPORTING NOW OR WAS SUPPORTING 19 | BACK THEN FASCISM, RUSCISM, COMMUNISM, CHAUVINISM, HUMILIATION, 20 | AND OTHER SUPPRESSIVE IDEOLOGIES IN DIFFERENT EXPRESSIONS. 21 | 22 | STOP KILLING UKRAINIANS, 23 | THE COUNTER RENDERS TENS OF MILLIONS. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 26 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 27 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 28 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 29 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 30 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 31 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Henk Barendregt: Pure Type System 2 | --------------------------------- 3 | 4 | This photo provided exclusively for **Henk** type checker. 5 | 6 | 7 | 8 | # Abstract 9 | 10 | **Henk** languages described first by Erik Meijer and Simon Peyton Jones in 1997. 11 | Later on in 2015 a new implementation of the ideas in Haskell appeared, called Morte. 12 | It used the Böhm-Berarducci encoding of recursive data types into non-recursive terms. 13 | Morte has constants, variables, and kinds, is based only on **П**, **λ** and **apply** constructions, 14 | one axiom and four deduction rules. The Henk language resembles Henk design and Morte implementation. 15 | This language is indended to be small, concise, easily provable, clean and 16 | be able to produce verifiable programs that can be distributed over the networks and compiled at target with safe linkage. 17 | 18 | ``` 19 | $ mix deps.get 20 | $ iex -S mix 21 | ``` 22 | 23 | ## Syntax 24 | 25 | The Henk Syntax is the following: 26 | 27 | ``` 28 | <> ::= #option 29 | 30 | I ::= #identifier 31 | 32 | U ::= * < #number > 33 | 34 | O ::= U | I | ( O ) | O O 35 | | λ ( I : O ) → O 36 | | ∀ ( I : O ) → O 37 | ``` 38 | 39 | Henk is an implementation of PTS with an Infinite Number of Universes, the pure lambda calculus with dependent types. 40 | It can be compiled (code extraction) to bytecode of Erlang virtual machines BEAM and LING. 41 | 42 | ## Semantics 43 | 44 | ### Hierarchy 45 | 46 | The hierarchy function computes the universe level of a type constructor (e.g., a function or product type) 47 | by delegating to dep with a configurable mode. In the code, `hierarchy Arg Out -> dep Arg Out (env om hierarchy impredicative)` 48 | uses an environment variable to choose between impredicative (default) and predicative settings, 49 | allowing flexibility in the type system’s universe structure. Formally, Barendregt describes the hierarchy in PTS via the rules R, 50 | where the resulting sort s3 of a product `Πx:A.B` depends on the sorts of A and B: in impredicative CoC, 51 | while in predicative systems, it may lift to a higher universe. He writes, "The choice of hierarchy rule 52 | determines the expressiveness and consistency of the system" (Barendregt, Lambda Calculus: Its Syntax and 53 | Semantics, 1992, p. 567), which the code reflects by parameterizing this choice. He writes, "The choice of 54 | hierarchy rule determines the expressiveness and consistency of the system" (Barendregt, Lambda Calculus: 55 | Its Syntax and Semantics, 1992, p. 567), which the code reflects by parameterizing this choice. 56 | 57 | ### Star 58 | 59 | The star function extracts or validates the numeric level of a universe sort, central to the infinite hierarchy of types. 60 | In the code, `star (star,N) -> N` returns the integer `N` from a universe term `star N` (e.g., \*0, \*1, 61 | while `star S -> error ("universe",\*,S)` errors out for invalid inputs. Formally, Barendregt defines sorts in PTS as a set 62 | S, such as `{∗,□}` in CoC, or an infinite sequence `\*0 : \*1 : \*2 : ...` in systems with universes, where each 63 | `**n : **(n+1)`. He states, "Sorts form the backbone of the type hierarchy, with each level governing the types 64 | below it" (Barendregt, Introduction to Generalized Type Systems, 1991, p. 6), and the code’s star function directly 65 | supports this by managing universe indices. 66 | 67 | ### Equality 68 | 69 | The `eq` function tests convertibility between two terms, a key aspect of type checking in PTS. 70 | It checks dependent products for equality by comparing domains and codomains with substitution, 71 | while `eq (app (F1,A)) (app (F2,A2)) -> eq(F1, F2), eq(A1, A2)` handles applications. 72 | Formally, Barendregt defines equality as beta-convertibility: 73 | `M =_β N` if `M` and `N` reduce to the same normal form. He writes, "Equality in typed 74 | lambda calculi relies on convertibility, ensuring types align under reduction" (Barendregt, 75 | Introduction to Generalized Type Systems, 1991, p. 17), which eq implements via structural 76 | and substitution-based comparison. 77 | 78 | ### Shift 79 | 80 | The shift function adjusts the indices of free variables in a term to account for changes in the binding context, 81 | such as when a term is moved under a new binder (e.g., a lambda or universal quantifier). In the code, 82 | `shift (var (N,I)) N P when I >= P -> var (N,I+1)` increments the index `I` of a variable named `N` by `1` 83 | if I >= P (the cutoff point), while `shift (∀,(N,0)) (I,O) N P` recursively shifts indices 84 | in the input `I` and output `O` of a dependent function type, adjusting `O` under an additional 85 | binder `P+1`. Formally, per Barendregt, shifting (often denoted as an "up" operation) is defined as: 86 | for a term t, the shifted term `t↑_c^d` increases all free variable indices `i≥c` by `d`, where `c` 87 | is the cutoff and `d` is the shift amount (typically 1). Barendregt states, "The operation `t↑_c^d` 88 | is used to avoid capture of variables when substituting under binders" (Barendregt, Lambda Calculus: Its Syntax and Semantics, 1992, p. 49), 89 | ensuring that free variables retain their intended references during term manipulation. 90 | 91 | ### Substitution 92 | 93 | The subst function performs substitution, replacing a variable in a term with another term, 94 | while respecting the binding structure to avoid variable capture. In the code, 95 | `subst (var (N,L)) N V L -> V` replaces a variable with index L matching the 96 | current level with the value `V`, while `subst ((λ,(N,0)),(I,O)) N V L -> ((λ,(N,0)),(subst I N V L, subst O N shift(V,N,0) L+1))` 97 | substitutes in a lambda term, shifting `V` to adjust for the new binder in `O`. 98 | Formally, Barendregt defines substitution as: for a term `t`, variable `x`, and term `u`, 99 | the substitution `t[x:=u]` replaces all free occurrences of `x` in `t` with `u`, 100 | with indices adjusted to prevent capture by binders. He writes, "Substitution `t[x:=u]` 101 | must ensure that free variables in `u` are not accidentally bound by binders in 102 | `t`, necessitating a careful adjustment of indices" (Barendregt, Introduction to 103 | Generalized Type Systems, 1991, p. 15), which aligns with the code’s use of shift 104 | within subst to maintain correctness in dependent type systems like the Calculus of Constructions. 105 | 106 | ### Normalization 107 | 108 | The norm function computes the normal form of a term, performing beta reduction and structural 109 | normalization. In the code, `norm (app (F,A)) -> case norm(F) of ((λ,(N,0)),(O,O)) -> norm(subst(O,N,A))` 110 | reduces applications by substituting into lambdas, while `norm (→,(I,O)) -> ((∀,(_,0)),(norm(I),norm(O)))` 111 | rewrites function types as dependent products. Formally, Barendregt defines normalization as reducing a 112 | term to its normal form via beta reduction, where `(λx.M)N→M[x:=N]`, ensuring strong normalization 113 | in systems like CoC. He states, "Normalization guarantees that every typable term has a unique 114 | normal form, critical for consistency" (Barendregt, Lambda Calculus: Its Syntax and Semantics, 1992, p. 62), 115 | which norm achieves through recursive reduction. 116 | 117 | ### Type Inference 118 | 119 | The type function infers or checks the type of a term in a given context, enforcing the PTS typing rules. 120 | In the code, `type (star N) _ -> star (N+1)` assigns each universe its successor, `type ((∀,(N,0)),(I,O)) D -> star hierarchy(star(type(I,D)), star(type(O,[{N,norm(I)}|D])))` 121 | types dependent products, and `type (app (F,A)) D` handles applications by matching function 122 | types and substituting. Formally, Barendregt defines typing in PTS via judgments `Γ ⊢ M : A`, 123 | governed by rules like `Γ⊢Πx:A.B:s3 if Γ⊢A:s1 /\ Γ,x:A⊢B:s2` for products. He notes, "The typing 124 | relation ensures that every term inhabits a sort or type, preserving the hierarchy" (Barendregt, 125 | Lambda Calculus: Its Syntax and Semantics, 1992, p. 568), which type upholds by recursively computing types within the context. 126 | 127 | ## Artefact 128 | 129 | In repository `henk` you may find the following parts of core: 130 | 131 | * [Parser](https://github.com/groupoid/henk/blob/main/src/elixir/syntax/morte/om_parse.erl) 132 | * [Type Checker](https://github.com/groupoid/henk/blob/main/src/elixir/typechecker/om_type.erl) 133 | * [Eraser](https://github.com/groupoid/henk/blob/main/src/elixir/extractor/om_erase.erl) 134 | * [Code Extractor](https://github.com/groupoid/henk/blob/main/src/elixir/extractor/om_extract.erl) 135 | 136 | Henk ships with different "modes" (spaces of types with own encodings), or "preludes", which 137 | you may find in `lib` directory. They are selectable with `om:mode("normal")`. 138 | 139 | #### [Henk Library](https://github.com/groupoid/henk/tree/main/src/elixir/priv/Morte) 140 | 141 | ```sh 142 | henk.groupoid.space/src/elixir/priv/Morte 143 | ├── Bool 144 | ├── Cmd 145 | ├── Eq 146 | ├── Equ 147 | ├── Frege 148 | ├── IO 149 | ├── IOI 150 | ├── Lazy 151 | ├── Leibnitz 152 | ├── List 153 | ├── Maybe 154 | ├── Mon 155 | ├── Monad 156 | ├── Monoid 157 | ├── Morte 158 | ├── Nat 159 | ├── Path 160 | ├── Prod 161 | ├── Prop 162 | ├── Sigma 163 | ├── Simple 164 | ├── String 165 | ├── Unit 166 | └── Vector 167 | ``` 168 | 169 | This is a minimal practical prelude similar to Morte's base library of Gabriella Gonzalez. 170 | It contains common inductive constructions encoded using plain Church (or Böhm-Berarducci if you wish) encoding, 171 | and two basic (co)monadic effect systems: IO (free monad, for finite I/O) and IOI (free comonad, 172 | for infinitary I/O, long-term processes). The generated code is being sewed with 173 | Erlang effects that are passed as parameters to pure functions. 174 | 175 | Note: all these folders (modules) are encoded in plain CoC in Henk repository to demonstrate 176 | you the basic principles how things work. Later all these should be written in Per 177 | languages and translated to Henk automatically (if possible). You may think of Henk as the low-level 178 | typed assembler of type theory. 179 | 180 | PTS 181 | --- 182 | 183 | * AUTOMATH, a language for mathematics. [Nicolaas Govert de Bruijn] 184 | * Lambda Calculi with Types [Henk Barendregt] 185 | * The Calculus of Constructions [Thierry Coquand, Gerard Huet] 186 | * Introduction to Generalized Type Systems [Henk Barendregt] 187 | * Some remarks about Dependent Type Theory [Thierry Coquand] 188 | * Henk: a typed intermediate language [Erik Meijer, Simon Peyton Jones] 189 | * Morte: an intermediate language for super-optimizing functional programs [Gabriella Gonzalez] 190 | * Henk: Pure Type System for Erlang [Maksym Sokhatskyi] 191 | * Система доведення теорем з однiєю аксiомою [Maksym Sokhatskyi] 192 | 193 | Credits 194 | ------- 195 | 196 | * Maksym Sokhatskyi 🇺🇦 197 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | default: 2 | pdflatex pts.tex 3 | bibtex pts 4 | pdflatex pts.tex 5 | pdflatex pts.tex 6 | pdflatex pts_ua.tex 7 | bibtex pts_ua 8 | pdflatex pts_ua.tex 9 | pdflatex pts_ua.tex 10 | return 0 11 | 12 | clean: 13 | rm -f *.toc 14 | rm -f *.aux 15 | rm -f *.log 16 | rm -f *.out 17 | rm -f *.bbl 18 | rm -f *.blg 19 | 20 | -------------------------------------------------------------------------------- /doc/henk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/doc/henk.pdf -------------------------------------------------------------------------------- /doc/pts.bbl: -------------------------------------------------------------------------------- 1 | \begin{thebibliography}{10} 2 | 3 | \bibitem{Kaposi16} 4 | Thorsten Altenkirch and Ambrus Kaposi. 5 | \newblock Type theory in type theory using quotient inductive types. 6 | \newblock In {\em Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT Symposium 7 | on Principles of Programming Languages}, POPL '16, pages 18--29, New York, 8 | NY, USA, 2016. ACM. 9 | 10 | \bibitem{Henk93} 11 | H.~P. Barendregt. 12 | \newblock In S.~Abramsky, Dov~M. Gabbay, and S.~E. Maibaum, editors, {\em 13 | Handbook of Logic in Computer Science (Vol. 2)}, pages 117--309, New York, 14 | NY, USA, 1992. Oxford University Press, Inc. 15 | 16 | \bibitem{Barthe95} 17 | Gilles Barthe. 18 | \newblock {\em Extensions of pure type systems}, pages 16--31. 19 | \newblock Springer Berlin Heidelberg, Berlin, Heidelberg, 1995. 20 | 21 | \bibitem{Bohm85} 22 | Corrado B{\"o}hm and Alessandro Berarducci. 23 | \newblock Automatic synthesis of typed lambda-programs on term algebras. 24 | \newblock In {\em Theoretical Computer Science}, volume~39, pages 135--154, 25 | 1985. 26 | 27 | \bibitem{Mortberg17} 28 | Cyril Cohen, Thierry Coquand, Simon Huber, and Anders M{\"{o}}rtberg. 29 | \newblock In {\em Cubical Type Theory: a constructive interpretation of the 30 | univalence axiom}, volume abs/1611.02108, 2017. 31 | 32 | \bibitem{Coq96} 33 | Thierry Coquand. 34 | \newblock An algorithm for type-checking dependent types. 35 | \newblock In {\em Sci. Comput. Program.}, volume~26, pages 167--177, 1996. 36 | 37 | \bibitem{Coq88} 38 | Thierry Coquand and Gerard Huet. 39 | \newblock The calculus of constructions. 40 | \newblock In {\em Information and Computation}, pages 95--120, Duluth, MN, USA, 41 | 1988. Academic Press, Inc. 42 | 43 | \bibitem{Dagand13} 44 | P.{\'E}. Dagand, University of~Strathclyde. Department~of Computer, and 45 | PhD~thesis Information~Sciences. 46 | \newblock {\em A Cosmology of Datatypes: Reusability and Dependent Types}. 47 | \newblock 2013. 48 | 49 | \bibitem{Fu14} 50 | Peng Fu and Aaron Stump. 51 | \newblock Self types for dependently typed lambda encodings. 52 | \newblock In {\em Rewriting and Typed Lambda Calculi - Joint International 53 | Conference, {RTA-TLCA} 2014, Held as Part of the Vienna Summer of Logic, 54 | {VSL} 2014, Vienna, Austria, July 14-17, 2014. Proceedings}, pages 224--239, 55 | 2014. 56 | 57 | \bibitem{Geuvers01} 58 | Herman Geuvers. 59 | \newblock {\em Induction Is Not Derivable in Second Order Dependent Type 60 | Theory}, pages 166--181. 61 | \newblock Springer Berlin Heidelberg, Berlin, Heidelberg, 2001. 62 | 63 | \bibitem{Hamana11} 64 | Makoto Hamana and Marcelo~P. Fiore. 65 | \newblock A foundation for gadts and inductive families: dependent polynomial 66 | functor approach. 67 | \newblock In {\em Proceedings of the seventh {ACM} {SIGPLAN} workshop on 68 | Generic programming, WGP@ICFP 2011, Tokyo, Japan, September 19-21, 2011}, 69 | pages 59--70, 2011. 70 | 71 | \bibitem{Hinze13} 72 | Ralf Hinze and Nicolas Wu. 73 | \newblock Histo- and dynamorphisms revisited. 74 | \newblock In {\em Proceedings of the 9th ACM SIGPLAN Workshop on Generic 75 | Programming}, WGP '13, pages 1--12, New York, NY, USA, 2013. ACM. 76 | 77 | \bibitem{Erik97} 78 | Simon~Peyton Jones and Erik Meijer. 79 | \newblock Henk: A typed intermediate language. 80 | \newblock In {\em In Proc. First Int'l Workshop on Types in Compilation}, 1997. 81 | 82 | \bibitem{Lof84} 83 | P.~Martin-L{\"o}f and G.~Sambin. 84 | \newblock {\em Intuitionistic type theory}. 85 | \newblock Studies in proof theory. Bibliopolis, 1984. 86 | 87 | \bibitem{Ore92} 88 | Christian-Emil Ore. 89 | \newblock The extended calculus of constructions (ecc) with inductive types. 90 | \newblock In {\em Information and Computation}, volume~99, pages 231 -- 264, 91 | 1992. 92 | 93 | \bibitem{Mohring15} 94 | Christine Paulin-Mohring. 95 | \newblock {Introduction to the Calculus of Inductive Constructions}. 96 | \newblock In Bruno~Woltzenlogel Paleo and David Delahaye, editors, {\em {All 97 | about Proofs, Proofs for All}}, volume~55 of {\em Studies in Logic 98 | (Mathematical logic and foundations)}. {College Publications}, January 2015. 99 | 100 | \bibitem{Stump17} 101 | Aaron Stump. 102 | \newblock The calculus of dependent lambda eliminations. 103 | \newblock In {\em Journal of Functional Programming}, volume~27. Cambridge 104 | University Press, 2017. 105 | 106 | \end{thebibliography} 107 | -------------------------------------------------------------------------------- /doc/pts.bib: -------------------------------------------------------------------------------- 1 | @book{MacLane71, 2 | added-at = {2009-09-18T21:22:09.000+0200}, 3 | address = {New York}, 4 | author = {MacLane, Saunders}, 5 | biburl = {https://www.bibsonomy.org/bibtex/29e8ca8b4bf357cc41e40e98cca25cb8c/minas}, 6 | interhash = {51566d046db4c3ea930c2b5ca79173f1}, 7 | intrahash = {9e8ca8b4bf357cc41e40e98cca25cb8c}, 8 | keywords = {CategoryTheory}, 9 | mrclass = {18-02}, 10 | mrnumber = {MR0354798 (50 \#7275)}, 11 | mrreviewer = {H.-B. Brinkmann}, 12 | note = {Graduate Texts in Mathematics, Vol. 5}, 13 | pages = {ix+262}, 14 | publisher = {Springer-Verlag}, 15 | timestamp = {2009-09-18T21:22:09.000+0200}, 16 | title = {Categories for the Working Mathematician}, 17 | year = {1971} 18 | } 19 | 20 | @INPROCEEDINGS{Erik97, 21 | author = {Simon Peyton Jones and Erik Meijer}, 22 | title = {Henk: A Typed Intermediate Language}, 23 | booktitle = {In Proc. First Int'l Workshop on Types in Compilation}, 24 | year = {1997} 25 | } 26 | 27 | @inproceedings{Henk93, 28 | author = {Barendregt, H. P.}, 29 | chapter = {Lambda Calculi with Types}, 30 | booktitle = {Handbook of Logic in Computer Science (Vol. 2)}, 31 | editor = {Abramsky, S. and Gabbay, Dov M. and Maibaum, S. E.}, 32 | year = {1992}, 33 | isbn = {0-19-853761-1}, 34 | pages = {117--309}, 35 | numpages = {193}, 36 | url = {http://dl.acm.org/citation.cfm?id=162552.162561}, 37 | acmid = {162561}, 38 | publisher = {Oxford University Press, Inc.}, 39 | address = {New York, NY, USA}, 40 | } 41 | 42 | @inproceedings{Coq88, 43 | author = {Coquand, Thierry and Huet, Gerard}, 44 | title = {The Calculus of Constructions}, 45 | booktitle = {Information and Computation}, 46 | year = {1988}, 47 | issn = {0890-5401}, 48 | pages = {95--120}, 49 | numpages = {26}, 50 | url = {http://dx.doi.org/10.1016/0890-5401(88)90005-3}, 51 | doi = {10.1016/0890-5401(88)90005-3}, 52 | acmid = {47725}, 53 | publisher = {Academic Press, Inc.}, 54 | address = {Duluth, MN, USA}, 55 | } 56 | 57 | @inproceedings{Pfenning89, 58 | author = {Frank Pfenning and Christine Paulin{-}Mohring}, 59 | title = {Inductively Defined Types in the Calculus of Constructions}, 60 | booktitle = {Mathematical Foundations of Programming Semantics, 5th International 61 | Conference, Tulane University, New Orleans, Louisiana, USA, March 62 | 29 - April 1, 1989, Proceedings}, 63 | pages = {209--228}, 64 | year = {1989}, 65 | crossref = {DBLP:conf/mfps/1989}, 66 | url = {https://doi.org/10.1007/BFb0040259}, 67 | doi = {10.1007/BFb0040259}, 68 | timestamp = {Fri, 19 May 2017 13:10:47 +0200}, 69 | biburl = {http://dblp.org/rec/bib/conf/mfps/PfenningP89}, 70 | bibsource = {dblp computer science bibliography, http://dblp.org} 71 | } 72 | 73 | @incollection{Mohring15, 74 | TITLE = {{Introduction to the Calculus of Inductive Constructions}}, 75 | AUTHOR = {Paulin-Mohring, Christine}, 76 | URL = {https://hal.inria.fr/hal-01094195}, 77 | BOOKTITLE = {{All about Proofs, Proofs for All}}, 78 | EDITOR = {Bruno Woltzenlogel Paleo and David Delahaye}, 79 | PUBLISHER = {{College Publications}}, 80 | SERIES = {Studies in Logic (Mathematical logic and foundations)}, 81 | VOLUME = {55}, 82 | YEAR = {2015}, 83 | MONTH = Jan, 84 | KEYWORDS = {Coq proof assistant ; Calculus of Inductive Constructions}, 85 | PDF = {https://hal.inria.fr/hal-01094195/file/CIC.pdf}, 86 | HAL_ID = {hal-01094195}, 87 | HAL_VERSION = {v1}, 88 | } 89 | 90 | @inproceedings{Ore92, 91 | title = "The Extended Calculus of Constructions (ECC) with inductive types", 92 | booktitle = "Information and Computation", 93 | volume = "99", 94 | number = "2", 95 | pages = "231 - 264", 96 | year = "1992", 97 | issn = "0890-5401", 98 | doi = "https://doi.org/10.1016/0890-5401(92)90031-A", 99 | url = "http://www.sciencedirect.com/science/article/pii/089054019290031A", 100 | author = "Christian-Emil Ore" 101 | } 102 | 103 | @Inbook{Barthe95, 104 | author="Barthe, Gilles", 105 | editor="Dezani-Ciancaglini, Mariangiola 106 | and Plotkin, Gordon", 107 | title="Extensions of pure type systems", 108 | bookTitle="Typed Lambda Calculi and Applications: Second International Conference on Typed Lambda Calculi and Applications, TLCA '95 Edinburgh, United Kingdom, April 10--12, 1995 Proceedings", 109 | year="1995", 110 | publisher="Springer Berlin Heidelberg", 111 | address="Berlin, Heidelberg", 112 | pages="16--31", 113 | abstract="We extend pure type systems with quotient types and subset types and establish an equivalence between four strong normalisation problems: subset types, quotient types, definitions and the so-called K-rules. As a corollary, we get strong normalisation of ECC with definitions, subset and quotient types.", 114 | isbn="978-3-540-49178-1", 115 | doi="10.1007/BFb0014042", 116 | url="https://doi.org/10.1007/BFb0014042" 117 | } 118 | 119 | @inproceedings{Fu14, 120 | author = {Peng Fu and Aaron Stump}, 121 | title = {Self Types for Dependently Typed Lambda Encodings}, 122 | booktitle = {Rewriting and Typed Lambda Calculi - Joint International Conference, 123 | {RTA-TLCA} 2014, Held as Part of the Vienna Summer of Logic, {VSL} 124 | 2014, Vienna, Austria, July 14-17, 2014. Proceedings}, 125 | pages = {224--239}, 126 | year = {2014}, 127 | url = {https://doi.org/10.1007/978-3-319-08918-8_16}, 128 | doi = {10.1007/978-3-319-08918-8_16}, 129 | timestamp = {Tue, 23 May 2017 01:10:28 +0200}, 130 | biburl = {http://dblp.org/rec/bib/conf/rta/FuS14}, 131 | } 132 | 133 | @book{Lof84, 134 | title = {Intuitionistic type theory}, 135 | author = {Martin-L{\"o}f, P. and Sambin, G.}, 136 | series = {Studies in proof theory}, 137 | url = {https://books.google.com.ua/books?id=\_D0ZAQAAIAAJ}, 138 | year = {1984}, 139 | publisher = {Bibliopolis} 140 | } 141 | 142 | @inproceedings{Stump17, 143 | title = {The calculus of dependent lambda eliminations}, 144 | volume = {27}, 145 | DOI = {10.1017/S0956796817000053}, 146 | booktitle = {Journal of Functional Programming}, 147 | publisher = {Cambridge University Press}, 148 | year = {2017}, 149 | author = {Stump, Aaron} 150 | } 151 | 152 | @Inbook{Geuvers01, 153 | author = "Geuvers, Herman", 154 | editor = "Abramsky, Samson", 155 | title = "Induction Is Not Derivable in Second Order Dependent Type Theory", 156 | bookTitle = "Typed Lambda Calculi and Applications: 5th International Conference, TLCA 2001 Krak{\'o}w, Poland, May 2--5, 2001 Proceedings", 157 | year = "2001", 158 | publisher = "Springer Berlin Heidelberg", 159 | address = "Berlin, Heidelberg", 160 | pages = "166--181", 161 | abstract = "This paper proves the non-derivability of induction in second order dependent type theory ($\lambda$P2). This is done by providing a model construction for $\lambda$P2, based on a saturated sets like interpretation of types as sets of terms of a weakly extensional combinatory algebra. We give counter-models in which the induction principle over natural numbers is not valid. The proof does not depend on the specific encoding for natural numbers that has been chosen (like e.g. polymorphic Church numerals), so in fact we prove that there can not be an encoding of natural numbers in $\lambda$P2 such that the induction principle is satisfied. The method extends immediately to other data types, like booleans, lists, trees, etc.", 162 | isbn = "978-3-540-45413-7", 163 | doi = "10.1007/3-540-45413-6_16", 164 | url = "https://doi.org/10.1007/3-540-45413-6_16" 165 | } 166 | 167 | @inproceedings{Bohm85, 168 | author = {Corrado B{\"o}hm and Alessandro Berarducci}, 169 | title = {Automatic synthesis of typed Lambda-programs on term algebras}, 170 | volume = {39}, 171 | number = {2-3}, 172 | bookTitle = {Theoretical Computer Science}, 173 | year = {1985}, 174 | pages = {135--154} 175 | } 176 | 177 | @inproceedings{Hinze13, 178 | author = {Hinze, Ralf and Wu, Nicolas}, 179 | title = {Histo- and Dynamorphisms Revisited}, 180 | booktitle = {Proceedings of the 9th ACM SIGPLAN Workshop on Generic Programming}, 181 | series = {WGP '13}, 182 | year = {2013}, 183 | isbn = {978-1-4503-2389-5}, 184 | location = {Boston, Massachusetts, USA}, 185 | pages = {1--12}, 186 | numpages = {12}, 187 | url = {http://doi.acm.org/10.1145/2502488.2502496}, 188 | doi = {10.1145/2502488.2502496}, 189 | acmid = {2502496}, 190 | publisher = {ACM}, 191 | address = {New York, NY, USA}, 192 | keywords = {dynamic programming, dynamorphisms, histomorphisms, recursion schemes}, 193 | } 194 | 195 | @book{Dagand13, 196 | title = {A Cosmology of Datatypes: Reusability and Dependent Types}, 197 | author = {Dagand, P.{\'E}. and University of Strathclyde. Department of Computer and Information Sciences, PhD thesis}, 198 | url = {https://books.google.com.ua/books?id=7RF8nQAACAAJ}, 199 | year = {2013} 200 | } 201 | 202 | @inproceedings{Kaposi16, 203 | author = {Altenkirch, Thorsten and Kaposi, Ambrus}, 204 | title = {Type Theory in Type Theory Using Quotient Inductive Types}, 205 | booktitle = {Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages}, 206 | series = {POPL '16}, 207 | year = {2016}, 208 | isbn = {978-1-4503-3549-2}, 209 | location = {St. Petersburg, FL, USA}, 210 | pages = {18--29}, 211 | numpages = {12}, 212 | url = {http://doi.acm.org/10.1145/2837614.2837638}, 213 | doi = {10.1145/2837614.2837638}, 214 | acmid = {2837638}, 215 | publisher = {ACM}, 216 | address = {New York, NY, USA}, 217 | keywords = {Agda, Higher Inductive Types, Homotopy Type Theory, Logical Relations, Metaprogramming}, 218 | } 219 | 220 | @inproceedings{Hamana11, 221 | author = {Makoto Hamana and Marcelo P. Fiore}, 222 | title = {A foundation for GADTs and inductive families: dependent polynomial functor approach}, 223 | booktitle = {Proceedings of the seventh {ACM} {SIGPLAN} workshop on Generic programming, WGP@ICFP 2011, Tokyo, Japan, September 19-21, 2011}, 224 | pages = {59--70}, 225 | year = {2011}, 226 | url = {http://doi.acm.org/10.1145/2036918.2036927}, 227 | doi = {10.1145/2036918.2036927}, 228 | timestamp = {Mon, 18 Jan 2016 16:05:02 +0100}, 229 | biburl = {http://dblp.org/rec/bib/conf/icfp/HamanaF11}, 230 | } 231 | 232 | @inproceedings{Mortberg17, 233 | author = {Cyril Cohen and Thierry Coquand and Simon Huber and Anders M{\"{o}}rtberg}, 234 | booktitle = {Cubical Type Theory: a constructive interpretation of the univalence axiom}, 235 | journal = {CoRR}, 236 | volume = {abs/1611.02108}, 237 | year = {2017} 238 | } 239 | 240 | @inproceedings{Coq96, 241 | author = {Thierry Coquand}, 242 | title = {An Algorithm for Type-Checking Dependent Types}, 243 | booktitle = {Sci. Comput. Program.}, 244 | volume = {26}, 245 | number = {1-3}, 246 | pages = {167--177}, 247 | year = {1996} 248 | } 249 | 250 | -------------------------------------------------------------------------------- /doc/pts.blg: -------------------------------------------------------------------------------- 1 | This is BibTeX, Version 0.99d (TeX Live 2020/Debian) 2 | Capacity: max_strings=200000, hash_size=200000, hash_prime=170003 3 | The top-level auxiliary file: pts.aux 4 | The style file: plain.bst 5 | Database file #1: pts_ua.bib 6 | Warning--empty title in Henk93 7 | Warning--can't use both author and editor fields in Barthe95 8 | Warning--can't use both volume and number fields in Bohm85 9 | Warning--empty title in Mortberg17 10 | Warning--can't use both volume and number fields in Coq96 11 | Warning--empty publisher in Dagand13 12 | Warning--can't use both author and editor fields in Geuvers01 13 | Warning--can't use both volume and number fields in Ore92 14 | You've used 17 entries, 15 | 2118 wiz_defined-function locations, 16 | 629 strings with 7220 characters, 17 | and the built_in function-call counts, 6517 in all, are: 18 | = -- 655 19 | > -- 213 20 | < -- 17 21 | + -- 88 22 | - -- 65 23 | * -- 392 24 | := -- 966 25 | add.period$ -- 56 26 | call.type$ -- 17 27 | change.case$ -- 75 28 | chr.to.int$ -- 0 29 | cite$ -- 25 30 | duplicate$ -- 323 31 | empty$ -- 584 32 | format.name$ -- 65 33 | if$ -- 1481 34 | int.to.chr$ -- 0 35 | int.to.str$ -- 17 36 | missing$ -- 21 37 | newline$ -- 86 38 | num.names$ -- 38 39 | pop$ -- 123 40 | preamble$ -- 1 41 | purify$ -- 64 42 | quote$ -- 0 43 | skip$ -- 243 44 | stack$ -- 0 45 | substring$ -- 405 46 | swap$ -- 126 47 | text.length$ -- 17 48 | text.prefix$ -- 0 49 | top$ -- 0 50 | type$ -- 60 51 | warning$ -- 8 52 | while$ -- 68 53 | width$ -- 19 54 | write$ -- 199 55 | (There were 8 warnings) 56 | -------------------------------------------------------------------------------- /doc/pts_ua.bib: -------------------------------------------------------------------------------- 1 | @book{MacLane71, 2 | added-at = {2009-09-18T21:22:09.000+0200}, 3 | address = {New York}, 4 | author = {MacLane, Saunders}, 5 | biburl = {https://www.bibsonomy.org/bibtex/29e8ca8b4bf357cc41e40e98cca25cb8c/minas}, 6 | interhash = {51566d046db4c3ea930c2b5ca79173f1}, 7 | intrahash = {9e8ca8b4bf357cc41e40e98cca25cb8c}, 8 | keywords = {CategoryTheory}, 9 | mrclass = {18-02}, 10 | mrnumber = {MR0354798 (50 \#7275)}, 11 | mrreviewer = {H.-B. Brinkmann}, 12 | note = {Graduate Texts in Mathematics, Vol. 5}, 13 | pages = {ix+262}, 14 | publisher = {Springer-Verlag}, 15 | timestamp = {2009-09-18T21:22:09.000+0200}, 16 | title = {Categories for the Working Mathematician}, 17 | year = {1971} 18 | } 19 | 20 | @INPROCEEDINGS{Erik97, 21 | author = {Simon Peyton Jones and Erik Meijer}, 22 | title = {Henk: A Typed Intermediate Language}, 23 | booktitle = {In Proc. First Int'l Workshop on Types in Compilation}, 24 | year = {1997} 25 | } 26 | 27 | @inproceedings{Henk93, 28 | author = {Barendregt, H. P.}, 29 | chapter = {Lambda Calculi with Types}, 30 | booktitle = {Handbook of Logic in Computer Science (Vol. 2)}, 31 | editor = {Abramsky, S. and Gabbay, Dov M. and Maibaum, S. E.}, 32 | year = {1992}, 33 | isbn = {0-19-853761-1}, 34 | pages = {117--309}, 35 | numpages = {193}, 36 | url = {http://dl.acm.org/citation.cfm?id=162552.162561}, 37 | acmid = {162561}, 38 | publisher = {Oxford University Press, Inc.}, 39 | address = {New York, NY, USA}, 40 | } 41 | 42 | @inproceedings{Coq88, 43 | author = {Coquand, Thierry and Huet, Gerard}, 44 | title = {The Calculus of Constructions}, 45 | booktitle = {Information and Computation}, 46 | year = {1988}, 47 | issn = {0890-5401}, 48 | pages = {95--120}, 49 | numpages = {26}, 50 | url = {http://dx.doi.org/10.1016/0890-5401(88)90005-3}, 51 | doi = {10.1016/0890-5401(88)90005-3}, 52 | acmid = {47725}, 53 | publisher = {Academic Press, Inc.}, 54 | address = {Duluth, MN, USA}, 55 | } 56 | 57 | @inproceedings{Pfenning89, 58 | author = {Frank Pfenning and Christine Paulin{-}Mohring}, 59 | title = {Inductively Defined Types in the Calculus of Constructions}, 60 | booktitle = {Mathematical Foundations of Programming Semantics, 5th International 61 | Conference, Tulane University, New Orleans, Louisiana, USA, March 62 | 29 - April 1, 1989, Proceedings}, 63 | pages = {209--228}, 64 | year = {1989}, 65 | crossref = {DBLP:conf/mfps/1989}, 66 | url = {https://doi.org/10.1007/BFb0040259}, 67 | doi = {10.1007/BFb0040259}, 68 | timestamp = {Fri, 19 May 2017 13:10:47 +0200}, 69 | biburl = {http://dblp.org/rec/bib/conf/mfps/PfenningP89}, 70 | bibsource = {dblp computer science bibliography, http://dblp.org} 71 | } 72 | 73 | @incollection{Mohring15, 74 | TITLE = {{Introduction to the Calculus of Inductive Constructions}}, 75 | AUTHOR = {Paulin-Mohring, Christine}, 76 | URL = {https://hal.inria.fr/hal-01094195}, 77 | BOOKTITLE = {{All about Proofs, Proofs for All}}, 78 | EDITOR = {Bruno Woltzenlogel Paleo and David Delahaye}, 79 | PUBLISHER = {{College Publications}}, 80 | SERIES = {Studies in Logic (Mathematical logic and foundations)}, 81 | VOLUME = {55}, 82 | YEAR = {2015}, 83 | MONTH = Jan, 84 | KEYWORDS = {Coq proof assistant ; Calculus of Inductive Constructions}, 85 | PDF = {https://hal.inria.fr/hal-01094195/file/CIC.pdf}, 86 | HAL_ID = {hal-01094195}, 87 | HAL_VERSION = {v1}, 88 | } 89 | 90 | @inproceedings{Ore92, 91 | title = "The Extended Calculus of Constructions (ECC) with inductive types", 92 | booktitle = "Information and Computation", 93 | volume = "99", 94 | number = "2", 95 | pages = "231 - 264", 96 | year = "1992", 97 | issn = "0890-5401", 98 | doi = "https://doi.org/10.1016/0890-5401(92)90031-A", 99 | url = "http://www.sciencedirect.com/science/article/pii/089054019290031A", 100 | author = "Christian-Emil Ore" 101 | } 102 | 103 | @Inbook{Barthe95, 104 | author="Barthe, Gilles", 105 | editor="Dezani-Ciancaglini, Mariangiola 106 | and Plotkin, Gordon", 107 | title="Extensions of pure type systems", 108 | bookTitle="Typed Lambda Calculi and Applications: Second International Conference on Typed Lambda Calculi and Applications, TLCA '95 Edinburgh, United Kingdom, April 10--12, 1995 Proceedings", 109 | year="1995", 110 | publisher="Springer Berlin Heidelberg", 111 | address="Berlin, Heidelberg", 112 | pages="16--31", 113 | abstract="We extend pure type systems with quotient types and subset types and establish an equivalence between four strong normalisation problems: subset types, quotient types, definitions and the so-called K-rules. As a corollary, we get strong normalisation of ECC with definitions, subset and quotient types.", 114 | isbn="978-3-540-49178-1", 115 | doi="10.1007/BFb0014042", 116 | url="https://doi.org/10.1007/BFb0014042" 117 | } 118 | 119 | @inproceedings{Fu14, 120 | author = {Peng Fu and Aaron Stump}, 121 | title = {Self Types for Dependently Typed Lambda Encodings}, 122 | booktitle = {Rewriting and Typed Lambda Calculi - Joint International Conference, 123 | {RTA-TLCA} 2014, Held as Part of the Vienna Summer of Logic, {VSL} 124 | 2014, Vienna, Austria, July 14-17, 2014. Proceedings}, 125 | pages = {224--239}, 126 | year = {2014}, 127 | url = {https://doi.org/10.1007/978-3-319-08918-8_16}, 128 | doi = {10.1007/978-3-319-08918-8_16}, 129 | timestamp = {Tue, 23 May 2017 01:10:28 +0200}, 130 | biburl = {http://dblp.org/rec/bib/conf/rta/FuS14}, 131 | } 132 | 133 | @book{Lof84, 134 | title = {Intuitionistic type theory}, 135 | author = {Martin-L{\"o}f, P. and Sambin, G.}, 136 | series = {Studies in proof theory}, 137 | url = {https://books.google.com.ua/books?id=\_D0ZAQAAIAAJ}, 138 | year = {1984}, 139 | publisher = {Bibliopolis} 140 | } 141 | 142 | @inproceedings{Stump17, 143 | title = {The calculus of dependent lambda eliminations}, 144 | volume = {27}, 145 | DOI = {10.1017/S0956796817000053}, 146 | booktitle = {Journal of Functional Programming}, 147 | publisher = {Cambridge University Press}, 148 | year = {2017}, 149 | author = {Stump, Aaron} 150 | } 151 | 152 | @Inbook{Geuvers01, 153 | author = "Geuvers, Herman", 154 | editor = "Abramsky, Samson", 155 | title = "Induction Is Not Derivable in Second Order Dependent Type Theory", 156 | bookTitle = "Typed Lambda Calculi and Applications: 5th International Conference, TLCA 2001 Krak{\'o}w, Poland, May 2--5, 2001 Proceedings", 157 | year = "2001", 158 | publisher = "Springer Berlin Heidelberg", 159 | address = "Berlin, Heidelberg", 160 | pages = "166--181", 161 | abstract = "This paper proves the non-derivability of induction in second order dependent type theory ($\lambda$P2). This is done by providing a model construction for $\lambda$P2, based on a saturated sets like interpretation of types as sets of terms of a weakly extensional combinatory algebra. We give counter-models in which the induction principle over natural numbers is not valid. The proof does not depend on the specific encoding for natural numbers that has been chosen (like e.g. polymorphic Church numerals), so in fact we prove that there can not be an encoding of natural numbers in $\lambda$P2 such that the induction principle is satisfied. The method extends immediately to other data types, like booleans, lists, trees, etc.", 162 | isbn = "978-3-540-45413-7", 163 | doi = "10.1007/3-540-45413-6_16", 164 | url = "https://doi.org/10.1007/3-540-45413-6_16" 165 | } 166 | 167 | @inproceedings{Bohm85, 168 | author = {Corrado B{\"o}hm and Alessandro Berarducci}, 169 | title = {Automatic synthesis of typed Lambda-programs on term algebras}, 170 | volume = {39}, 171 | number = {2-3}, 172 | bookTitle = {Theoretical Computer Science}, 173 | year = {1985}, 174 | pages = {135--154} 175 | } 176 | 177 | @inproceedings{Hinze13, 178 | author = {Hinze, Ralf and Wu, Nicolas}, 179 | title = {Histo- and Dynamorphisms Revisited}, 180 | booktitle = {Proceedings of the 9th ACM SIGPLAN Workshop on Generic Programming}, 181 | series = {WGP '13}, 182 | year = {2013}, 183 | isbn = {978-1-4503-2389-5}, 184 | location = {Boston, Massachusetts, USA}, 185 | pages = {1--12}, 186 | numpages = {12}, 187 | url = {http://doi.acm.org/10.1145/2502488.2502496}, 188 | doi = {10.1145/2502488.2502496}, 189 | acmid = {2502496}, 190 | publisher = {ACM}, 191 | address = {New York, NY, USA}, 192 | keywords = {dynamic programming, dynamorphisms, histomorphisms, recursion schemes}, 193 | } 194 | 195 | @book{Dagand13, 196 | title = {A Cosmology of Datatypes: Reusability and Dependent Types}, 197 | author = {Dagand, P.{\'E}. and University of Strathclyde. Department of Computer and Information Sciences, PhD thesis}, 198 | url = {https://books.google.com.ua/books?id=7RF8nQAACAAJ}, 199 | year = {2013} 200 | } 201 | 202 | @inproceedings{Kaposi16, 203 | author = {Altenkirch, Thorsten and Kaposi, Ambrus}, 204 | title = {Type Theory in Type Theory Using Quotient Inductive Types}, 205 | booktitle = {Proceedings of the 43rd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages}, 206 | series = {POPL '16}, 207 | year = {2016}, 208 | isbn = {978-1-4503-3549-2}, 209 | location = {St. Petersburg, FL, USA}, 210 | pages = {18--29}, 211 | numpages = {12}, 212 | url = {http://doi.acm.org/10.1145/2837614.2837638}, 213 | doi = {10.1145/2837614.2837638}, 214 | acmid = {2837638}, 215 | publisher = {ACM}, 216 | address = {New York, NY, USA}, 217 | keywords = {Agda, Higher Inductive Types, Homotopy Type Theory, Logical Relations, Metaprogramming}, 218 | } 219 | 220 | @inproceedings{Hamana11, 221 | author = {Makoto Hamana and Marcelo P. Fiore}, 222 | title = {A foundation for GADTs and inductive families: dependent polynomial functor approach}, 223 | booktitle = {Proceedings of the seventh {ACM} {SIGPLAN} workshop on Generic programming, WGP@ICFP 2011, Tokyo, Japan, September 19-21, 2011}, 224 | pages = {59--70}, 225 | year = {2011}, 226 | url = {http://doi.acm.org/10.1145/2036918.2036927}, 227 | doi = {10.1145/2036918.2036927}, 228 | timestamp = {Mon, 18 Jan 2016 16:05:02 +0100}, 229 | biburl = {http://dblp.org/rec/bib/conf/icfp/HamanaF11}, 230 | } 231 | 232 | @inproceedings{Mortberg17, 233 | author = {Cyril Cohen and Thierry Coquand and Simon Huber and Anders M{\"{o}}rtberg}, 234 | booktitle = {Cubical Type Theory: a constructive interpretation of the univalence axiom}, 235 | journal = {CoRR}, 236 | volume = {abs/1611.02108}, 237 | year = {2017} 238 | } 239 | 240 | @inproceedings{Coq96, 241 | author = {Thierry Coquand}, 242 | title = {An Algorithm for Type-Checking Dependent Types}, 243 | booktitle = {Sci. Comput. Program.}, 244 | volume = {26}, 245 | number = {1-3}, 246 | pages = {167--177}, 247 | year = {1996} 248 | } 249 | 250 | -------------------------------------------------------------------------------- /doc/pts_ua.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/doc/pts_ua.pdf -------------------------------------------------------------------------------- /doc/stages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/doc/stages.png -------------------------------------------------------------------------------- /doc/static.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/doc/static.png -------------------------------------------------------------------------------- /doc/structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/doc/structure.png -------------------------------------------------------------------------------- /footer.pug: -------------------------------------------------------------------------------- 1 | link(rel='stylesheet' href='main.css') 2 | 3 | footer.footer 4 | a(href='https://ansders.groupoid.space/lib/') 5 | img.footer__logo(src='https://homotopy.dev/images/seal.png',width=50) 6 | span.footer__copy 2016—2022 © Namdak Tönpa 7 | script(src='https://groupoid.space/bundle.js') 8 | script(src='https://groupoid.space/highlight.js') 9 | -------------------------------------------------------------------------------- /framework.js: -------------------------------------------------------------------------------- 1 | // Mixin usages in PUG: 2 | 3 | // +tex(false, false). 4 | // $\mathbf{Definition}$ (Space of Sections). Let $\mathbf{H}$ be 5 | // a $(\infty,1)$-topos, and let $E \rightarrow B : \mathbf{H}_{/B}$ a bundle in 6 | // $\mathbf{H}$, object in the slice topos. Then the space of sections $\Gamma_\Sigma(E)$ 7 | // of this bundle is the Dependent Product. 8 | 9 | // +tex(true, false). 10 | // $$ 11 | // \Gamma_\Sigma(E) = \Pi_\Sigma (E) \in \mathbf{H}. 12 | // $$ 13 | 14 | // +code. 15 | // def Pi (A : U) (B : A → U) : U := Π (x : A), B x 16 | 17 | const {mathjax} = require('mathjax-full/js/mathjax.js'); 18 | const {TeX} = require('mathjax-full/js/input/tex.js'); 19 | const {SVG} = require('mathjax-full/js/output/svg.js'); 20 | const {liteAdaptor} = require('mathjax-full/js/adaptors/liteAdaptor.js'); 21 | const {RegisterHTMLHandler} = require('mathjax-full/js/handlers/html.js'); 22 | const {AssistiveMmlHandler} = require('mathjax-full/js/a11y/assistive-mml.js'); 23 | const {AllPackages} = require('mathjax-full/js/input/tex/AllPackages.js'); 24 | 25 | const adaptor = liteAdaptor(); 26 | const handler = RegisterHTMLHandler(adaptor); 27 | 28 | const tex = new TeX({ 29 | packages: ['base', 'autoload', 'require', 'ams', 'amscd', 'newcommand', 'configmacros'], 30 | inlineMath: [ ["$", "$"] ], 31 | macros: { // Plug your Glyphs here 32 | llparenthesis: '\\mathopen{\u2987}', 33 | rrparenthesis: '\\mathclose{\u2988}', 34 | llbracket: '\\mathopen{\u27E6}', 35 | rrbracket: '\\mathclose{\u27E7}', 36 | incmap: '\\mathclose{\u21AA}', 37 | meet: '\\mathopen{\u2227}', 38 | map: '\\mathopen{\u21A6}', 39 | join: '\\mathopen{\u2228}', 40 | trans: '\\, \\mathbin{\\vcenter{\\rule{.3ex}{.3ex}}} \\,', 41 | mapright: ['\\xrightarrow{{#1}}', 1], 42 | mapdown: ['\\Big\\downarrow\\rlap{\\raise2pt{\\scriptstyle{#1}}}', 1], 43 | mapdiagl: ['\\vcenter{\\searrow}\\rlap{\\raise2pt{\\scriptstyle{#1}}}', 1], 44 | mapdiagr: ['\\vcenter{\\swarrow}\\rlap{\\raise2pt{\\scriptstyle{#1}}}', 1], 45 | } 46 | }); 47 | 48 | tex.postFilters.add(({math, data}) => { 49 | if (!data.error) return; 50 | data.root.walkTree((node) => { 51 | if (node.isKind('merror')) { 52 | console.log('TeX error:\n ' + node.attributes.get('data-mjx-error')); 53 | } 54 | }); 55 | }); 56 | 57 | const svg = new SVG({fontCache: 'local'}); 58 | 59 | function renderPug(block) { 60 | var recv; with({pug_html: ""}){ 61 | eval(`(${block})();`); recv = pug_html; 62 | }; return recv 63 | } 64 | 65 | function renderTeX(formulae) { 66 | return adaptor.innerHTML(mathjax.document(formulae, { 67 | InputJax: tex, OutputJax: svg 68 | }).render().document.body); 69 | } 70 | 71 | exports.tex = function (block) { 72 | return renderTeX(renderPug(block)); 73 | } 74 | 75 | exports.highlight = function (block) { 76 | return renderPug(block) 77 | .replace(/([(){}→=]+|:|:=)/g, 78 | '$1') 79 | .replace(/\b(∀|Π|Σ|W|λ|glue|unglue|Glue|transp|hcomp|where|def|begin|end|module|import|option|false|true|indᵂ|sup|.1|.2|𝟎|𝟏|𝟐|ind₂|ind₁|ind₀|★|0₂|1₂|PathP|PartialP|inc|ouc|axiom|theorem|lemdata|ma|U|V)\b(?!:)/g, 80 | '$1'); 81 | } 82 | -------------------------------------------------------------------------------- /header.pug: -------------------------------------------------------------------------------- 1 | mixin tex(center=false, paragraph=true) 2 | if paragraph 3 | p(style=center ? {'text-align': 'center' } : null)!= tex(`${block}`) 4 | else 5 | span(style=center ? {'text-align': 'center', 'display': 'block', 6 | 'padding-top': '8px', 'padding-bottom': '8px', } : null)!= tex(`${block}`) 7 | 8 | mixin code 9 | code!= highlight(`${block}`) 10 | 11 | mixin header(logo, title, subtitle) 12 | header.header 13 | .header__titles 14 | h1.header__title!= title 15 | h4.header__subtitle!= subtitle 16 | 17 | doctype html 18 | html 19 | head 20 | meta(charset='utf-8') 21 | meta(http-equiv='x-ua-compatible' content='ie=edge') 22 | meta(property='fb:app_id' content='118554188236439') 23 | meta(name='viewport' content='width=device-width, initial-scale=1') 24 | meta(name='author' content='Maxim Sokhatsky') 25 | meta(name='twitter:site' content='@infinitystack') 26 | meta(name='twitter:creator' content='@infinitystack') 27 | meta(property='og:type' content='website') 28 | meta(property='og:image' content='https://avatars.githubusercontent.com/u/17128096?s=400&u=66a63d4cdd9625b2b4b37d724cc00fe6401e5bd8&v=4') 29 | meta(name='msapplication-TileColor' content='#ffffff') 30 | meta(name='msapplication-TileImage' content='https://homotopy.dev/images/ms-icon-144x144.png') 31 | meta(name='theme-color' content='#ffffff') 32 | 33 | link(rel='stylesheet' href='main.css') 34 | link(rel='apple-touch-icon' sizes='57x57' href='https://homotopy.dev/images/apple-icon-57x57.png') 35 | link(rel='apple-touch-icon' sizes='60x60' href='https://homotopy.dev/images/apple-icon-60x60.png') 36 | link(rel='apple-touch-icon' sizes='72x72' href='https://homotopy.dev/images/apple-icon-72x72.png') 37 | link(rel='apple-touch-icon' sizes='76x76' href='https://homotopy.dev/images/apple-icon-76x76.png') 38 | link(rel='apple-touch-icon' sizes='114x114' href='https://homotopy.dev/images/apple-icon-114x114.png') 39 | link(rel='apple-touch-icon' sizes='120x120' href='https://homotopy.dev/images/apple-icon-120x120.png') 40 | link(rel='apple-touch-icon' sizes='144x144' href='https://homotopy.dev/images/apple-icon-144x144.png') 41 | link(rel='apple-touch-icon' sizes='152x152' href='https://homotopy.dev/images/apple-icon-152x152.png') 42 | link(rel='apple-touch-icon' sizes='180x180' href='https://homotopy.dev/images//apple-icon-180x180.png') 43 | link(rel='icon' type='image/png' sizes='192x192' href='https://homotopy.dev/images/android-icon-192x192.png') 44 | link(rel='icon' type='image/png' sizes='32x32' href='https://homotopy.dev/images/favicon-32x32.png') 45 | link(rel='icon' type='image/png' sizes='96x96' href='https://homotopy.dev/images/favicon-96x96.png') 46 | link(rel='icon' type='image/png' sizes='16x16' href='https://homotopy.dev/images/favicon-16x16.png') 47 | link(rel='manifest' href='https://homotopy.dev/images/manifest.json') 48 | 49 | style. 50 | svg a{fill:blue;stroke:blue} 51 | [data-mml-node="merror"]>g{fill:red;stroke:red} 52 | [data-mml-node="merror"]>rect[data-background]{fill:yellow;stroke:none} 53 | [data-frame],[data-line]{stroke-width:70px;fill:none} 54 | .mjx-dashed{stroke-dasharray:140} 55 | .mjx-dotted{stroke-linecap:round;stroke-dasharray:0,140} 56 | use[data-c]{stroke-width:3px} 57 | 58 | body.content 59 | block vars 60 | block content 61 | -------------------------------------------------------------------------------- /img/Henk Barendregt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/groupoid/henk/16c535e39f377b20e0e79aa4b30da807d43f3aea/img/Henk Barendregt.jpg -------------------------------------------------------------------------------- /index.pug: -------------------------------------------------------------------------------- 1 | include header 2 | 3 | html 4 | head 5 | meta(property='og:title' content='HENK') 6 | meta(property='og:description' content='Чиста система типів CoC') 7 | meta(property='og:url' content='https://henk.groupoid.space/') 8 | 9 | block title 10 | title HENK 11 | 12 | block content 13 | +header('', 'Henk', 'Мінімальна мова з квантором узагальнення та нескінченною кількістю універсумів для послідовних обчислень в локальних декартово-замкнених категоріях') 14 | article.main 15 | .exe 16 | section 17 | h1 Анотація 18 | aside Намдак Тонпа 19 | time ДАТА: 10 ЖОВТНЯ 2016 20 | section 21 | +tex. 22 | Мова програмування $\mathbf{Henk}$ — це залежно-типізоване лямбда-числення вищого порядку, 23 | розширення числення конструкцій (Кокан, Юе) з ієрархією предикативних і непредикативних універсумів. 24 | 25 | .semantics 26 | section 27 | h2#nat Універсуми 28 | p. 29 | Нескінченна ієрархія універсумів дозволяє уникати парадоксів (Жирара, Рассела, Гуркенса) 30 | у теорії типів (Мартіна-Льофа). 31 | code. 32 | U₀ : U₁ : U₂ : U₃ : … 33 | 34 | U₀ — пропозиції 35 | U₁ — значення та множини 36 | U₂ — типи 37 | U₃ — сорти 38 | br 39 | +tex(true). 40 | $$ 41 | \begin{equation} 42 | \tag{S} 43 | \dfrac 44 | {o : Nat} 45 | {Type_o} 46 | \end{equation} 47 | $$ 48 | 49 | h2#axioms Предикативні універсуми 50 | p. 51 | Усі терми підкоряються рейтингу A у послідовності універсумів S, 52 | а складність R залежного терму дорівнює максимуму складності терму та його залежності. 53 | Система універсумів повністю описується наступною нотацією PTS (за Барендрегтом): 54 | code. 55 | S (n : nat) = U n 56 | A₁ (n m : nat) = U n : U m де m > n — кумулятивні 57 | R₁ (m n : nat) = U m ⟶ U n : U (max m n) — предикативні 58 | br. 59 | p. 60 | Зверніть увагу, що предикативні універсуми несумісні з кодуванням лямбда-термів за Чьорчем. 61 | Ви можете перемикатися між предикативними та непредикативними універсумами за допомогою параметра перевірки типів. 62 | +tex(true). 63 | $$ 64 | \begin{equation} 65 | \tag{A₁} 66 | \dfrac 67 | {i: Nat,\ \ \ \ j: Nat,\ \ \ \ i < j} 68 | {Type_i : Type_{j}} 69 | \end{equation} 70 | $$ 71 | +tex(true). 72 | $$ 73 | \begin{equation} 74 | \tag{R₁} 75 | \dfrac 76 | {i : Nat,\ \ \ \ j : Nat} 77 | {Type_i \rightarrow Type_{j} : Type_{max(i,j)}} 78 | \end{equation} 79 | $$ 80 | 81 | h2#axioms Непредикативні універсуми 82 | p. 83 | Пропозиційний контрактний нижній простір — єдине доступне розширення предикативної ієрархії, 84 | яке не призводить до неконсистентності. Однак є інший варіант із нескінченною 85 | непредикативною ієрархією. 86 | code. 87 | A₂ (n : nat) = U n : U (n + 1) — некумулятивні 88 | R₂ (m n : nat) = U m ⟶ U n : U n — непредикативні 89 | br. 90 | +tex(true). 91 | $$ 92 | \begin{equation} 93 | \tag{A₂} 94 | \dfrac 95 | {i: Nat} 96 | {Type_i : Type_{i+1}} 97 | \end{equation} 98 | $$ 99 | +tex(true). 100 | $$ 101 | \begin{equation} 102 | \tag{R₂} 103 | \dfrac 104 | {i : Nat,\ \ \ \ j : Nat} 105 | {Type_i \rightarrow Type_{j} : Type_{j}} 106 | \end{equation} 107 | $$ 108 | 109 | h2#ast Мова з єдиною аксіомою 110 | p. 111 | Ця мова називається мовою з єдиною аксіомою (або чистою), оскільки елімінатор 112 | та введення спряжених функторів виводяться з правила формування типів. 113 | Єдиним правилом обчислення для типу Пі є бета-редукція. 114 | code. 115 | Pi (A: U) (B: A -> U): U = (x: A) -> B x 116 | lambda (A: U) (B: A -> U) (b: Pi A B): Pi A B = \ (x: A) -> b x 117 | app (A: U) (B: A -> U) (f: Pi A B) (a: A): B a = f a 118 | beta (A: U) (B: A -> U) (a:A) (f: Pi A B): Equ (B a) (app A B (lambda A B f) a) (f a) = 119 | br. 120 | +tex(true). 121 | \begin{equation} 122 | \tag{$\Pi$-formation} 123 | \dfrac 124 | {x:A \vdash B : Type} 125 | {\Pi\ (x:A) \rightarrow B : Type} 126 | \end{equation} 127 | +tex(true). 128 | \begin{equation} 129 | \tag{$\Pi$-intro} 130 | \dfrac 131 | {x:A \vdash b : B} 132 | {\lambda\ (x:A) \rightarrow b : \Pi\ (x: A) \rightarrow B } 133 | \end{equation} 134 | br. 135 | +tex(true). 136 | $$ 137 | \begin{equation} 138 | \tag{$\Pi$-application} 139 | \dfrac 140 | {f: (\Pi\ (x:A) \rightarrow B)\ \ \ a: A} 141 | {f\ a : B\ [a/x]} 142 | \end{equation} 143 | $$ 144 | +tex(true). 145 | $$ 146 | \begin{equation} 147 | \tag{$\beta$-rule} 148 | \dfrac 149 | {x:A \vdash b: B\ \ \ a:A} 150 | {(\lambda\ (x:A) \rightarrow b)\ a = b\ [a/x] : B\ [a/x]} 151 | \end{equation} 152 | $$ 153 | br. 154 | 155 | h2#ast Синтаксис 156 | +tex. 157 | Терми $\mathbf{Henk}$ складаються з nat-індексованих зірок, змінних, застосувань, 158 | абстракцій та універсальних кванторів. Ця мова називається Калькулем Конструкцій 159 | і існує в різних синтаксисах. 160 | code. 161 | <> = #опція 162 | I = #ідентифікатор 163 | U = * < #число > 164 | PTS = U | I | PTS → PTS | ∀ ( I : PTS ) → PTS 165 | | PTS PTS | ( PTS ) | λ ( I : PTS ) → PTS 166 | p. 167 | Еквівалентне кодування дерева HOAS для розпарсених термінів: 168 | code. 169 | type term = 170 | | Var of string 171 | | Universe of int 172 | | Pi of string * term * term (* ∀ (x : a), b *) 173 | | Lam of string * term * term (* λ (x : a), b *) 174 | | App of term * term 175 | br. 176 | 177 | h2 Універсуми 178 | code. 179 | let universe = function 180 | | Universe i -> i 181 | | _ -> raise (Failure ("Expected a universe")) 182 | br. 183 | 184 | h2 Підстановка 185 | code. 186 | let rec subst x s = function 187 | | Var y -> if x = y then s else Var y 188 | | Pi (y, a, b) when x <> y -> Pi (y, subst x s a, subst x s b) 189 | | Lam (y, a, b) when x <> y -> Lam (y, subst x s a, subst x s b) 190 | | App (f, a) -> App (subst x s f, subst x s a) 191 | | t -> t 192 | br. 193 | 194 | h2 Рівність 195 | code. 196 | let rec equal ctx t1 t2 = match t1, t2 with 197 | | Var x, Var y -> x = y 198 | | Universe i, Universe j -> i <= j 199 | | Pi (x, a, b), Pi (y, a', b') 200 | | Lam (x, a, b), Lam (y, a', b') -> equal ctx a a' && equal ((x,a) :: ctx) b (subst y (Var x) b') 201 | | Lam (x, _, b), t -> equal ctx b (App (t, Var x)) 202 | | t, Lam (x, _, b) -> equal ctx (App (t, Var x)) b 203 | | App (f, a), App (f', a') -> equal ctx f f' && equal ctx a a' 204 | | _ -> false 205 | br. 206 | 207 | h2 Редукція 208 | code. 209 | and reduce ctx t = match t with 210 | | App (Lam (x, _, b), a) -> subst x a b 211 | | App (Pi (x, _, b), a) -> subst x a b 212 | | App (f, a) -> App (reduce ctx f, reduce ctx a) 213 | | _ -> t 214 | br. 215 | 216 | h2 Нормалізація 217 | code. 218 | and normalize ctx t = 219 | let t' = reduce ctx t in 220 | if equal ctx t t' then t else normalize ctx t' 221 | br. 222 | 223 | h2 Перевірка типів 224 | code. 225 | and infer ctx t = let res = match t with 226 | | Var x -> lookup x ctx 227 | | Universe i -> Universe (i + 1) 228 | | Pi (x, a, b) -> Universe (max (universe (infer ctx a)) (universe (infer ((x,a)::ctx) b))) 229 | | Lam (x, a, b) -> let _ = infer ctx a in Pi (x, a, infer ((x,a)::ctx) b) 230 | | App (f, a) -> match infer ctx f with | Pi (x, _, b) -> subst x a b | t -> raise (Failure "Requires a Pi type.") 231 | in normalize ctx res 232 | br. 233 | 234 | section 235 | h1 Використання 236 | 237 | h2#normal Нормалізація 238 | +tex. 239 | Терми в мові $\mathbf{Henk}$. 240 | code. 241 | $ om show List/Cons 242 | 243 | λ (A: *) 244 | → λ (Head: A) 245 | → λ (Tail: 246 | ∀ (List: *) 247 | → ∀ (Cons: 248 | ∀ (Head: A) 249 | → ∀ (Tail: List) 250 | → List) 251 | → ∀ (Nil: List) 252 | → List) 253 | → λ (List: *) 254 | → λ (Cons: 255 | ∀ (Head: A) 256 | → ∀ (Tail: List) 257 | → List) 258 | → λ (Nil: List) 259 | → Cons Head (Tail List Cons Nil) 260 | br. 261 | 262 | h2#erased Стирання типів 263 | +tex. 264 | Нетипізована лямбда-мова $\mathbf{Joe}$ — найпростіша мова, що використовується в 265 | $\mathbf{Henk}$ для генерації програм бекенду. Мова $\mathbf{Joe}$ використовується 266 | як результат стирання типів. 267 | code. 268 | I = #identifier 269 | O = I | ( O ) | O O | λ I -> O 270 | +tex. 271 | Терми в чистій нетипізованій лямбда-мові $\mathbf{Joe}$. 272 | code. 273 | $ om print fst erase a "#List/Cons" 274 | ( λ Head 275 | → ( λ Tail 276 | → ( λ Cons 277 | → ( λ Nil 278 | → ((Cons Head) ((Tail Cons) Nil)))))) 279 | ok 280 | br. 281 | 282 | section 283 | h1 Бібліографія 284 | p(style="font-size:16px;"). 285 | [1]. Додаток I: Чиста система типів для Erlang
286 | [2]. Деякі зауваження про залежну теорію типів
287 | 288 | include footer 289 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'local'; 3 | src: url("https://groupoid.space/Geometria-Light.otf"); 4 | font-weight: normal; 5 | font-style: normal; } 6 | 7 | .MathJax_Display { 8 | overflow-x: auto; 9 | overflow-y: hidden; } 10 | 11 | nav a { 12 | font-size: 18px; 13 | border: 2px solid #dedede; 14 | background-color: white; 15 | color: lightblue; 16 | text-decoration: none; 17 | margin: 5px 5px; 18 | padding: 7px 12px; 19 | min-width: 150px; 20 | text-align: center; } 21 | 22 | nav a:visited { 23 | color: lightblue; } 24 | 25 | nav a:hover { 26 | border-bottom: 2px solid #00b8cf; } 27 | 28 | nav { 29 | display: flex; 30 | padding-top: 7px; 31 | background-color: #FBFBFB; 32 | flex-direction: row; 33 | justify-content: center; } 34 | 35 | nav a { 36 | font-size: 18px; 37 | min-width: initial; } 38 | 39 | * { 40 | margin: 0; 41 | padding: 0; 42 | box-sizing: border-box; } 43 | 44 | sub, 45 | sup { 46 | font-size: 80%; 47 | line-height: 0; 48 | position: relative; 49 | vertical-align: baseline; } 50 | 51 | sub { 52 | bottom: -0.25em; } 53 | 54 | sup { 55 | top: -0.5em; } 56 | 57 | html { 58 | height: 100%; } 59 | 60 | body { 61 | min-height: 100%; 62 | text-rendering: optimizeLegibility; 63 | -webkit-font-smoothing: antialiased; } 64 | 65 | h1, h2, h3, h4 { 66 | font-weight: normal; } 67 | 68 | ul { 69 | list-style-type: none; } 70 | 71 | ol, 72 | ul { 73 | text-align: left; 74 | line-height: 1.5; } 75 | 76 | img, figure { 77 | vertical-align: middle; } 78 | 79 | img { 80 | margin-left: 20px; } 81 | 82 | .content { 83 | min-height: 100%; 84 | font-family: local; 85 | display: flex; 86 | flex-direction: column; 87 | position: relative; } 88 | 89 | .main { 90 | color: #586E75; 91 | background: #FBFBFB; 92 | padding: 50px 0px; 93 | text-align: center; 94 | box-shadow: 0 3px 10px rgba(0, 0, 0, 0); 95 | z-index: 5; 96 | flex: 1 1 auto; } 97 | 98 | figure { 99 | min-width: 300px; 100 | overflow-x: auto; 101 | padding: 10px 2px; 102 | font-size: 18px; 103 | display: block; } 104 | 105 | figure::after { 106 | content: "\A"; 107 | white-space: pre; } 108 | 109 | h2 { 110 | font-size: 24px; 111 | color: #268BD2; 112 | margin: 34px 0 8px; } 113 | @media (min-width: 768px) { 114 | h2 { 115 | font-size: 32px; } } 116 | 117 | h3 { 118 | max-width: 100%; 119 | margin: 16px auto 0; 120 | padding: 0 0 0 8px; 121 | text-transform: uppercase; 122 | text-align: left; 123 | font-size: 22px; } 124 | 125 | p { 126 | max-width: 100%; 127 | width: 650px; 128 | margin: auto; 129 | padding: 8px; 130 | text-align: left; 131 | font-size: 18px; 132 | line-height: 1.4; } 133 | @media (min-width: 768px) { 134 | p { 135 | font-size: 22px; } } 136 | 137 | p:hover { 138 | background: white; } 139 | 140 | mark { 141 | background: #FDF6E3; 142 | padding: 0px 2px; 143 | border-radius: 2px; 144 | color: #586E75; } 145 | 146 | a { 147 | color: #3A98C8; 148 | text-decoration: none; } 149 | a:visited { 150 | color: #3A98C8; } 151 | a:hover { 152 | color: #D33682; } 153 | a:active { 154 | color: #D33682; } 155 | 156 | aside { 157 | max-width: 650px; 158 | margin: auto; 159 | padding: 8px; 160 | font-size: 20px; 161 | text-align: right; } 162 | aside time, aside div { 163 | margin-bottom: 20px; 164 | display: block; } 165 | 166 | .header { 167 | background: black; 168 | color: white; 169 | position: relative; 170 | min-height: 450px; 171 | padding: 16px 8px; 172 | display: flex; 173 | text-align: center; 174 | flex-direction: column; 175 | justify-content: center; 176 | align-items: center; 177 | width: 100%; 178 | z-index: 5; } 179 | .header__logo { 180 | width: 130px; 181 | position: relative; } 182 | .header__titles { 183 | position: relative; 184 | max-width: 800px; 185 | margin: 20px; 186 | text-shadow: 1px 1px 7px #56CCF2; } 187 | .header__title { 188 | font-size: 48px; 189 | line-height: 1.1; } 190 | .header__subtitle { 191 | font-size: 22px; } 192 | @media (min-width: 768px) { 193 | .header { 194 | flex-direction: row; } 195 | .header__logo { 196 | width: 160px; 197 | margin-right: 10px; } 198 | .header__title { 199 | font-size: 60px; } 200 | .header__subtitle { 201 | font-size: 30px; } } 202 | 203 | .footer { 204 | width: 100%; 205 | padding: 15px; 206 | background: #7F8C8D; 207 | color: white; 208 | text-align: center; } 209 | .footer__logo { 210 | width: 50px; 211 | margin: 20px; } 212 | .footer__copy { 213 | font-size: 16px; 214 | white-space: pre; } 215 | @media (min-width: 768px) { 216 | .footer__copy { 217 | font-size: 24px; } } 218 | 219 | .semantics { 220 | text-align: center; } 221 | .semantics figure { 222 | display: inline-block; 223 | max-width: min-content; 224 | font-size: 13px; } 225 | @media (min-width: 800px) { 226 | .semantics figure { 227 | font-size: 16px; } } 228 | .semantics h1 { 229 | color: #7D8A96; 230 | font-size: 32px; 231 | text-transform: uppercase; 232 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); 233 | display: inline-block; 234 | margin-bottom: 8px; } 235 | .semantics section { 236 | margin-top: 40px; } 237 | 238 | .intro { 239 | width: 650px; 240 | max-width: 100%; 241 | margin: auto; } 242 | 243 | .status { 244 | text-align: left; 245 | display: inline-block; 246 | padding-left: 32px; } 247 | .status ol { 248 | line-height: 1.5; 249 | font-size: 18px; } 250 | @media (min-width: 768px) { 251 | .status ol { 252 | font-size: 22px; } } 253 | 254 | .resources { 255 | max-width: 650px; 256 | margin: 32px auto 0; 257 | text-align: left; 258 | padding: 8px; } 259 | .resources__title { 260 | display: inline-block; 261 | margin-bottom: 10px; 262 | color: #7D8A96; 263 | font-size: 32px; 264 | text-transform: uppercase; 265 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); } 266 | @media (min-width: 768px) { 267 | .resources__title { 268 | font-size: 40px; } } 269 | .resources__list { 270 | padding-left: 32px; 271 | line-height: 1.5; 272 | font-size: 18px; } 273 | @media (min-width: 768px) { 274 | .resources__list { 275 | font-size: 22px; } } 276 | 277 | .index { 278 | max-width: 900px; 279 | margin: auto; 280 | padding: 20px 0; 281 | display: flex; 282 | flex-wrap: wrap; 283 | justify-content: center; } 284 | .index__col { 285 | white-space: nowrap; 286 | padding: 15px 25px; 287 | margin: 15px; 288 | background: #fefefe; 289 | box-shadow: 0 1px 4px rgba(0, 0, 100, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.1); 290 | transition: box-shadow 0.5s cubic-bezier(0.23, 1, 0.32, 1); } 291 | .index__col:hover { 292 | box-shadow: 0 8px 40px rgba(0, 0, 100, 0.15), inset 0 0 0 1px rgba(0, 0, 0, 0.1); } 293 | .index a { 294 | line-height: 1.5; 295 | color: #888; 296 | font-size: 24px; } 297 | .index a[href^="#"] { 298 | color: #BBBBBB; } 299 | .index a:hover { 300 | color: #3A98C8; } 301 | .index a[href^="#"]:hover { 302 | color: #BBBBBB; } 303 | .index h2 { 304 | font-size: 24px; 305 | text-align: left; 306 | color: #707070; 307 | margin: 0 0 10px; 308 | text-transform: uppercase; } 309 | 310 | .om figure { 311 | max-width: inherit; } 312 | 313 | .om section h1 { 314 | margin-top: 50px; } 315 | 316 | .om h1 { 317 | color: #7D8A96; 318 | font-size: 32px; 319 | text-transform: uppercase; 320 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); 321 | display: inline-block; 322 | margin-bottom: 32px; } 323 | @media (min-width: 768px) { 324 | .om h1 { 325 | font-size: 40px; } } 326 | 327 | .om h1 + h2 { 328 | margin-top: 20px; } 329 | 330 | .om h3 { 331 | max-width: 100%; 332 | margin: auto; 333 | width: 600px; 334 | padding: 16px 8px 0; } 335 | 336 | .exe figure { 337 | max-width: inherit; } 338 | 339 | .exe h1 { 340 | color: #7D8A96; 341 | font-size: 32px; 342 | text-transform: uppercase; 343 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); 344 | display: inline-block; 345 | margin: 42px 0 10px; } 346 | @media (min-width: 768px) { 347 | .exe h1 { 348 | font-size: 40px; } } 349 | 350 | .exe h1 + h2 { 351 | margin-top: 0px; } 352 | 353 | .macro { 354 | margin: 0 auto; 355 | display: flex; 356 | justify-content: space-around; 357 | max-width: 600px; 358 | flex-wrap: wrap; 359 | width: 100%; } 360 | .macro__code { 361 | margin-right: -200px; 362 | padding-left: 24px; 363 | line-height: 1.5; 364 | font-size: 14px; } 365 | .macro__code h3 { 366 | padding: 0; 367 | width: initial; } 368 | @media (min-width: 768px) { 369 | .macro__code { 370 | font-size: 22px; } } 371 | .macro__col { 372 | padding-left: 24px; 373 | line-height: 1.5; 374 | font-size: 14px; } 375 | .macro__col h3 { 376 | padding: 0; 377 | width: initial; } 378 | @media (min-width: 768px) { 379 | .macro__col { 380 | font-size: 22px; } } 381 | 382 | .types { 383 | display: inline-block; 384 | text-align: left; 385 | max-width: 100%; 386 | padding: 0 8px; } 387 | .types h1 { 388 | color: #7D8A96; 389 | font-size: 32px; 390 | text-transform: uppercase; 391 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); 392 | display: inline-block; 393 | margin: 42px 0 10px; } 394 | @media (min-width: 768px) { 395 | .types h1 { 396 | font-size: 40px; } } 397 | .types section { 398 | max-width: 100%; } 399 | .types p { 400 | margin: 0; 401 | padding-left: 0; } 402 | .types h1 + h2 { 403 | margin-top: 0px; } 404 | .types .type { 405 | max-width: 660px; 406 | display: flex; 407 | flex-flow: row wrap; } 408 | .types .type__col { 409 | padding-left: 22px; 410 | flex: 1 0 15%; } 411 | .types .type__col h3 { 412 | width: initial; 413 | padding: 0; 414 | margin: 0; } 415 | @media (min-width: 600px) { 416 | .types .type__col { 417 | padding-right: 22px; 418 | flex: 1 0 15%; 419 | font-size: 20px; } } 420 | .types .legend { 421 | margin: 20px auto 0; 422 | display: inline-block; 423 | padding: 10px 20px; 424 | font-size: 24px; 425 | background: #FDF6E3; 426 | border-radius: 4px; 427 | box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08); } 428 | 429 | .list h1 { 430 | color: #7D8A96; 431 | font-size: 32px; 432 | text-transform: uppercase; 433 | border-bottom: 1px solid rgba(0, 0, 0, 0.3); 434 | display: inline-block; 435 | margin: 42px 8px 10px; } 436 | @media (min-width: 768px) { 437 | .list h1 { 438 | font-size: 40px; } } 439 | 440 | code { 441 | display: inline-block; 442 | overflow-x: auto; 443 | max-width: 100%; 444 | padding: 12px; 445 | margin: 8px 0; 446 | white-space: pre; 447 | text-align: left; 448 | border-radius: 4px; 449 | font-size: 14px; 450 | color: #00259c; 451 | background: white; 452 | box-shadow: 0 1px 4px #f1f0f0, inset 0 0 0 1px #e7e6e5; } 453 | @media (min-width: 768px) { 454 | code { 455 | font-size: 17px; } } 456 | 457 | pre { 458 | white-space: normal; 459 | max-width: 100%; 460 | width: 650px; 461 | padding: 12px; 462 | margin: 8px auto; 463 | text-align: left; 464 | border-radius: 4px; 465 | font-size: 14px; 466 | color: #00259c; 467 | background: white; 468 | box-shadow: 0 1px 4px #f1f0f0, inset 0 0 0 1px #e7e6e5; } 469 | @media (min-width: 768px) { 470 | pre { 471 | font-size: 17px; } } 472 | 473 | .h__name { 474 | color: #00259c; 475 | font-weight: bold; } 476 | 477 | .h__keyword { 478 | color: #ca30d4; } 479 | 480 | .h__symbol { 481 | color: #9f9fa3; } 482 | 483 | canvas { 484 | max-width: 100%; 485 | position: absolute; 486 | z-index: -10; } 487 | 488 | .stack { 489 | margin: auto; 490 | max-width: 100%; 491 | border-spacing: 10px; 492 | color: #282828; 493 | font-size: 20px; } 494 | .stack td { 495 | background-color: #fff9a6; 496 | padding: 4px; 497 | outline: 1px solid rgba(0, 0, 0, 0.3); } 498 | .stack th { 499 | padding: 4px; 500 | text-align: left; 501 | font-weight: normal; } 502 | .stack .empty { 503 | background-color: inherit; 504 | outline: inherit; } 505 | 506 | @media (max-width: 600px) { 507 | .stack { 508 | font-size: 16px; 509 | display: inline-block; 510 | border-spacing: 0; } 511 | .stack tbody { 512 | display: block; } 513 | .stack tr { 514 | display: block; 515 | text-align: left; 516 | vertical-align: top; 517 | position: relative; } 518 | .stack td { 519 | margin: 30px 0 10px; 520 | text-align: center; 521 | padding: 4px; 522 | display: inline-block; 523 | width: 90px; } 524 | .stack td[colspan="4"] { 525 | width: 360px; } 526 | .stack td[colspan="2"] { 527 | width: 180px; } 528 | .stack th { 529 | position: absolute; 530 | top: 0; 531 | width: 100%; } } 532 | 533 | @media (max-width: 320px) { 534 | .stack { 535 | font-size: 12px; } 536 | .stack td { 537 | margin: 20px 0 5px; 538 | width: 80px; } 539 | .stack td[colspan="4"] { 540 | width: 320px; } 541 | .stack td[colspan="2"] { 542 | width: 160px; } } 543 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "henk", 3 | "version": "1.0.1", 4 | "description": "Henk: Pure CoC Type System", 5 | "main": "", 6 | "scripts": { 7 | "start": "node-sass ../anders/styles -o ./ && pug -O ./framework.js index.pug", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git://github.com/groupoid/henk" 13 | }, 14 | "author": "Namdak Tonpa", 15 | "license": "DHARMA", 16 | "preinstall": "npm i -g node-sass && npm i -g pug-cli", 17 | "devDependencies": { 18 | "mathjax-full": "^3.2.0", 19 | "node-sass": "^9.0.0", 20 | "npm": "^10.1.0", 21 | "pug": "^3.0.2", 22 | "pug-cli": "^1.0.0-alpha6", 23 | "sass": "^1.68.0" 24 | }, 25 | "dependencies": { 26 | "saas": "^1.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/elixir/encodings/ch.erl: -------------------------------------------------------------------------------- 1 | -module(ch). 2 | -description('Natural Encoding Schema'). 3 | -compile(export_all). 4 | 5 | % Erlang Partial Application 6 | 7 | ap(Fun,Args) -> lists:foldl(fun(X,Acc) -> Acc(X) end,Fun,Args). 8 | 9 | ap1(Fun,Arg) -> Fun(Arg). 10 | 11 | % data bool: * := 12 | % (true: bool) 13 | % (false: bool) 14 | 15 | 'if' () -> fun (P) -> fun (A) -> fun (B) -> (P(A))(B) end end end. 16 | 17 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'True'(), 18 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 19 | % fun(_) -> 'Nat':'Zero'() end])). 20 | % CONS 21 | % 1 22 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'False'(), 23 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 24 | % fun(_) -> 'Nat':'Zero'() end])). 25 | % 0 26 | 27 | bool () -> [ begin io:format("TRUE~n"), "true" end, begin io:format("FALSE~n"), "false" end]. 28 | true () -> fun (T) -> fun (_) -> io:format("true called~n"), T end end. 29 | false () -> fun (_) -> fun (F) -> io:format("false called~n"), F end end. 30 | 31 | bool(F) -> ?MODULE:F(). 32 | unbool(X) -> ap(X,bool()). 33 | 34 | % record prod: * := 35 | % (pr1: *) 36 | % (pr2: *) 37 | 38 | prod () -> [fun (A) -> fun (B)-> {prod,A,B} end end]. 39 | prodid () -> fun (X) -> fun (_Mk) -> X end end. 40 | mk () -> fun (A) -> fun (B) -> fun (Mk) -> ap(Mk,[ap(A,[Mk]),ap(B,[Mk])]) end end end. 41 | pr1 () -> [fun (A) -> fun (_) -> A end end]. 42 | pr2 () -> [fun (_) -> fun (B) -> B end end]. 43 | 44 | prod({A,B}) -> ap(mk(),[ap(prodid(),[A]),ap(prodid(),[B])]). 45 | unprod(X) -> ap(X,prod()). 46 | 47 | % > ch:ap(ch:prod({io,2}),ch:pr1()). 48 | % io 49 | % 2> ch:ap(ch:prod({io,2}),ch:prod()). 50 | % {prod,io,2} 51 | 52 | % data proto: * := 53 | % (ok: * → proto) 54 | % (error: * → proto) 55 | % (io: * → * → proto) 56 | 57 | ret () -> [fun (X) -> {ok,X} end, fun (X) -> {error,X} end, fun(X) -> fun (Y) -> {io,X,Y} end end]. 58 | retid () -> fun (R) -> fun (_Ok) -> fun (_Error) -> fun (_Io) -> R end end end end. 59 | ok () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Ok, [ap(V,[Ok,Error,Io])]) end end end end. 60 | error () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Error,[ap(V,[Ok,Error,Io])]) end end end end. 61 | io () -> fun (X) -> fun (Y) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Io, [ap(X,[Ok,Error,Io]),ap(Y,[Ok,Error,Io])]) end end end end end. 62 | 63 | ret({N,A}) -> ap(?MODULE:N(),[ap(retid(),[A])]); 64 | ret({io,A,B}) -> ap(io(),[ap(retid(),[A]),ap(retid(),[B])]). 65 | unret(A) -> ap(A,ret()). 66 | 67 | % data nat: * := 68 | % (zero: () → nat) 69 | % (succ: nat → nat) 70 | 71 | nat_ () -> [fun (Succ) -> 1 + Succ end, 0 ]. 72 | nat () -> [fun (Succ) -> {succ,Succ} end, zero]. 73 | zero () -> fun (_Succ) -> fun (Zero) -> Zero end end. 74 | succ () -> fun (Nat) -> fun (Succ) -> fun (Zero) -> Succ((Nat(Succ))(Zero)) end end end. 75 | pred () -> fun(N) -> fun (F) -> fun (X) -> ((N(fun (G) -> fun (H) -> 76 | H(G(F)) end end))( fun (_) -> X end ))( fun (U) -> U end ) end end end. 77 | 78 | % mapping to erlang integer 79 | 80 | nat (0) -> 'Nat':'Zero'(); 81 | nat (I) -> ('Nat':'Succ'())(nat(I-1)). % fun (Succ) -> fun(Zero) -> Succ(((nat(I-1))(Succ))(Zero)) end end. 82 | unnat (N) -> ap(N,nat_()). 83 | plus(A,B) -> nat(erlang:'+'(unnat(A),unnat(B))). 84 | 85 | % data list: (A:*) → * := 86 | % (nil: () → list A) 87 | % (cons: A → list A → list A) 88 | 89 | list_ () -> [fun (H) -> fun (T) -> [H|T] end end, [] ]. 90 | list () -> [fun (H) -> fun (T) -> {cons,H,T} end end, nil]. 91 | nil () -> fun (_Cons) -> fun (Nil) -> Nil end end. 92 | cons () -> fun (Head) -> fun (Tail) -> fun (Cons) -> fun (Nil) -> ((Cons(Head))((Tail(Cons))(Nil))) end end end end. 93 | 94 | % mapping to erlang list 95 | 96 | list ([]) -> 'List':'Nil'(); 97 | list ([Head|Tail]) -> (('List':'Cons'())(Head))(list(Tail)). 98 | unlist (L) -> ap(L,list_()). 99 | 100 | getLine() -> fun(IO) -> fun(_) -> L = ch:list(unicode:characters_to_list(io:get_line("> "))), ch:ap(IO,[L]) end end. 101 | putLine() -> fun (S) -> fun(IO) -> io:format(": "), io:put_chars(ch:unlist(S)), ch:ap(IO,[S]) end end. 102 | pure() -> fun(IO) -> IO end. 103 | rec() -> ap('Morte':recursive(),[getLine(),putLine(),pure(),list([])]). 104 | 105 | copure() -> fun (_) -> fun(IO) -> IO end end. 106 | cogetLine() -> fun(IO) -> fun(_) -> L = ch:list(unicode:characters_to_list(io:get_line("> "))), ch:ap(IO,[L]) end end. 107 | coputLine() -> fun (S) -> fun(_IO) -> X = ch:unlist(S), 108 | io:format(": "), io:put_chars(X), 109 | case X of "0\n" -> list([]); 110 | _ -> corec() end end end. 111 | corec() -> ap('Morte':corecursive(),[copure(),cogetLine(),coputLine(),copure(),list([])]). 112 | 113 | % marshaling sample 114 | 115 | % > ch:ap(ch:ap(ch:succ(),[ch:ap(ch:succ(),[ch:zero()])]),ch:nat()). 116 | % {succ,{succ,zero}} 117 | 118 | % > ch:ap(ch:ap(ch:cons(),[2,ch:ap(ch:cons(),[1,ch:nil()])]),ch:list()). 119 | % {cons,2,{cons,1,nil}} 120 | 121 | % benchmarks in 1M 122 | 123 | main () -> io:format("Zero: ~p~n", [unnat(zero())]), 124 | io:format("Cons/Nil: ~p~n", [unlist(ap(cons(),[2,ap(cons(),[1,nil()])]))]), 125 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive Nat: ~p~n", [timer:tc(fun () -> unnat(nat(1000000)) end)]) end), 126 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 ErlangOTP List: ~p~n", [{element(1,timer:tc(fun () -> lists:foldl(fun(A,_) -> A end,0,lists:seq(1,1000000)) end)),'_'}]) end ), 127 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive List: ~p~n", [{element(1,timer:tc(fun () -> unlist(list(lists:seq(1,1000000))) end)),'_'}]) end ), 128 | io:format("Test Big List: ~p~n", [unlist(list([2,3,5,8,11,19]))]), 129 | io:format("Two: ~p~n", [unnat(ap(succ(),[ap(succ(),[zero()])]))]). 130 | -------------------------------------------------------------------------------- /src/elixir/encodings/cps.erl: -------------------------------------------------------------------------------- 1 | -module(cps). 2 | -description('Composition Continuator Encoding Schema'). 3 | -compile(export_all). 4 | 5 | % Composition Continuator is 6 | 7 | % (F ,X: Type) ... \ (C: Type -> Type) -> C F X 8 | 9 | ap(Fun,Args) -> lists:foldl(fun(X,Acc) -> Acc(X) end,Fun,Args). 10 | 11 | ap1(Fun,Arg) -> Fun(Arg). 12 | 13 | % data bool: * := 14 | % (true: bool) 15 | % (false: bool) 16 | 17 | 'if' () -> fun (P) -> fun (A) -> fun (B) -> (P(A))(B) end end end. 18 | 19 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'True'(), 20 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 21 | % fun(_) -> 'Nat':'Zero'() end])). 22 | % CONS 23 | % 1 24 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'False'(), 25 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 26 | % fun(_) -> 'Nat':'Zero'() end])). 27 | % 0 28 | 29 | bool () -> [ begin io:format("TRUE~n"), "true" end, begin io:format("FALSE~n"), "false" end]. 30 | true () -> fun (T) -> fun (_) -> io:format("true called~n"), T end end. 31 | false () -> fun (_) -> fun (F) -> io:format("false called~n"), F end end. 32 | 33 | bool(F) -> ?MODULE:F(). 34 | unbool(X) -> ap(X,bool()). 35 | 36 | % record prod: * := 37 | % (pr1: *) 38 | % (pr2: *) 39 | 40 | prod () -> [fun (A) -> fun (B)-> {prod,A,B} end end]. 41 | prodid () -> fun (X) -> fun (_Mk) -> X end end. 42 | mk () -> fun (A) -> fun (B) -> fun (Mk) -> ap(Mk,[ap(A,[Mk]),ap(B,[Mk])]) end end end. 43 | pr1 () -> [fun (A) -> fun (_) -> A end end]. 44 | pr2 () -> [fun (_) -> fun (B) -> B end end]. 45 | 46 | prod({A,B}) -> ap(mk(),[ap(prodid(),[A]),ap(prodid(),[B])]). 47 | unprod(X) -> ap(X,prod()). 48 | 49 | % > ch:ap(ch:prod({io,2}),ch:pr1()). 50 | % io 51 | % 2> ch:ap(ch:prod({io,2}),ch:prod()). 52 | % {prod,io,2} 53 | 54 | % data proto: * := 55 | % (ok: * → proto) 56 | % (error: * → proto) 57 | % (io: * → * → proto) 58 | 59 | ret () -> [fun (X) -> {ok,X} end, fun (X) -> {error,X} end, fun(X) -> fun (Y) -> {io,X,Y} end end]. 60 | retid () -> fun (R) -> fun (_Ok) -> fun (_Error) -> fun (_Io) -> R end end end end. 61 | ok () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Ok, [ap(V,[Ok,Error,Io])]) end end end end. 62 | error () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Error,[ap(V,[Ok,Error,Io])]) end end end end. 63 | io () -> fun (X) -> fun (Y) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Io, [ap(X,[Ok,Error,Io]),ap(Y,[Ok,Error,Io])]) end end end end end. 64 | 65 | ret({N,A}) -> ap(?MODULE:N(),[ap(retid(),[A])]); 66 | ret({io,A,B}) -> ap(io(),[ap(retid(),[A]),ap(retid(),[B])]). 67 | unret(A) -> ap(A,ret()). 68 | 69 | % data nat: * := 70 | % (zero: () → nat) 71 | % (succ: nat → nat) 72 | 73 | nat_ () -> [fun (Succ) -> 1 + Succ end, 0 ]. 74 | nat () -> [fun (Succ) -> {succ,Succ} end, zero]. 75 | id () -> begin fun (X) -> X end end. 76 | zero () -> fun (_Succ) -> fun (Zero) -> Zero end end. 77 | succ () -> fun (Nat) -> fun (Succ) -> fun (Zero) -> Succ((Nat(Succ))(Zero)) end end end. 78 | pred () -> fun(N) -> fun (F) -> fun (X) -> ((N(fun (G) -> fun (H) -> H(G(F)) end end)) 79 | (fun (_) -> X end))(fun (U) -> U end) end end end. 80 | 81 | % mapping to erlang integer 82 | 83 | nat (0) -> 'Nat':'Zero'(); 84 | nat (I) -> ('Nat':'Succ2'())(nat(I-1)). % fun (Succ) -> fun(Zero) -> Succ(((nat(I-1))(Succ))(Zero)) end end. 85 | unnat (N) -> ap(N,nat_()). 86 | plus(A,B) -> nat(erlang:'+'(unnat(A),unnat(B))). 87 | 88 | % data list: (A:*) → * := 89 | % (nil: () → list A) 90 | % (cons: A → list A → list A) 91 | 92 | list_ () -> [fun (H) -> fun (T) -> [H|T] end end, [] ]. 93 | list () -> [fun (H) -> fun (T) -> {cons,H,T} end end, nil]. 94 | nil () -> fun (_Cons) -> fun (Nil) -> Nil end end. 95 | cons () -> fun (Head) -> fun (Tail) -> fun (Cons) -> 96 | fun (Nil) -> ((Cons(Head))((Tail(Cons))(Nil))) end end end end. 97 | 98 | % mapping to erlang list 99 | 100 | list ([]) -> 'List':'Nil'(); 101 | list ([Head|Tail]) -> (('List':'Cons'())(Head))(list(Tail)). 102 | unlist (L) -> ap(L,list_()). 103 | 104 | getLine() -> fun(IO) -> fun(_) -> L = ch:list(io:get_line("> ")), ch:ap(IO,[L]) end end. 105 | putLine() -> fun(S) -> fun(IO) -> io:format(": "), io:put_chars(ch:unlist(S)), ch:ap(IO,[S]) end end. 106 | pure() -> fun(IO) -> IO end. 107 | 108 | ma() -> ap('Morte':recursive(),[getLine(),putLine(),pure(),ch:nil()]). 109 | 110 | % marshaling sample 111 | 112 | % > ch:ap(ch:ap(ch:succ(),[ch:ap(ch:succ(),[ch:zero()])]),ch:nat()). 113 | % {succ,{succ,zero}} 114 | 115 | % > ch:ap(ch:ap(ch:cons(),[2,ch:ap(ch:cons(),[1,ch:nil()])]),ch:list()). 116 | % {cons,2,{cons,1,nil}} 117 | 118 | % benchmarks in 1M 119 | 120 | main () -> io:format("Zero: ~p~n", [unnat(zero())]), 121 | io:format("Cons/Nil: ~p~n", [unlist(ap(cons(),[2,ap(cons(),[1,nil()])]))]), 122 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive Nat Improved: ~p~n", [timer:tc(fun () -> unnat1(nat1(1000000)) end)]) end), 123 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive Nat Church: ~p~n", [timer:tc(fun () -> unnat(nat(1000000)) end)]) end), 124 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive List: ~p~n", [{element(1,timer:tc(fun () -> unlist(list(lists:seq(1,1000000))) end)),'_'}]) end ), 125 | io:format("Test Big List: ~p~n", [unlist(list([2,3,5,8,11,19]))]), 126 | io:format("Two: ~p~n", [unnat(ap(succ(),[ap(succ(),[zero()])]))]). 127 | 128 | unnat1(N) -> ap(N,nat1()). 129 | nat1() -> [ fun (F) -> fun (X) -> F(X) + 1 end end, 0 ]. 130 | zero1() -> fun (_) -> fun (X) -> X end end. 131 | succ1() -> fun (Z) -> fun (F) -> fun (X) -> (F(fun(C) -> (C(F))(X) end))(Z) end end end. 132 | one1() -> fun (F) -> fun (X) -> (F(fun(C) -> (C(F))(X) end))(zero1()) end end. 133 | two1() -> fun (F) -> fun (X) -> (F(fun(C) -> (C(F))(X) end))(one1()) end end. 134 | three1()-> fun (F) -> fun (X) -> (F(fun(C) -> (C(F))(X) end))(two1()) end end. 135 | pred1() -> begin fun (N) -> (N(fun (_) -> fun(Pred) -> Pred end end))(N) end end. 136 | 137 | nat1(0) -> zero1(); 138 | nat1(I) -> (succ1())(nat1(I-1)). 139 | -------------------------------------------------------------------------------- /src/elixir/encodings/parigot.erl: -------------------------------------------------------------------------------- 1 | -module(parigot). 2 | -description('Parigot Encoding Schema'). 3 | -compile(export_all). 4 | 5 | 6 | % Erlang Partial Application 7 | 8 | ap(Fun,Args) -> lists:foldl(fun(X,Acc) -> Acc(X) end,Fun,Args). 9 | 10 | ap1(Fun,Arg) -> Fun(Arg). 11 | 12 | % data bool: * := 13 | % (true: bool) 14 | % (false: bool) 15 | 16 | 'if' () -> fun (P) -> fun (A) -> fun (B) -> (P(A))(B) end end end. 17 | 18 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'True'(), 19 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 20 | % fun(_) -> 'Nat':'Zero'() end])). 21 | % CONS 22 | % 1 23 | % > ch:unnat(ch:ap('Bool':'if'(),['Bool':'False'(), 24 | % fun(_) -> ('List':length())((('ch':'cons'())(1))('List':'Nil'())) end, 25 | % fun(_) -> 'Nat':'Zero'() end])). 26 | % 0 27 | 28 | bool () -> [ begin io:format("TRUE~n"), "true" end, begin io:format("FALSE~n"), "false" end]. 29 | true () -> fun (T) -> fun (_) -> io:format("true called~n"), T end end. 30 | false () -> fun (_) -> fun (F) -> io:format("false called~n"), F end end. 31 | 32 | bool(F) -> ?MODULE:F(). 33 | unbool(X) -> ap(X,bool()). 34 | 35 | % record prod: * := 36 | % (pr1: *) 37 | % (pr2: *) 38 | 39 | prod () -> [fun (A) -> fun (B)-> {prod,A,B} end end]. 40 | prodid () -> fun (X) -> fun (_Mk) -> X end end. 41 | mk () -> fun (A) -> fun (B) -> fun (Mk) -> ap(Mk,[ap(A,[Mk]),ap(B,[Mk])]) end end end. 42 | pr1 () -> [fun (A) -> fun (_) -> A end end]. 43 | pr2 () -> [fun (_) -> fun (B) -> B end end]. 44 | 45 | prod({A,B}) -> ap(mk(),[ap(prodid(),[A]),ap(prodid(),[B])]). 46 | unprod(X) -> ap(X,prod()). 47 | 48 | % > ch:ap(ch:prod({io,2}),ch:pr1()). 49 | % io 50 | % 2> ch:ap(ch:prod({io,2}),ch:prod()). 51 | % {prod,io,2} 52 | 53 | % data proto: * := 54 | % (ok: * → proto) 55 | % (error: * → proto) 56 | % (io: * → * → proto) 57 | 58 | ret () -> [fun (X) -> {ok,X} end, fun (X) -> {error,X} end, fun(X) -> fun (Y) -> {io,X,Y} end end]. 59 | retid () -> fun (R) -> fun (_Ok) -> fun (_Error) -> fun (_Io) -> R end end end end. 60 | ok () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Ok, [ap(V,[Ok,Error,Io])]) end end end end. 61 | error () -> fun (V) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Error,[ap(V,[Ok,Error,Io])]) end end end end. 62 | io () -> fun (X) -> fun (Y) -> fun (Ok) -> fun (Error) -> fun (Io) -> ap(Io, [ap(X,[Ok,Error,Io]),ap(Y,[Ok,Error,Io])]) end end end end end. 63 | 64 | ret({N,A}) -> ap(?MODULE:N(),[ap(retid(),[A])]); 65 | ret({io,A,B}) -> ap(io(),[ap(retid(),[A]),ap(retid(),[B])]). 66 | unret(A) -> ap(A,ret()). 67 | 68 | % data nat: * := 69 | % (zero: () → nat) 70 | % (succ: nat → nat) 71 | 72 | nat_ () -> [fun (Succ) -> 1 + Succ end, 0 ]. 73 | nat () -> [fun (Succ) -> {succ,Succ} end, zero]. 74 | zero () -> fun (_Succ) -> fun (Zero) -> Zero end end. 75 | succ () -> fun (Nat) -> fun (Succ) -> fun (Zero) -> Succ((Nat(Succ))(Zero)) end end end. 76 | %ap(Succ,[ap(Nat,[Succ,Zero])]) end end end. 77 | 78 | % mapping to erlang integer 79 | 80 | nat (0) -> 'Nat':'Zero'(); 81 | nat (I) -> ('Nat':'Succ'())(nat(I-1)). % fun (Succ) -> fun(Zero) -> Succ(((nat(I-1))(Succ))(Zero)) end end. 82 | unnat (N) -> ap(N,nat_()). 83 | plus(A,B) -> nat(erlang:'+'(unnat(A),unnat(B))). 84 | 85 | % data list: (A:*) → * := 86 | % (nil: () → list A) 87 | % (cons: A → list A → list A) 88 | 89 | list_ () -> [fun (H) -> fun (T) -> [H|T] end end, [] ]. 90 | list () -> [fun (H) -> fun (T) -> {cons,H,T} end end, nil]. 91 | nil () -> fun (_Cons) -> fun (Nil) -> Nil end end. 92 | cons () -> io:format("CONS~n"), 93 | fun (Head) -> fun (Tail) -> fun (Cons) -> fun (Nil) -> ((Cons(Head))((Tail(Cons))(Nil))) end end end end. 94 | % ap(Cons,[Head,ap(Tail,[Cons,Nil])]) end end end end. 95 | 96 | % mapping to erlang list 97 | 98 | list ([]) -> 'List':'Nil'(); 99 | list ([Head|Tail]) -> (('List':'Cons'())(Head))(list(Tail)). 100 | %fun (Cons) -> fun (Nil) -> (Cons(Head))(((list(Tail))(Cons))(Nil)) end end. 101 | unlist (L) -> ap(L,list_()). 102 | 103 | getLine() -> fun(IO) -> fun(_) -> L = ch:list(io:get_line("> ")), ch:ap(IO,[L]) end end. 104 | putLine() -> fun(S) -> fun(IO) -> io:format(": "), io:put_chars(ch:unlist(S)), ch:ap(IO,[S]) end end. 105 | pure() -> fun(IO) -> IO end. 106 | 107 | ma() -> ap('Morte':recursive(),[getLine(),putLine(),pure(),ch:nil()]). 108 | 109 | % marshaling sample 110 | 111 | % > ch:ap(ch:ap(ch:succ(),[ch:ap(ch:succ(),[ch:zero()])]),ch:nat()). 112 | % {succ,{succ,zero}} 113 | 114 | % > ch:ap(ch:ap(ch:cons(),[2,ch:ap(ch:cons(),[1,ch:nil()])]),ch:list()). 115 | % {cons,2,{cons,1,nil}} 116 | 117 | % benchmarks in 1M 118 | 119 | main () -> io:format("Zero: ~p~n", [unnat(zero())]), 120 | io:format("Cons/Nil: ~p~n", [unlist(ap(cons(),[2,ap(cons(),[1,nil()])]))]), 121 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive Nat Parigot: ~p~n", [timer:tc(fun () -> unnat1(nat1(1000000)) end)]) end), 122 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive Nat Church: ~p~n", [timer:tc(fun () -> unnat(nat(1000000)) end)]) end), 123 | spawn(fun () -> io:format("Pack/Unpack 1 000 000 Inductive List: ~p~n", [{element(1,timer:tc(fun () -> unlist(list(lists:seq(1,1000000))) end)),'_'}]) end ), 124 | io:format("Test Big List: ~p~n", [unlist(list([2,3,5,8,11,19]))]), 125 | io:format("Two: ~p~n", [unnat(ap(succ(),[ap(succ(),[zero()])]))]). 126 | 127 | unnat1(N) -> ap(N,nat1()). 128 | nat1() -> [fun(_) -> fun(B) -> ap(B,nat1()) + 1 end end, 0]. 129 | nat2() -> [fun(_) -> fun(B) -> {succ,ap(B,nat2())} end end, zero]. 130 | zero1() -> fun (_) -> fun (X) -> X end end. 131 | %succ1() -> fun (Z) -> fun (F) -> fun (X) -> 132 | % (F(fun (F1) -> fun(X1) -> F((Z(F1))(X1)) end end))(Z) end end end. 133 | succ1() -> fun (Z) -> fun (F) -> fun (_) -> (F(Z))(Z) end end end. 134 | 135 | one1() -> fun (F) -> fun (_) -> (F(fun (F1) -> fun(X1) -> F1(X1) end end))(zero1()) end end. 136 | two1() -> fun (F) -> fun (_) -> (F(fun (F1) -> fun(X1) -> F1(F1(X1)) end end))(one1()) end end. 137 | three1() -> fun (F) -> fun (_) -> (F(fun (F1) -> fun(X1) -> F1(F1(F1(X1))) end end))(two1()) end end. 138 | four1() -> fun (F) -> fun (_) -> (F(fun (F1) -> fun(X1) -> F1(F1(F1(F1(X1)))) end end))(three1()) end end. 139 | pred1() -> begin 140 | fun (N) -> (N(fun (_) -> fun(Pred) -> 141 | io:format("TICK~n"), 142 | Pred end end))(N) end 143 | end. 144 | 145 | nat1(0) -> zero1(); 146 | nat1(I) -> (succ1())(nat1(I-1)). 147 | -------------------------------------------------------------------------------- /src/elixir/extractor/om_erase.erl: -------------------------------------------------------------------------------- 1 | -module(om_erase). 2 | -description('Eraser'). 3 | -import(om_type,[type/2,star/1,norm/1,eq/2,subst/3,func/1,hierarchy/2,var/2]). 4 | -compile(export_all). 5 | -define(is_fun(F), F == <<"∀"/utf8>>; F== <<"λ"/utf8>>). 6 | 7 | univ({star,_}) -> true; 8 | univ({{<<"∀"/utf8>>,_},{_,O}}) -> univ(O); 9 | univ(_) -> false. 10 | 11 | erase({box,_},_) -> {none,{star,3}}; 12 | erase({star,N},_) -> {none,{star,N+1}}; 13 | erase({var,{N,I}},D) -> true = var(N,D), 14 | T = om:keyget(N,D,I), 15 | case univ(T) of 16 | true -> {none,T}; 17 | false -> {{var,{N,I}},T} end; 18 | erase({<<"→"/utf8>>,{I,O}},D) -> {none,{star,hierarchy(star(type(I,D)),star(type(O,D)))}}; 19 | erase({{<<"∀"/utf8>>,{N,0}},{I,O}},D) -> {none,{star,hierarchy(star(type(I,D)),star(type(O,[{N,norm(I)}|D])))}}; 20 | erase({{<<"λ"/utf8>>,{N,0}},{I,O}},D) -> star(type(I,D)), 21 | NI = norm(I), 22 | {B1,S1} = erase(O,[{N,NI}|D]), 23 | T = {{<<"∀"/utf8>>,{N,0}},{NI,S1}}, 24 | case univ(NI) of 25 | true -> {B1,T}; 26 | false -> {{{<<"λ"/utf8>>,{N,0}},{any,B1}},T} end; 27 | erase({app,{F,A}},D) -> {B1,S1} = erase(F,D), 28 | {B2,S2} = erase(A,D), 29 | true = func(S1), 30 | {{<<"∀"/utf8>>,{N,0}},{I,O}} = S1, 31 | true = eq(I,S2), 32 | T=norm(subst(O,N,A)), 33 | case univ(S1) of 34 | true -> {none,T}; 35 | false -> case univ(S2) of 36 | true -> {B1,T}; 37 | false -> {{app,{B1,B2}},T} end end; 38 | erase({remote,N},D) -> om:cache(erased,N,D). 39 | 40 | -------------------------------------------------------------------------------- /src/elixir/extractor/om_extract.erl: -------------------------------------------------------------------------------- 1 | -module(om_extract). 2 | -description('Extractor'). 3 | -compile(export_all). 4 | 5 | scan() -> Root = "priv/", 6 | [ begin om:restart(), om:mode(X), extract(om:cat([Root,X])) end 7 | || X <- om:snd(file:list_dir(Root)), lists:member(X,om:modes()) ]. 8 | 9 | replace(X,Y,Z) -> string:join(string:tokens(X,Y),Z). 10 | name(X,F) -> om:cat([X,"/",lists:flatten([F|[]])]). 11 | normal("",X) -> om:cname(X); 12 | normal(A,_) -> A. 13 | 14 | extr(X) -> om:restart(), om:mode(X), extract("priv/"++X). 15 | extract(X) -> O = replace(om:pname(X),"/","."), 16 | save(X, [{attribute,1,module,om:atom(normal(O,X))}, 17 | {attribute,1,compile,export_all}] ++ [ begin 18 | Norm = om:norm(om:fst(om:erase(om:snd(om:parse(om:read(name(X,F))))))), 19 | Ext = extract(F,Norm,1), 20 | io:format("Extract: ~p~n",[{X,F,Ext}]), 21 | Ext 22 | end || F <- element(2,file:list_dir(X)), not filelib:is_dir(name(X,F)) ] ++ [{eof,1}] ), 23 | [ extract(name(X,Subdir)) || Subdir <- om:snd(file:list_dir(X)), filelib:is_dir(name(X,Subdir)) ], 24 | ok. 25 | 26 | save(_,Forms) -> case compile:forms(om:flat(Forms),[debug_info]) of 27 | {ok,Name,Bin} -> file:write_file(om:cat([ebin,"/",Name,".beam"]),Bin), 28 | code:load_binary(Name,Name,Bin); 29 | _Error -> om:info(?MODULE,"Extract Error: ~p~n",[Forms]) end. 30 | 31 | extract(F,T,C) -> case ext(F,T,C) of 32 | [] -> []; 33 | Ex -> {function,C,om:atom(F),0,[{clause,C,[],[],[Ex]}]} end. 34 | 35 | ext(_,[],_) -> []; 36 | ext(_,{{"∀",_Name},{_,_Out}},_N) -> []; 37 | ext(_,{"→",{_,_Out}},_N) -> []; 38 | ext(F,{{"λ",{Name,_}},{_,Out}},N) -> {'fun', N,{clauses,[{clause,N,[{var,N,Name}],[],[ext(F,Out,N)]}]}}; 39 | ext(F,{app,{A,B}},N) -> {'call',N,ext(F,A,N),[ext(F,B,N)]}; 40 | ext(_,{var,{Name,_}},N) -> {'var', N,Name}; 41 | ext(_,_,_) -> []. 42 | -------------------------------------------------------------------------------- /src/elixir/henk.app.src: -------------------------------------------------------------------------------- 1 | {application, henk, 2 | [ 3 | {description, "Henk: Pure Type System"}, 4 | {vsn, "7.0.0"}, 5 | {registered, []}, 6 | {applications, [kernel, stdlib]}, 7 | {mod, { henk, []}}, 8 | {env, []} 9 | ]}. 10 | -------------------------------------------------------------------------------- /src/elixir/henk.erl: -------------------------------------------------------------------------------- 1 | -module(henk). 2 | -description('Henk: Pure Type System'). 3 | -behaviour(supervisor). 4 | -behaviour(application). 5 | -export([init/1, start/2, stop/1, start/0, boot/0, tables/0 ]). 6 | 7 | opt() -> [ set, named_table, { keypos, 1 }, public ]. 8 | tables() -> [ term, norm, type, erased, filesystem ]. 9 | boot() -> [ ets:new(T,opt()) || T <- tables() ]. 10 | unicode() -> io:setopts(standard_io, [{encoding, unicode}]). 11 | start() -> start(normal,[]). 12 | start(_,_) -> unicode(), supervisor:start_link({local,henk},henk,[]). 13 | ets_clear() -> [ ets:delete(T) || T <- tables() ]. 14 | stop(_) -> ets_clear(), ok. 15 | init([]) -> boot(), om:mode("Morte"), {ok, {{one_for_one, 5, 10}, []}}. 16 | -------------------------------------------------------------------------------- /src/elixir/lib/app.ex: -------------------------------------------------------------------------------- 1 | defmodule Henk do 2 | use Application 3 | def start(_, _) do 4 | opts = [strategy: :one_for_one, name: App.Supervisor] 5 | :henk.start(:"Morte",[]) 6 | Supervisor.start_link([], opts) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /src/elixir/lib/syntax/automath.ex: -------------------------------------------------------------------------------- 1 | defmodule AUTOMATH do 2 | @moduledoc """ 3 | 50 years of Pure Type Systems 4 | 5 | AUTOMATH (c) 1968, Nicolaas Govert de Bruijn 6 | Calculus of Construction (c) 1988, Thierry Coquand 7 | Morte (c) 2014, Gabriella Gonzalez 8 | Henk (c) 2018, Namdak Tonpa 9 | 10 | CoC Syntax: 11 | 12 | *₁₀₁ -- 101-th Universe 13 | [x : A] Exp -- Universal Quantifier 14 | (x : A) Exp -- Lambda 15 | M N -- Application 16 | L₁ -- Variable with de Bruijn index 1 17 | """ 18 | 19 | def ilst(x), do: :erlang.integer_to_list(x) 20 | def lsti(x), do: :erlang.list_to_integer(x) 21 | def lstb(x), do: :binary.list_to_bin(x) 22 | def lbin(x), do: :erlang.list_to_binary(x) 23 | def atmb(x), do: :erlang.atom_to_binary(x) 24 | def utf8(x), do: :unicode.characters_to_binary(x) 25 | 26 | def sub(x) when x >= 0 and x < 10, do: utf8([8320+x]) 27 | def sub(x), do: lstb(:lists.map(fn x -> sub(lsti([x])) end, ilst(x))) 28 | def bin(x) when is_list(x), do: lbin(x) 29 | def bin(x) when is_binary(x), do: x 30 | def bin(x) when is_atom(x), do: atmb(x) 31 | def name(s,x), do: bin(s) <> sub(x) 32 | 33 | def ext({:star,x}), do: name("*",x) 34 | def ext({:var,{s,x}}), do: name(s,x) 35 | def ext({:app,{a,b}}), do: {ext(a),ext(b)} 36 | def ext({{"∀",{s,x}},{i,o}}), do: {:"П",name(s,x),ext(i),ext(o)} 37 | def ext({"→",{i,o}}), do: {:"П",name("_",0),ext(i),ext(o)} 38 | def ext({{"λ",{s,x}},{i,o}}), do: {:"λ",name(s,x),ext(i),ext(o)} 39 | 40 | def prn({:star,x}), do: name("*",x) 41 | def prn({:var,{s,x}}), do: name(s,x) 42 | def prn({:app,{{:app,{a,x}},{:app,{y,b}}}}), do: "#{prn(a)}∘#{prn(x)}∘(#{prn(y)}∘#{prn(b)})" 43 | def prn({:app,{{:app,{a,x}},b}}), do: "#{prn(a)}∘#{prn(x)}∘#{prn(b)}" 44 | def prn({:app,{a,{:app,{x,b}}}}), do: "#{prn(a)}∘(#{prn(x)}∘#{prn(b)})" 45 | def prn({:app,{a,b}}), do: "#{prn(a)}∘#{prn(b)}" 46 | def prn({"→",{i,o}}), do: "#{prn(i)}→#{prn(o)}" 47 | def prn({{"∀",{"_",_}},{i,o}}), do: "#{prn(i)}→#{prn(o)}" 48 | def prn({{"∀",{s,x}},{i,o}}), do: "[#{name(s,x)}:#{prn(i)}]#{prn(o)}" 49 | def prn({{"λ",{s,x}},{i,o}}), do: "(#{name(s,x)}:#{prn(i)})#{prn(o)}" 50 | 51 | end 52 | -------------------------------------------------------------------------------- /src/elixir/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule Henk.Mixfile do 2 | use Mix.Project 3 | def project do 4 | [ app: :henk, 5 | version: "1.0.0", 6 | elixir: ">= 1.9.0", 7 | description: "Groupoid Infinity Henk Programming Language", 8 | deps: deps(), 9 | package: package(), 10 | ] 11 | end 12 | def package do 13 | [ files: ["lib", "src", "priv", "mix.exs", "CNAME", "LICENSE"], 14 | maintainers: ["Namdak Tonpa"], 15 | licenses: ["ISC"], 16 | links: %{"GitHub" => "https://github.com/groupoid/henk"} 17 | ] 18 | end 19 | def application do 20 | [ extra_applications: [], 21 | mod: {:henk,[]} 22 | ] 23 | end 24 | def deps do 25 | [ 26 | {:ex_doc, "~> 0.21", only: :dev} 27 | ] 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /src/elixir/om.erl: -------------------------------------------------------------------------------- 1 | -module(om). 2 | -description('Henk: Pure Type System'). 3 | -compile(export_all). 4 | 5 | % env 6 | 7 | ver(_) -> ver(). 8 | ver() -> {version,[keyget(I,element(2,application:get_all_key(henk)))||I<-[description,vsn]]}. 9 | 10 | rec() -> ch:rec(). 11 | corec() -> ch:corec(). 12 | restart() -> [ ets:delete(T) || T <- henk:tables() ], henk:boot(). 13 | libdir() -> application:get_env(om,lib,"priv"). 14 | mode(S) -> application:set_env(om,mode,S). 15 | mode() -> application:get_env(om,mode,"Morte"). 16 | debug(S) -> application:set_env(om,debug,atom(S)). 17 | debug() -> application:get_env(om,debug,false). 18 | 19 | % constants 20 | allmodes() -> ["Morte"]. 21 | modes() -> allmodes(). 22 | 23 | % providing functions 24 | 25 | help(_) -> help(). 26 | help() -> om_help:help(). 27 | pwd(_) -> case file:get_cwd() of {ok, Cwd} -> Cwd; _ -> "." end. 28 | print(X) -> io:format("~ts~n",[bin(X)]). 29 | bin(X) -> unicode:characters_to_binary(om:flat(om_parse:print(X,0))). 30 | extract(X) -> om_extract:extr(X). 31 | extract() -> om_extract:extr("Morte"). 32 | norm(T) -> om_type:norm(T). 33 | eq(X,Y) -> om_type:eq(X,Y). 34 | type(S) -> type(S,[]). 35 | type(T,C) -> om_type:type(T,C). 36 | erase(X) -> erase(X,[]). 37 | erase(T,C) -> om_erase:erase(T,C). 38 | modes(_) -> modes(). 39 | allmodes(_) -> allmodes(). 40 | lib(Mode) -> lists:concat([libdir(),"/",Mode]). 41 | name(_,[]) -> lib(mode()); 42 | name(_,F) -> string:join([lib(mode()),F],"/"). 43 | name(M,[],F) -> name(M,F); 44 | name(_,P,F) -> string:join([lib(mode()),P,F],"/"). 45 | tokens(B) -> om_tok:tokens([],B,0,{1,[]},[]). 46 | str(F) -> tokens(unicode:characters_to_binary(F)). 47 | read(F) -> tokens(file(F)). 48 | comp(F) -> rev(tokens(F,"/")). 49 | cname(F) -> hd(comp(F)). 50 | tname(F) -> tname(F,[]). 51 | pname(F) -> string:join(tl(tl(string:tokens(F,"/"))),"/"). 52 | tname(F,S) -> X = string:join(rev(tl(comp(F))),"/"), case om:mode() of X -> []; _ -> X ++ S end. 53 | show(F) -> Term = snd(parse(tname(F),cname(F))), mad:info("~n~ts~n~n", [bin(Term)]), Term. 54 | a(F) -> snd(parse(str(F))). 55 | fst({X,_}) -> X. 56 | snd({error,X}) -> {error,X}; 57 | snd({_,[X]}) -> X; 58 | snd({_,X}) -> X. 59 | parse(X) -> om_parse:expr([],X,[],{0,0}). 60 | parse(T,C) -> om_parse:expr(T,read(name(mode(),T,C)),[],{0,0}). 61 | 62 | % system functions 63 | 64 | convert(A,S, nt) -> convert(A,S); 65 | convert(A,_, _) -> A. 66 | 67 | convert([],Acc) -> rev(Acc); 68 | convert([$>|T],Acc) -> convert(T,[61502|Acc]); 69 | convert([$<|T],Acc) -> convert(T,[61500|Acc]); 70 | convert([$:|T],Acc) -> convert(T,[61498|Acc]); 71 | convert([$||T],Acc) -> convert(T,[61564|Acc]); 72 | convert([H|T],Acc) -> convert(T,[H|Acc]). 73 | 74 | % test suite 75 | 76 | typed(X) -> try _ = om:type(X), {X,[]} catch _:_ -> {X,typed} end. 77 | erased(X) -> try A = om:erase(X), {A,[]} catch _:_ -> {X,erased} end. 78 | parsed(F) -> case parse([],pname(F)) of {_,[X]} -> {X,[]}; _ -> {F,parsed} end. 79 | pipe(L) -> io:format("[~tp]~n",[L]), % workaround for trevis timeout break 80 | lists:foldl(fun(X,{A,D}) -> 81 | {N,E}=?MODULE:X(A), {N,[E|D]} end,{L,[]},[parsed,typed,erased]). 82 | pass(0) -> "PASSED"; 83 | pass(X) -> "FAILED " ++ integer_to_list(X). 84 | all(_) -> all(). 85 | all() -> X = lists:flatten([ begin om:restart(), om:mode(M), om:scan() end || M <- allmodes() ]), 86 | om:restart(), om:mode("Morte"), 87 | X. 88 | syscard(P) -> [ {F} || F <- filelib:wildcard(name(mode(),P,"**/*")), filelib:is_dir(F) /= true ]. 89 | wildcard(P) -> Q = om:name(mode(),P), lists:flatten([ {A} 90 | || {A,_} <- ets:tab2list(filesystem), lists:sublist(A,length(Q)) == Q ]). 91 | scan() -> scan([]). 92 | scan(P) -> Res = [ { flat(element(2,pipe(F))), lists:concat([tname(F),"/",cname(F)])} 93 | || {F} <- lists:umerge(wildcard(P),syscard(P)), 94 | lists:member(lists:nth(2,tokens(F,"/")),modes()) ], 95 | Passed = lists:foldl(fun({X,_},B) -> case X of [] -> B; _ -> B + 1 end end, 0, Res), 96 | {mode(),pass(Passed),Res}. 97 | test(_) -> All = om:all(), 98 | io:format("~tp~n",[om_parse:test()]), 99 | io:format("~tp~n",[All]), 100 | case lists:all(fun({_Mode,Status,_Tests}) -> Status == om:pass(0) end, All) of 101 | true -> 0; 102 | false -> put(ret,1),1 end . 103 | 104 | % relying functions 105 | 106 | rev(X) -> lists:reverse(X). 107 | flat(X) -> lists:flatten(X). 108 | tokens(X,Y) -> string:tokens(X,Y). 109 | debug(S,A) -> case om:debug() of true -> io:format(S,A); false -> ok end. 110 | atom(X) -> list_to_atom(cat([X])). 111 | cat(X) -> lists:concat(X). 112 | keyget(K,D) -> proplists:get_value(K,D). 113 | keyget(K,D,I) -> lists:nth(I+1,proplists:get_all_values(K,D)). 114 | 115 | file(F) -> case file:read_file(convert(F,[],element(2,os:type()))) of 116 | {ok,Bin} -> Bin; 117 | {error,_} -> erlang:error({"File not found",F}) end. 118 | 119 | cache(X,Y,Z) -> om_cache:cache(X,Y,Z). 120 | 121 | -define(LOGGER, om_io). 122 | 123 | log_modules() -> [om]. 124 | log_level() -> info. 125 | 126 | -define(LOG_MODULES, (application:get_env(om,log_modules,om))). 127 | -define(LOG_LEVEL, (application:get_env(om,log_level,om))). 128 | 129 | log_level(none) -> 3; 130 | log_level(error) -> 2; 131 | log_level(warning) -> 1; 132 | log_level(_) -> 0. 133 | 134 | log(Module, String, Args, Fun) -> 135 | case log_level(Fun) < log_level(?LOG_LEVEL:log_level()) of 136 | true -> skip; 137 | false -> case ?LOG_MODULES:log_modules() of 138 | any -> ?LOGGER:Fun(Module, String, Args); 139 | Allowed -> case lists:member(Module, Allowed) of 140 | true -> ?LOGGER:Fun(Module, String, Args); 141 | false -> skip end end end. 142 | 143 | info(Module, String, Args) -> log(Module, String, Args, info). 144 | info( String, Args) -> log(?MODULE, String, Args, info). 145 | info( String ) -> log(?MODULE, String, [], info). 146 | 147 | warning(Module, String, Args) -> log(Module, String, Args, warning). 148 | warning( String, Args) -> log(?MODULE, String, Args, warning). 149 | warning( String ) -> log(?MODULE, String, [], warning). 150 | 151 | error(Module, String, Args) -> log(Module, String, Args, error). 152 | error( String, Args) -> log(?MODULE, String, Args, error). 153 | error( String) -> log(?MODULE, String, [], error). 154 | -------------------------------------------------------------------------------- /src/elixir/om_help.erl: -------------------------------------------------------------------------------- 1 | -module(om_help). 2 | -compile(export_all). 3 | 4 | help() -> [{a,[expr],"to parse. Returns {_,_} or {error,_}."}, 5 | {type,[term],"typechecks and returns type."}, 6 | {erase,[term],"to untyped term. Returns {_,_}."}, 7 | {norm,[term],"normalize term. Returns term's normal form."}, 8 | {file,[name],"load file as binary."}, 9 | {str,[binary],"lexical tokenizer."}, 10 | {parse,[tokens],"parse given tokens into {_,_} term."}, 11 | {fst,[{x,y}],"returns first element of a pair."}, 12 | {snd,[{x,y}],"returns second element of a pair."}, 13 | {debug,[bool],"enable/disable debug output."}, 14 | {mode,[name],"select metaverse folder."}, 15 | {modes,[],"list all metaverses."} 16 | ]. 17 | -------------------------------------------------------------------------------- /src/elixir/om_io.erl: -------------------------------------------------------------------------------- 1 | -module(om_io). 2 | -export([info/3, warning/3, error/3]). 3 | 4 | info(Module, String, Args) -> io:format(format_message(Module, String), Args). 5 | warning(Module, String, Args) -> io:format(format_message(Module, String), Args). 6 | error(Module, String, Args) -> io:format(format_message(Module, String), Args). 7 | format_message(Module, String) -> lists:concat([Module, ":", String, "\n\r"]). 8 | -------------------------------------------------------------------------------- /src/elixir/priv/AUT-68/List/@.aut: -------------------------------------------------------------------------------- 1 | --- List/@ AUT-68 2 | 3 | module List begin 4 | variable (A : *) 5 | def rec := (B: list A) { name : B, surname list A } 6 | def list := [List: *] [Cons: A → List → List] [Nil: List] List 7 | def nil := (List: *) (Cons: A -> List -> List) (Nil: List) Nil 8 | def cons := (Head: A) (Tail: [List: *] [Cons: A -> List -> List] [Nil: List] List) 9 | (List: *) (Cons: A -> List -> List) (Nil: List) Cons Head (Tail List Cons Nil) 10 | def list (A: U) : U := | nil : list , cons : A -> list -> list | 11 | 12 | def fix len (A : U) (acc: N) : (L : list A) -> N 13 | := case | nil -> Acc , cons x xs -> len A (succ acc) xs | 14 | 15 | def list-Lamb (A : U) : U := ( nil : list , cons : A -> list -> list ) 1 16 | def list-Func (A : U) : U := [ nil : list , cons : A -> list -> list ] 1 17 | def list-Pair (A : *) : U := { nil : list , cons : A -> list -> list } 1 18 | def list-Summ (A : U) : U := | nil : list , cons : A -> list -> list | 0 19 | 20 | def patient : list-Alg A := { nil, (x:A,xs:List) cons x xs (list cons nil) } 21 | end 22 | -------------------------------------------------------------------------------- /src/elixir/priv/AUT-68/List/Cons.aut: -------------------------------------------------------------------------------- 1 | --- List/Cons AUT-68 2 | (A: *) (Head: A) (Tail: [List: *] [Cons: A -> List -> List] [Nil: List] List) 3 | (List: *) (Cons: A -> List -> List) (Nil: List) Cons Head (Tail List Cons Nil) 4 | -------------------------------------------------------------------------------- /src/elixir/priv/AUT-68/List/Nil.aut: -------------------------------------------------------------------------------- 1 | --- List/Nil AUT-68 2 | (A: *) (List: *) (Cons: A -> List -> List) (Nil: List) Nil 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/@: -------------------------------------------------------------------------------- 1 | ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/False: -------------------------------------------------------------------------------- 1 | λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/True: -------------------------------------------------------------------------------- 1 | λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/[&&]: -------------------------------------------------------------------------------- 1 | λ(b1 : #Bool/@ ) → λ(b2 : #Bool/@ ) → b1 #Bool/@ b2 #Bool/False 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/[||]: -------------------------------------------------------------------------------- 1 | λ(b1 : #Bool/@ ) → b1 #Bool/@ #Bool/True 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/and: -------------------------------------------------------------------------------- 1 | λ (B1: #Bool/@ ) → λ (B2: #Bool/@ ) → B1 #Bool/@ B2 #Bool/False 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/eif: -------------------------------------------------------------------------------- 1 | λ (A : *) 2 | → λ (X : #Bool/@) 3 | → λ (Y : A) 4 | → λ (Z : A) 5 | → X A Y Z 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/eiff: -------------------------------------------------------------------------------- 1 | \ (X: #Bool/@) 2 | -> \ (Y: #Nat/@) 3 | -> #Bool/eif #Nat/@ X 4 | (#Nat/[+] Y (#Nat/Succ (#Nat/Succ (#Nat/Succ (#Nat/Succ (#Nat/Succ #Nat/Zero)))))) 5 | (Y) 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/if: -------------------------------------------------------------------------------- 1 | λ (A : *) 2 | → λ (X : #Bool/@) 3 | → λ (Y : #Unit/@ → A) 4 | → λ (Z : #Unit/@ → A) 5 | → X (#Unit/@ → A) Y Z #Unit/Make 6 | 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/iff: -------------------------------------------------------------------------------- 1 | \ (X: #Bool/@) 2 | -> \ (Y: #List/@ #Nat/@) 3 | -> #Bool/if #Nat/@ X 4 | (\ (l: #Unit/@) -> #List/length #Nat/@ 5 | (#List/Cons #Nat/@ #Nat/Zero 6 | (#List/Cons #Nat/@ #Nat/Zero 7 | (#List/Cons #Nat/@ #Nat/Zero 8 | (#List/Cons #Nat/@ #Nat/Zero 9 | (#List/Cons #Nat/@ #Nat/Zero 10 | (#List/Cons #Nat/@ #Nat/Zero 11 | (#List/Cons #Nat/@ (#Nat/Succ #Nat/Zero) Y)))))))) 12 | (\ (p: #Unit/@) -> #List/length #Nat/@ Y) 13 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/induction_on.type: -------------------------------------------------------------------------------- 1 | forall (P : #Bool/@ → #Prop/@) 2 | -> ∀ (a : #Bool/@) 3 | -> P #Bool/True 4 | → P #Bool/False 5 | → P a 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/not: -------------------------------------------------------------------------------- 1 | λ(x : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → x (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Bool/or: -------------------------------------------------------------------------------- 1 | λ(Xs : ∀(List : *) → ∀(Cons : ∀(Head : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → ∀(tail : List) → List) → ∀(Nil : List) → List) → Xs (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(x : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → x (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True)) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/@: -------------------------------------------------------------------------------- 1 | λ (f : * → *) 2 | → λ (a : *) 3 | → ∀ (Cmd : *) 4 | → ∀ (Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) 5 | → ∀ (Pure : ∀(r : a) → Cmd) 6 | → Cmd 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/Bind: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(a : *) → λ(b : *) → λ(_x : f b) → λ(_x : b → ∀(Cmd : *) → 2 | ∀(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → ∀(Pure : ∀(r : a) → Cmd) → Cmd) → 3 | λ(Cmd : *) → λ(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → λ(Pure : ∀(r : a) → Cmd) → 4 | Bind b _x@1 (λ(_x : b) → _x@1 _x@0 Cmd Bind Pure) 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/Monad: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(a : *) → λ(cmd : #Cmd/@ (#Cmd/@ f) a) → λ(Cmd : *) → λ(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → cmd Cmd (λ(b : *) → λ(x : #Cmd/@ f b) → x Cmd Bind) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/Monad.old: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(cmd : #Cmd/@ #IO/@ a) → cmd (#IO/@ a) (λ(b : *) → #IO/[>>=] b a) (#IO/pure a) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/Pure: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(a : *) → λ(r : a) → λ(Cmd : *) → λ(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → λ(Pure : ∀(r : a) → Cmd) → Pure r 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/[>>=]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(m : * → *) → λ(cmd : #Cmd/@ m a) → cmd (#Cmd/@ m b) (#Cmd/Bind m b) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/embed: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(g : * → *) → λ(k : ∀(a : *) → f a → #Cmd/@ g a) → λ(a : *) → λ(x : #Cmd/@ f a) → λ(Cmd : *) → λ(Bind : ∀(b : *) → g b → (b → Cmd) → Cmd) → x Cmd (λ(b : *) → λ(m : f b) → k b m Cmd Bind) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/lift: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(a : *) → λ(m : f a) → λ(Cmd : *) → λ(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → Bind a m 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/map: -------------------------------------------------------------------------------- 1 | λ(f : * → *) → λ(a : *) → λ(b : *) → λ(k : a → b) → λ(cmd : #Cmd/@ f a) → λ(Cmd : *) → λ(Bind : ∀(b : *) → f b → (b → Cmd) → Cmd) → λ(Pure : ∀(r : b) → Cmd) → cmd Cmd Bind (λ(x : a) → Pure (k x)) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Cmd/sequence_: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(cmds : #List/@ (#Cmd/@ m #Unit/@ )) → cmds (#Cmd/@ m #Unit/@ ) (λ(cmd1 : #Cmd/@ m #Unit/@ ) → λ(cmd2 : #Cmd/@ m #Unit/@ ) → #Cmd/[>>=] #Unit/@ #Unit/@ m cmd1 (λ(_x : #Unit/@ ) → cmd2)) (#Cmd/Pure m #Unit/@ #Unit/Make ) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Eq: -------------------------------------------------------------------------------- 1 | λ(a : *) → a → a → #Bool/@ 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Equ/@: -------------------------------------------------------------------------------- 1 | -- Equ/@ 2 | λ (A: *) 3 | → λ (x: A) 4 | → λ (y: A) 5 | → ∀ (Equ: A → A → *) 6 | → ∀ (Refl: ∀ (z: A) → Equ z z) 7 | → Equ x y 8 | 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Equ/Refl: -------------------------------------------------------------------------------- 1 | -- Equ/Refl 2 | λ (A: *) 3 | → \ (x: A) 4 | → \ (Equ: A → A → *) 5 | → \ (Refl: ∀ (z: A) → Equ z z) 6 | → Refl x 7 | 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Frege/@: -------------------------------------------------------------------------------- 1 | forall (p: #Prop/@) 2 | -> forall (q: #Prop/@) 3 | -> forall (r: #Prop/@) 4 | -> (p -> q -> r) 5 | -> (p -> q) 6 | -> p 7 | -> r 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Frege/intro: -------------------------------------------------------------------------------- 1 | \ (p: #Prop/@) 2 | -> \ (q: #Prop/@) 3 | -> \ (r: #Prop/@) 4 | -> \ (f: p -> q -> r) 5 | -> \ (g: p -> q) 6 | -> \ (h: p) 7 | -> f h (g h) 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/@: -------------------------------------------------------------------------------- 1 | -- IO/@ 2 | \ (a : *) 3 | -> \/ (IO : *) 4 | -> \/ (GetLine_ : (#IO/data -> IO) -> IO) 5 | -> \/ (PutLine_ : #IO/data -> IO -> IO) 6 | -> \/ (Pure_ : a -> IO) 7 | -> IO 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/[>>=]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(m : ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : 2 | #IO/data → IO → IO) → ∀(Pure_ : a → IO) → IO) → λ(f : a → ∀(IO : *) → ∀(GetLine_ : (#IO/data 3 | → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → m (∀(IO : *) → 4 | ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) 5 | (λ(_x : #IO/data → ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → 6 | ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) → λ(PutLine_ : #IO/data → IO → IO) 7 | → λ(Pure_ : b → IO) → GetLine_ (λ(_x : #IO/data ) → _x@1 _x IO GetLine_ PutLine_ Pure_)) 8 | (λ(_x : #IO/data ) → λ(_x : ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : 9 | #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) 10 | → IO) → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → PutLine_ _x@1 (_x IO GetLine_ PutLine_ Pure_)) 11 | (λ(r : a) → f r (∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → 12 | ∀(Pure_ : b → IO) → IO) (λ(_x : #IO/data → ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → 13 | ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) 14 | → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → GetLine_ (λ(_x : #IO/data ) 15 | → _x@1 _x IO GetLine_ PutLine_ Pure_)) (λ(_x : #IO/data ) → λ(_x : ∀(IO : *) → 16 | ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) 17 | → λ(GetLine_ : (#IO/data → IO) → IO) → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → PutLine_ 18 | _x@1 (_x IO GetLine_ PutLine_ Pure_)) (λ(_x : b) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) → 19 | λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → Pure_ _x)) 20 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/[>>=].Aut: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(m : ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : 2 | #IO/data → IO → IO) → ∀(Pure_ : a → IO) → IO) → λ(f : a → ∀(IO : *) → ∀(GetLine_ : (#IO/data 3 | → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → m (∀(IO : *) → 4 | ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) 5 | (λ(_x : #IO/data → ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → 6 | ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) → λ(PutLine_ : #IO/data → IO → IO) 7 | → λ(Pure_ : b → IO) → GetLine_ (λ(_x : #IO/data ) → _x@1 _x IO GetLine_ PutLine_ Pure_)) 8 | (λ(_x : #IO/data ) → λ(_x : ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : 9 | #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) 10 | → IO) → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → PutLine_ _x@1 (_x IO GetLine_ PutLine_ Pure_)) 11 | (λ(r : a) → f r (∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → 12 | ∀(Pure_ : b → IO) → IO) (λ(_x : #IO/data → ∀(IO : *) → ∀(GetLine_ : (#IO/data → IO) → IO) → 13 | ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) 14 | → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → GetLine_ (λ(_x : #IO/data ) 15 | → _x@1 _x IO GetLine_ PutLine_ Pure_)) (λ(_x : #IO/data ) → λ(_x : ∀(IO : *) → 16 | ∀(GetLine_ : (#IO/data → IO) → IO) → ∀(PutLine_ : #IO/data → IO → IO) → ∀(Pure_ : b → IO) → IO) → λ(IO : *) 17 | → λ(GetLine_ : (#IO/data → IO) → IO) → λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → PutLine_ 18 | _x@1 (_x IO GetLine_ PutLine_ Pure_)) (λ(_x : b) → λ(IO : *) → λ(GetLine_ : (#IO/data → IO) → IO) → 19 | λ(PutLine_ : #IO/data → IO → IO) → λ(Pure_ : b → IO) → Pure_ _x)) 20 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/[>>]: -------------------------------------------------------------------------------- 1 | \(m : #IO/@ #Unit/@) 2 | -> \(n : #IO/@ #Unit/@) 3 | -> #IO/[>>=] #Unit/@ #Unit/@ m (\(_x : #Unit/@) -> n) 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/data: -------------------------------------------------------------------------------- 1 | #String/@ 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/getLine: -------------------------------------------------------------------------------- 1 | λ (FIO : *) 2 | → λ (GetLine_ : (#IO/data → FIO) → FIO) 3 | → λ (PutLine_ : #IO/data → FIO → FIO) 4 | → GetLine_ 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/pure: -------------------------------------------------------------------------------- 1 | λ (a : *) 2 | → λ (_x : a) 3 | → λ (IO : *) 4 | → λ (GetLine_ : (#IO/data → IO) → IO) 5 | → λ (PutLine_ : #IO/data → IO → IO) 6 | → λ (Pure_ : a → IO) 7 | → Pure_ _x 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/putLine: -------------------------------------------------------------------------------- 1 | λ (str : #IO/data ) 2 | → λ (IO : * ) 3 | → λ (GetLine_ : (#IO/data → IO) → IO ) 4 | → λ (PutLine_ : #IO/data → IO → IO ) 5 | → λ (Pure_ : #Unit/@ → IO ) 6 | → PutLine_ str (Pure_ #Unit/Make ) 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IO/replicateM: -------------------------------------------------------------------------------- 1 | -- IO/replicateM 2 | \ (n: #Nat/@) 3 | -> \ (io: #IO/@ #Unit/@) 4 | -> #Nat/fold n (#IO/@ #Unit/@) 5 | (#IO/[>>] io) 6 | (#IO/pure #Unit/@ #Unit/Make) 7 | 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/@: -------------------------------------------------------------------------------- 1 | -- IOI/@ 2 | \ (r : *) 3 | -> forall (x : *) 4 | -> (forall (s : *) 5 | -> s 6 | -> (s -> #IOI/F r s) -> x) 7 | -> x 8 | 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/F: -------------------------------------------------------------------------------- 1 | -- IOI/F 2 | \ (a : *) 3 | -> \ (State : *) 4 | -> \/ (IOF : *) 5 | -> \/ (PutLine_ : #IOI/data -> State -> IOF) 6 | -> \/ (GetLine_ : (#IOI/data -> State) -> IOF) 7 | -> \/ (Pure_ : a -> IOF) 8 | -> IOF 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/MkIO: -------------------------------------------------------------------------------- 1 | -- IOI/MkIO 2 | \ (r : *) 3 | -> \ (s : *) 4 | -> \ (seed : s) 5 | -> \ (step : s -> #IOI/F r s) 6 | -> \ (x : *) 7 | -> \ (k : forall (s : *) -> s -> (s -> #IOI/F r s) -> x) 8 | -> k s seed step 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/data: -------------------------------------------------------------------------------- 1 | -- IOI/data 2 | #String/@ 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/getLine: -------------------------------------------------------------------------------- 1 | \(r : *) 2 | -> \(s : *) 3 | -> \(k : #IOI/data -> s) 4 | -> \(x : *) 5 | -> \(PutLine_ : #IOI/data -> s -> x) 6 | -> \(GetLine_ : (#IOI/data -> s) -> x) 7 | -> \(Return_ : r -> x) 8 | -> GetLine_ k 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/putLine: -------------------------------------------------------------------------------- 1 | \(r : *) 2 | -> \(s : *) 3 | -> \(str : #IOI/data) 4 | -> \(vs : s) 5 | -> \(x : *) 6 | -> \(PutLine_ : #IOI/data -> s -> x) 7 | -> \(GetLine_ : (#IOI/data -> s) -> x) 8 | -> \(Return_ : r -> x) 9 | -> PutLine_ str vs 10 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/IOI/return: -------------------------------------------------------------------------------- 1 | \(r : *) 2 | -> \(s : *) 3 | -> \(vr : r) 4 | -> \(x : *) 5 | -> \(PutLine_ : #IOI/data -> s -> x) 6 | -> \(GetLine_ : (#IOI/data -> s) -> x) 7 | -> \(Return_ : r -> x) 8 | -> Return_ vr 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Lazy/@: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → λ (x: a) 3 | → λ (y: #Unit/@) 4 | → x 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Lazy/delay: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → λ (delay: #Unit/@ → a) 3 | → #Lazy/@ a 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Lazy/force: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → λ (force: #Unit/@ → a) 3 | → a 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Leibnitz/@: -------------------------------------------------------------------------------- 1 | λ (T: *) 2 | → λ (a: T) 3 | → λ (b: T) 4 | → ∀ (equ: T → #Prop/@) 5 | → equ a → equ b 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Leibnitz/refl: -------------------------------------------------------------------------------- 1 | λ (T: *) 2 | → λ (a: T) 3 | → λ (Equ: ∀ (a: T) → #Prop/@) 4 | → #Prop/id (Equ a) 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Leibnitz/theorem: -------------------------------------------------------------------------------- 1 | (\ (x : (#Leibnitz/@ #Nat/@ #Nat/Zero #Nat/Zero)) -> x) 2 | (#Leibnitz/refl #Nat/@ #Nat/Zero) 3 | 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/@: -------------------------------------------------------------------------------- 1 | -- List/@ 2 | λ (A: *) 3 | → ∀ (L: *) 4 | → ∀ (C: A → L → L) 5 | → ∀ (N: L) 6 | → L 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/Cons: -------------------------------------------------------------------------------- 1 | -- List/Cons 2 | λ (A: *) 3 | → λ (H: A) 4 | → λ (T: 5 | ∀ (L: *) 6 | → ∀ (C: A → L → L) 7 | → ∀ (N: L) 8 | → L) 9 | → λ (L: *) 10 | → λ (C: A → L → L) 11 | → λ (N: L) 12 | → C H (T L C N) 13 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/Nil: -------------------------------------------------------------------------------- 1 | -- List/Nil 2 | λ (A: *) 3 | → λ (L: *) 4 | → λ (C: A → L → L) 5 | → λ (N: L) 6 | → N 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[++]: -------------------------------------------------------------------------------- 1 | λ (a : *) 2 | → λ (as1 : #List/@ a) 3 | → λ (as2 : #List/@ a) 4 | → λ (List : *) 5 | → λ (Cons : a → List → List) 6 | → λ (Nil : List) 7 | → as1 List Cons (as2 List Cons Nil) 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[<=<]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(g : b → ∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(f : a → ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(x : a) → f x (∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : b) → g head (∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : c) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : c) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) (λ(List : *) → λ(Cons : ∀(head : c) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[<|>]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil)) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[=<<]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(f : a → ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → f head (∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : b) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) (λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[>=>]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(f : a → ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(g : b → ∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(x : a) → f x (∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : b) → g head (∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : c) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : c) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : c) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) (λ(List : *) → λ(Cons : ∀(head : c) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/[>>=]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(f : a → ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → f head (∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : b) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) (λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/all: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(f : a → ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(head : a) → λ(tail : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → f head (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) tail (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False)) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/any: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(f : a → ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(head : a) → f head (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True)) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/concat: -------------------------------------------------------------------------------- 1 | 2 | λ (a : *) 3 | → λ (xs: ∀ (List : *) 4 | → ∀ (Cons : ∀ (head : ∀(List : *) 5 | → ∀ (Cons : ∀(head : a) 6 | → ∀ (tail : List) → List) 7 | → ∀ (Nil : List) → List) 8 | → ∀ (tail : List) → List) 9 | → ∀ (Nil : List) → List) 10 | → xs (∀ (List : *) 11 | → ∀ (Cons : ∀ (head : a) → 12 | ∀ (tail : List) → List) 13 | → ∀(Nil : List) → List) 14 | (λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 15 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/cond: -------------------------------------------------------------------------------- 1 | -- List/cond 2 | \ (a : *) 3 | -> \ (x: \/ (r : *) -> (a -> r -> r) -> r -> r) 4 | -> x 5 | 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/empty: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Nil 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/filter: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(f : a → ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → f head (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → Cons head) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Nil) (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil))) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/flip: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(f : ∀(x : a) → ∀(y : b) → c) → λ(y : b) → λ(x : a) → f x y 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/head: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(xs : #List/@ a) → xs (#Maybe/@ a) (λ(x : a) → λ(_ : #Maybe/@ a) → #Maybe/Just a x) (#Maybe/Nothing a) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/length: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) (λ(head : a) → λ(pred : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Succ (pred Nat Succ Zero)) (λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Zero) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/map: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(f : a → b) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : b) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Cons (f head) (tail List Cons Nil)) (λ(List : *) → λ(Cons : ∀(head : b) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/match: -------------------------------------------------------------------------------- 1 | -- List/match 2 | \ (A: *) 3 | -> \ (value: #List/@ A) 4 | -> \ (ret: *) 5 | -> \ (cons_branch: ret) 6 | -> \ (nil_branch: ret) 7 | -> #List/cond A value ret 8 | (\(_:A)->\(_:ret)-> cons_branch) 9 | nil_branch 10 | 11 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/match.test: -------------------------------------------------------------------------------- 1 | -- List/match.test 2 | #List/match #Nat/@ (#List/Nil #Nat/@) 3 | #Nat/@ #Nat/Two #Nat/Five 4 | 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/match.test2: -------------------------------------------------------------------------------- 1 | -- List/match.test2 2 | #List/match #Nat/@ (#List/Cons #Nat/@ #Nat/Zero (#List/Nil #Nat/@)) 3 | #Nat/@ #Nat/Two #Nat/Five 4 | 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/null: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(head : a) → λ(tail : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/pure: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(x : a) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → Cons x 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/replicate: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(n : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(x : a) → n (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Cons x (tail List Cons Nil)) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/reverse: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → tail (∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) (λ(head : a) → λ(tail : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Cons head (tail List Cons Nil)) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → Cons head)) (λ(List : *) → λ(Cons : ∀(head : a) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/List/tail: -------------------------------------------------------------------------------- 1 | λ (a : *) 2 | → λ (xs : #List/@ a) 3 | → xs ( ∀ (S : *) 4 | → ∀ (Empty : S) 5 | → ∀ (NonEmpty : 6 | ∀ (head : a) 7 | → ∀ (tail : #List/@ a) → S) 8 | → S) 9 | ( λ (x : a) 10 | → λ (s : 11 | ∀ (S : *) 12 | → ∀ (Empty : S) 13 | → ∀ (NonEmpty : 14 | ∀ (head : a) 15 | → ∀ (tail : #List/@ a) → S) 16 | → S) 17 | → s (∀ (S : *) 18 | → ∀ (Empty : S) 19 | → ∀ (NonEmpty : 20 | ∀ (head : a) 21 | → ∀ (tail : #List/@ a) 22 | → S) 23 | → S) 24 | ( λ (S : *) 25 | → λ (Empty : S) 26 | → λ (NonEmpty : 27 | ∀ (head : a) 28 | → ∀ (tail : #List/@ a) 29 | → S) 30 | → NonEmpty x (λ (List : *) 31 | → λ (Cons : 32 | ∀ (head : a) 33 | → ∀ (tail : List) 34 | → List) 35 | → λ (Nil : List) 36 | → Nil)) 37 | ( λ (head : a) 38 | → λ (tail : #List/@ a) 39 | → λ (S : *) 40 | → λ (Empty : S) 41 | → λ (NonEmpty : 42 | ∀ (head : a) 43 | → ∀ (tail : #List/@ a) 44 | → S) 45 | → NonEmpty x (#List/Cons a head tail))) 46 | ( λ (S : *) 47 | → λ (Empty : S) 48 | → λ (NonEmpty : 49 | ∀ (head : a) 50 | → ∀ (tail : #List/@ a) 51 | → S) 52 | → Empty) (#Maybe/@ (#List/@ a)) (#Maybe/Nothing (#List/@ a)) (λ (_ : a) → #Maybe/Just (#List/@ a)) 53 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/0: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(x : ∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) → x 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/@: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → ∀ (Maybe: *) 3 | → ∀ (Just: 4 | ∀ (_Just: a) 5 | → Maybe) 6 | → ∀ (Nothing : Maybe) 7 | → Maybe 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/Just: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(_Just : a) → λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Just _Just 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/Nothing: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Nothing 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/[<=<]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(g : b → ∀(Maybe : *) → ∀(Just : ∀(_Just : c) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(f : a → ∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(x : a) → f x (∀(Maybe : *) → ∀(Just : ∀(_Just : c) → Maybe) → ∀(Nothing : Maybe) → Maybe) g (λ(Maybe : *) → λ(Just : ∀(_Just : c) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/[<|>]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(x : ∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) → x (∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) (λ(_Just : a) → λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Just _Just) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/[=<<]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(f : a → ∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(x : ∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) → x (∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) f (λ(Maybe : *) → λ(Just : ∀(_Just : b) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/[>=>]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(f : a → ∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(g : b → ∀(Maybe : *) → ∀(Just : ∀(_Just : c) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(x : a) → f x (∀(Maybe : *) → ∀(Just : ∀(_Just : c) → Maybe) → ∀(Nothing : Maybe) → Maybe) g (λ(Maybe : *) → λ(Just : ∀(_Just : c) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/[>>=]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(x : ∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) → λ(f : a → ∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) → x (∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) f (λ(Maybe : *) → λ(Just : ∀(_Just : b) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/empty: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Nothing 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/map: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(f : a → b) → λ(x : ∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) → x (∀(Maybe : *) → ∀(Just : ∀(_Just : b) → Maybe) → ∀(Nothing : Maybe) → Maybe) (λ(_Just : a) → λ(Maybe : *) → λ(Just : ∀(_Just : b) → Maybe) → λ(Nothing : Maybe) → Just (f _Just)) (λ(Maybe : *) → λ(Just : ∀(_Just : b) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/maybe: -------------------------------------------------------------------------------- 1 | \(a : *) -> \(m : forall (x : *) -> (a -> x) -> x-> x) -> m 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Maybe/pure: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(x : a) → λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Just x 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Mon/@: -------------------------------------------------------------------------------- 1 | λ(a : *) → ∀(Prod1 : *) → ∀(Make : ∀(_1 : a) → Prod1) → Prod1 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Mon/Eq: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(eqA : #Eq a) → λ(p1 : #Mon/@ a) → λ(p2 : #Mon/@ a) → p1 #Bool/@ (λ(_1 : a) → p2 #Bool/@ (eqA _1)) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Mon/Make: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(_1 : a) → λ(Prod1 : *) → λ(Make : ∀(_1 : a) → Prod1) → Make _1 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Mon/get: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(_1 : a) → λ(product : #Mon/@ a) → _1 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/@: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → ∀(a : *) → #Cmd/@ m a → m a 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/[<=<]: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(c : *) → λ(monad : #Monad/@ m) → λ(g : b → m c) → 2 | λ(f : a → m b) → λ(x : a) → monad c (λ(Cmd : *) → λ(Bind : ∀(b : *) → m b → (b → Cmd) → Cmd) → 3 | λ(Pure : ∀(z : c) → Cmd) → Bind b (f x) (λ(y : b) → Bind c (g y) Pure)) 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/[=<<]: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(monad : #Monad/@ m) → λ(f : a → m b) → λ(n : m a) → monad b (λ(Cmd : *) → 2 | λ(Bind : ∀(b : *) → m b → (b → Cmd) → Cmd) → λ(Pure : b → Cmd) → Bind a n (λ(x : a) → Bind b (f x) Pure)) 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/[>=>]: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(c : *) → λ(monad : #Monad/@ m) → λ(f : a → m b) → λ(g : b → m c) → 2 | λ(x : a) → monad c (λ(Cmd : *) → λ(Bind : ∀(b : *) → m b → (b → Cmd) → Cmd) → λ(Pure : ∀(z : c) → Cmd) → 3 | Bind b (f x) (λ(y : b) → Bind c (g y) Pure)) 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/[>>=]: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(monad : #Monad/@ m) → λ(n : m a) → λ(f : a → m b) → 2 | monad b (λ(Cmd : *) → λ(Bind : ∀(b : *) → m b → (b → Cmd) → Cmd) → λ(Pure : b → Cmd) → 3 | Bind a n (λ(x : a) → Bind b (f x) Pure)) 4 | 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/forM: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(as : #List/@ a) → λ(f : a → m b) → #Monad/sequence m b (#List/map a (m b) f as) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/forM_: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(monad : #Monad/@ m) → λ(as : #List/@ a) → λ(f : a → m #Unit/@ ) → #Monad/sequence_ 2 | m (#List/map a (m #Unit/@ ) f as) 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/join: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(monad : #Monad/@ m) → λ(a : *) → λ(x : m (m a)) → monad a (λ(Cmd : *) → λ(Bind : ∀(b : *) → m b → (b → Cmd) → Cmd) → λ(Pure : a → Cmd) → Bind (m a) x (λ(y : m a) → Bind a y Pure)) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/mapM: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(f : a → m b) → λ(as : #List/@ a) → #Monad/sequence m b (#List/map a (m b) f as) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/mapM_: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(b : *) → λ(monad : #Monad/@ m) → λ(f : a → m #Unit/@ ) → λ(as : #List/@ a) → #Monad/sequence_ m (#List/map a (m #Unit/@ ) f as) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/replicateM: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(monad : #Monad/@ m) → λ(n : #Nat/@ ) → λ(a : *) → λ(cmd : m a) → #Monad/sequence m a (#List/replicate (m a) n cmd) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/replicateM_: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(n : #Nat/@ ) → λ(cmd : m #Unit/@ ) → #Monad/sequence_ m (#List/replicate (m #Unit/@ ) n cmd) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/sequence: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(a : *) → λ(cmds : #List/@ (m a)) → cmds (#Cmd/@ m (#List/@ a)) (λ(cmd1 : m a) → λ(cmd2 : #Cmd/@ 2 | m (#List/@ a)) → #Cmd/Monad m (#List/@ a) (λ(Cmd : *) → λ(Bind : ∀(b : *) → #Cmd/@ m b → (b → Cmd) → Cmd) → 3 | λ(Pure : #List/@ a → Cmd) → Bind a (#Cmd/lift m a cmd1) (λ(x : a) → Bind (#List/@ a) cmd2 (λ(xs : #List/@ a) 4 | → Bind (#List/@ a) (#Cmd/Pure m (#List/@ a) (#List/Cons a x xs)) Pure)))) (#Cmd/Pure m (#List/@ a) (#List/Nil a)) 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monad/sequence_: -------------------------------------------------------------------------------- 1 | λ(m : * → *) → λ(cmds : #List/@ (m #Unit/@ )) → cmds (#Cmd/@ m #Unit/@ ) (λ(cmd1 : m #Unit/@ ) → 2 | λ(cmd2 : #Cmd/@ m #Unit/@ ) → #Cmd/Bind m #Unit/@ #Unit/@ cmd1 (λ(_ : #Unit/@ ) → cmd2)) (#Cmd/Pure m #Unit/@ #Unit/Make ) 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monoid/@: -------------------------------------------------------------------------------- 1 | λ(m : *) → #List/@ m → m 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monoid/mappend: -------------------------------------------------------------------------------- 1 | λ(m : *) → λ(monoid : #Monoid/@ m) → λ(l : m) → λ(r : m) → monoid (λ(List : *) → λ(Cons : ∀(head : m) → ∀(tail : List) → List) → λ(Nil : List) → Cons l (Cons r Nil)) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Monoid/mempty: -------------------------------------------------------------------------------- 1 | λ(m : *) → λ(monoid : #Monoid/@ m) → monoid (λ(List : *) → λ(Cons : ∀(head : m) → ∀(tail : List) → List) → λ(Nil : List) → Nil) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Morte/corecursive: -------------------------------------------------------------------------------- 1 | \(r : *1) 2 | -> #IOI/MkIO 3 | r 4 | (#Maybe/@ #IOI/data) 5 | (#Maybe/Nothing #IOI/data) 6 | ( \(m : #Maybe/@ #IOI/data) 7 | -> #Maybe/maybe 8 | #IOI/data 9 | m 10 | (#IOI/F r (#Maybe/@ #IOI/data)) 11 | (\(str : #IOI/data) -> 12 | #IOI/putLine 13 | r 14 | (#Maybe/@ #IOI/data) 15 | str 16 | (#Maybe/Nothing #IOI/data) 17 | ) 18 | (#IOI/getLine r (#Maybe/@ #IOI/data) (#Maybe/Just #IOI/data)) 19 | ) 20 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Morte/recursive: -------------------------------------------------------------------------------- 1 | #IO/replicateM 2 | ( -- 99 is too slow, so comment +90 out 3 | --#Nat/[+] (#Nat/[*] #Nat/Nine #Nat/Ten) 4 | #Nat/Five) 5 | (#IO/[>>=] #IO/data #Unit/@ 6 | #IO/getLine 7 | #IO/putLine) 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/@: -------------------------------------------------------------------------------- 1 | ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Eight: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Seven 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Five: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Four 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Four: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Three 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Hundreed: -------------------------------------------------------------------------------- 1 | #Nat/[*] #Nat/Ten #Nat/Ten 2 | 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Nine: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Eight 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/One: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Zero 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Seven: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Six 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Six: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Five 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Succ: -------------------------------------------------------------------------------- 1 | λ(pred : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Succ (pred Nat Succ Zero) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Succ2: -------------------------------------------------------------------------------- 1 | 2 | -- Compose/Cont Encoding 3 | 4 | λ (Argument: \/(N:*)->(N->N)->N->N) 5 | → λ (Nat: *) 6 | → λ (Succ.CPS: (#Nat/@ -> Nat) -> #Nat/@ -> Nat) 7 | → λ (Succ: Nat -> Nat) 8 | → λ (Zero: Nat) 9 | → Succ.CPS (λ (C: #Nat/@) -> C Nat Succ Zero) Argument 10 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Ten: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Nine 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Thousand: -------------------------------------------------------------------------------- 1 | #Nat/[*] #Nat/Ten #Nat/Hundreed 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Three: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/Two 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Two: -------------------------------------------------------------------------------- 1 | #Nat/Succ #Nat/One 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/Zero: -------------------------------------------------------------------------------- 1 | λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Zero 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/[*]: -------------------------------------------------------------------------------- 1 | λ(x : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(y : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → x (∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) (y (∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) (λ(pred : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Succ (pred Nat Succ Zero))) 2 | (λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Zero) 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/[+]: -------------------------------------------------------------------------------- 1 | λ (x : ∀(Nat : *) 2 | → ∀ (Succ : Nat → Nat) 3 | → ∀ (Zero : Nat) → Nat) 4 | → x ( 5 | ∀ (Nat : *) 6 | → ∀ (Succ : Nat → Nat) 7 | → ∀ (Zero : Nat) → Nat) ( λ (pred : ∀(Nat : *) 8 | → ∀ (Succ : Nat → Nat) 9 | → ∀ (Zero : Nat) → Nat) 10 | → λ (Nat : *) → λ (Succ : Nat → Nat) 11 | → λ (Zero : Nat) → Succ (pred Nat Succ Zero)) 12 | 13 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/fold: -------------------------------------------------------------------------------- 1 | #id #Nat/@ 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/odd: -------------------------------------------------------------------------------- 1 | λ(x : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → x (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(x : ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → x (∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → True)) (λ(Bool : *) → λ(True : Bool) → λ(False : Bool) → False) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/product: -------------------------------------------------------------------------------- 1 | λ (xs : ∀ (List : *) → 2 | ∀ (Cons : ∀ (head : ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) → 3 | ∀ (tail : List) → List) → 4 | ∀ (Nil : List) → List) → 5 | xs ( ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) 6 | ( λ (x : ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) → 7 | λ (y : ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) → 8 | x ( ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) 9 | ( y ( ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) 10 | ( λ (pred : ∀ (Nat : *) → ∀ (Succ : Nat → Nat) → ∀ (Zero : Nat) → Nat) → 11 | λ (Nat : *) → λ (Succ : Nat → Nat) → λ (Zero : Nat) → Succ (pred Nat Succ Zero))) 12 | ( λ (Nat : *) → λ (Succ : Nat → Nat) → λ (Zero : Nat) → Zero)) 13 | ( λ (Nat : *) → λ (Succ : Nat → Nat) → Succ) 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Nat/sum: -------------------------------------------------------------------------------- 1 | λ(xs : ∀(List : *) → ∀(Cons : ∀(head : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) (λ(x : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → x (∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) (λ(pred : ∀(Nat : *) → ∀(Succ : Nat → Nat) → ∀(Zero : Nat) → Nat) → λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Succ (pred Nat Succ Zero))) (λ(Nat : *) → λ(Succ : Nat → Nat) → λ(Zero : Nat) → Zero) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Path/@: -------------------------------------------------------------------------------- 1 | λ (f: * → * → *) 2 | → λ (a: *) 3 | → λ (b: *) 4 | → ∀ (Path: 5 | ∀ (a: *) 6 | → ∀ (b: *) 7 | → *) 8 | → ∀ (Step: 9 | ∀ (a: *) 10 | → ∀ (b: *) 11 | → ∀ (c: *) 12 | → ∀ (head: f a b) 13 | → ∀ (tail: Path b c) 14 | → Path a c) 15 | → ∀ (End: 16 | ∀(a: *) 17 | → Path a a) 18 | → Path a b 19 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Path/End: -------------------------------------------------------------------------------- 1 | λ(f : * → * → *) → λ(a : *) → λ(Path : ∀(a : *) → ∀(c : *) → *) → λ(Step : ∀(a : *) → ∀(b : *) → ∀(c : *) → ∀(head : f a b) → ∀(tail : Path b c) → Path a c) → λ(End : ∀(a : *) → Path a a) → End a 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Path/Step: -------------------------------------------------------------------------------- 1 | λ(f : * → * → *) → λ(a : *) → λ(b : *) → λ(c : *) → λ(head : f a b) → λ(tail : #Path/@ f b c) → λ(Path : ∀(a : *) → ∀(c : *) → *) → λ(Step : ∀(a : *) → ∀(b : *) → ∀(c : *) → ∀(head : f a b) → ∀(tail : Path b c) → Path a c) → λ(End : ∀(a : *) → Path a a) → Step a b c head (tail Path Step End) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prod/@: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → λ (b: *) 3 | → ∀ (Prod2: *) 4 | → ∀ (Make: 5 | ∀ (_1 : a) 6 | → ∀ (_2 : b) 7 | → Prod2) 8 | → Prod2 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prod/Eq: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(eqA : #Eq a) → λ(eqB : #Eq b) → λ(p1 : #Prod/@ a b) → λ(p2 : #Prod/@ a b) 2 | → p1 #Bool/@ (λ(_1 : a) → λ(_2 : b) → p2 #Bool/@ (λ(_1 : a) → λ(_2 : b) → #Bool/[&&] (eqA _1@1 _1) (eqB _2@1 _2))) 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prod/Make: -------------------------------------------------------------------------------- 1 | λ (a: *) 2 | → λ (b: *) 3 | → λ (_1: a) 4 | → λ (_2: b) 5 | → λ (Prod2: *) 6 | → λ (Make: 7 | ∀ (x: a) 8 | → ∀ (y: b) 9 | → Prod2) 10 | → Make _1 _2 11 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prod/fst: -------------------------------------------------------------------------------- 1 | \(a: *) 2 | -> \(b: *) 3 | -> \(p: #Prod/@ a b) 4 | -> p a (\(_1 : a) -> \(_2 : b) -> _1) 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prod/snd: -------------------------------------------------------------------------------- 1 | \(a: *) 2 | -> \(b: *) 3 | -> \(p: #Prod/@ a b) 4 | -> p b (\(_1 : a) -> \(_2 : b) -> _2) 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/@: -------------------------------------------------------------------------------- 1 | *0 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/Exists: -------------------------------------------------------------------------------- 1 | -- Prop/Exists 2 | \ (A: *) 3 | -> \ (P: A -> *) 4 | -> \ (x: A) 5 | -> \/ (X: #Prop/@) 6 | -> (\/ (x: A) -> P x -> X) 7 | -> X 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/Exists.proof: -------------------------------------------------------------------------------- 1 | -- Prop/Exists.proof 2 | \ (A: *) 3 | -> \ (P: A -> *) 4 | -> \ (x: A) 5 | -> \ (X: #Prop/@) 6 | -> \ (Z: P x) 7 | -> \ (Y: \/ (y: A) -> P y -> X) 8 | -> Y x Z 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/False: -------------------------------------------------------------------------------- 1 | -- #False : #Prop/@ 2 | ∀ (False: #Prop/@) → False 3 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/Proof1: -------------------------------------------------------------------------------- 1 | \ (A:*) 2 | -> \ (B:*) 3 | -> \ (f: (A -> B) -> A)) 4 | -> \ (u: A -> B) 5 | -> u (f u) 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/Theorem1: -------------------------------------------------------------------------------- 1 | \ (A:*) 2 | -> \ (B:*) 3 | -> ((A → B) → A) → (A → B) → B 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/True: -------------------------------------------------------------------------------- 1 | -- #True/intro : #True/@ 2 | λ (True: #Prop/@) 3 | → λ (Intro: True) 4 | → Intro 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/True.type: -------------------------------------------------------------------------------- 1 | -- #True : #Prop/@ 2 | ∀ (True: #Prop/@) 3 | → ∀ (Intro: True) 4 | → True 5 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Prop/id: -------------------------------------------------------------------------------- 1 | λ (x: #Prop/@) 2 | → λ (t: x) 3 | → t 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/@: -------------------------------------------------------------------------------- 1 | -- Sigma/@ 2 | \ (A: *) 3 | -> \ (P: A -> *) 4 | -> \ (n: A) 5 | -> \/ (Exists: *) 6 | -> \/ (Intro: A -> P n -> Exists) 7 | -> Exists 8 | 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/Intro: -------------------------------------------------------------------------------- 1 | -- Sigma/Intro 2 | \ (A: *) 3 | -> \ (P: A -> *) 4 | -> \ (x: A) 5 | -> \ (y: P x) 6 | -> \ (Exists: *) 7 | -> \ (Intro: \/(x: A) -> P x -> Exists) 8 | -> Intro x y 9 | 10 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/fst: -------------------------------------------------------------------------------- 1 | -- Sigma/fst 2 | \ (A: *) 3 | -> \ (B: A -> *) 4 | -> \ (n: A) 5 | -> \ (S: #Sigma/@ A B n) 6 | -> S A ( \(x: A) -> \(_: B n) -> x ) 7 | 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/snd: -------------------------------------------------------------------------------- 1 | -- Sigma/snd 2 | \ (A: *) 3 | -> \ (B: A -> *) 4 | -> \ (n: A) 5 | -> \ (S: #Sigma/@ A B n) 6 | -> S (B n) ( \(_: A) -> \(y: B n) -> y ) 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/test: -------------------------------------------------------------------------------- 1 | -- Sigma/test 2 | #Sigma/Intro #Nat/@ 3 | (\(n: #Nat/@) -> #List/@ #Nat/@) 4 | #Nat/Five 5 | (#List/replicate #Nat/@ #Nat/Five #Nat/Zero) 6 | 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/test.first: -------------------------------------------------------------------------------- 1 | -- Sigma/test.fst 2 | #Sigma/fst #Nat/@ (\(n: #Nat/@) -> #List/@ #Nat/@) #Nat/Zero #Sigma/test 3 | 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Sigma/test.second: -------------------------------------------------------------------------------- 1 | -- Sigma/test.snd 2 | #Sigma/snd #Nat/@ 3 | (\(n: #Nat/@) -> #List/@ #Nat/@) 4 | #Nat/Zero 5 | #Sigma/test 6 | 7 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Simple/@: -------------------------------------------------------------------------------- 1 | forall (p: #Prop/@) 2 | → forall (q: #Prop/@) 3 | → p → (q → p) 4 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Simple/intro: -------------------------------------------------------------------------------- 1 | λ (p: #Prop/@) 2 | → λ (q: #Prop/@) 3 | → λ (pp: p) 4 | → λ (qq: q) 5 | → pp 6 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/String/@: -------------------------------------------------------------------------------- 1 | #List/@ #Nat/@ 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Unit/@: -------------------------------------------------------------------------------- 1 | ∀(Prod0 : *) → ∀(Make : Prod0) → Prod0 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Unit/Eq: -------------------------------------------------------------------------------- 1 | λ(_ : #Unit/@ ) → λ(_ : #Unit/@ ) → #Bool/True 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Unit/Make: -------------------------------------------------------------------------------- 1 | λ(Prod0 : *) → λ(Make : Prod0) → Make 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Vector/@: -------------------------------------------------------------------------------- 1 | -- Vector/@ 2 | \ (n: #Nat/@) 3 | -> \ (a: *) 4 | -> \/ (Vector: #Nat/@ -> * -> *) 5 | -> \/ (Cons: \/ (m: #Nat/@ ) -> \/ (b: *) -> b -> Vector m b -> Vector (#Nat/Succ m) b) 6 | -> \/ (Nil: \/ (b: *) -> Vector #Nat/Zero b) 7 | -> Vector n a 8 | 9 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/Vector/Nil: -------------------------------------------------------------------------------- 1 | -- Vector/Nil 2 | \ (A: *) 3 | -> \ (Vector: #Nat/@ -> * -> *) 4 | -> \ (Cons: \/ (m: #Nat/@ ) -> \/ (b: *) -> b -> Vector m b -> Vector (#Nat/Succ m) b) 5 | -> \ (Nil: \/ (b: *) -> Vector #Nat/Zero b) 6 | -> Nil 7 | 8 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/[.]: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(b : *) → λ(c : *) → λ(g : b → c) → λ(f : a → b) → λ(x : a) → g (f x) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/find: -------------------------------------------------------------------------------- 1 | λ(a : *) → λ(f : a → ∀(Bool : *) → ∀(True : Bool) → ∀(False : Bool) → Bool) → λ(xs : ∀(List : *) → ∀(Cons : ∀(head : a) → ∀(tail : List) → List) → ∀(Nil : List) → List) → xs (∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) (λ(head : a) → f head (∀(Maybe : *) → ∀(Just : ∀(_Just : a) → Maybe) → ∀(Nothing : Maybe) → Maybe) (λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Just head)) (λ(Maybe : *) → λ(Just : ∀(_Just : a) → Maybe) → λ(Nothing : Maybe) → Nothing) 2 | -------------------------------------------------------------------------------- /src/elixir/priv/Morte/id: -------------------------------------------------------------------------------- 1 | \(T : *) -> \(t : T) -> t 2 | -------------------------------------------------------------------------------- /src/elixir/rebar.config: -------------------------------------------------------------------------------- 1 | {deps, [{mad, ".*", {git, "https://github.com/synrc/mad", {tag,"master"}}}]}. 2 | 3 | -------------------------------------------------------------------------------- /src/elixir/syntax/morte/om_parse.erl: -------------------------------------------------------------------------------- 1 | -module(om_parse). 2 | -description('Parser'). 3 | -compile(export_all). 4 | -define(arr(F), (F == lambda orelse F == pi)). 5 | -define(noh(F), (F /= '$' andalso F /= ':')). 6 | -define(nah(F,C), (?noh(C) andalso ?noh(F))). 7 | -define(reason1, "syntax violation"). 8 | -define(reason2, "syntax violation"). 9 | -define(reason3, "wrong function definition"). 10 | 11 | expr(_,[], [{':',X}],{_,_}) -> {error,{?reason3,X}}; 12 | expr(_,[], A,{V,D}) -> rewind(A,{V,D},[]); 13 | expr(P,[close |T], A,{_,D}) -> case rewind(A,{D,D},[]) of 14 | {error,R} -> {error,R}; 15 | {{V1,D1},A1} -> expr(P,T,A1,{V1,D1}) end; 16 | 17 | expr(P,[F,open,{var,L},colon |T], Acc, {V,D}) when ?arr(F) -> expr(P,T,[{'$',{func(F),L}}|Acc],{V,D+1}); 18 | expr(P,[{remote,{_,L}}|T], [{C,Y}|Acc],{V,D}) when ?noh(C) -> expr(P,T,[{app,{{C,Y},{remote,L}}}|Acc],{V,D}); 19 | expr(P,[{remote,{_,L}} |T], Acc, {V,D}) -> expr(P,T,[{remote,L}|Acc],{V,D}); 20 | expr(P,[{N,X}|T], [{C,Y}|Acc],{V,D}) when ?nah(N,C) -> expr(P,T,[{app,{{C,Y},{N,X}}}|Acc],{V,D}); 21 | expr(P,[{N,X} |T], Acc, {V,D}) when ?noh(N) -> expr(P,T,[{N,X}|Acc],{V,D}); 22 | expr(P,[open |T], Acc, {V,D}) -> expr(P,T,[{open}|Acc],{V,D+1}); 23 | expr(P,[box |T], Acc, {V,D}) -> expr(P,T,[{star,2}|Acc],{V,D}); 24 | expr(P,[arrow |T], Acc, {V,D}) -> expr(P,T,[{arrow}|Acc],{V,D}); 25 | expr(_,[X |T], _cc, {_,_}) -> {error,{?reason1,hd(lists:flatten([X|T]))}}. 26 | 27 | rewind([], {V,D}, R) -> {{V,D},om:flat(R)}; 28 | rewind([{':',_}|_]=A, {V,D}, R) -> {{V,D},om:flat([R|A])}; 29 | rewind([{'$',M}|A], {V,D},[{C,X}|R]) -> rewind([{':',{M,{C,X}}}|A],{V,D},R); 30 | rewind([{arrow},{':',{M,I}} |A],{V,D},[{C,X}|R]) -> rewind([{M,{I,{C,X}}}|A],{V,D},R); 31 | rewind([{arrow},{B,Y} |A],{V,D},[{C,X}|R]) -> rewind([{func(arrow),{{B,Y},{C,X}}}|A],{V,D},R); 32 | rewind([{C,X},{'$',M}|A],{V,D},R) when V == D -> rewind([{':',{M,{C,X}}}|A],{V,D},R); 33 | rewind([{_,_},{'$',_}|_]=A, {V,D}, R) -> {{V,D}, om:flat([A|R])}; 34 | rewind([{C,X},{open},{':',{M,I}} |A],{V,D}, R) -> {{V,D-1},om:flat([{C,X},{':',{M,I}} |[R|A]])}; 35 | rewind([{C,X},{open},{'$',M} |A],{V,D}, R) -> {{V,D-1},om:flat([{C,X},{'$',M} |[R|A]])}; 36 | rewind([{C,X},{open},{open} |A],{V,D}, R) -> {{V,D-1},om:flat([{C,X},{open} |[R|A]])}; 37 | rewind([{C,X},{open},{B,Y} |A],{V,D}, R) -> {{V,D-1},om:flat([{app,{{B,Y},{C,X}}}|[R|A]])}; 38 | rewind([{C,X},{open}|A],{V,D}, R) -> {{V,D-1},om:flat([{C,X}|[R|A]])}; 39 | rewind([{C,X},{arrow},{':',{M,I}}|A],{V,D}, R) -> rewind([{M,{I,{C,X}}}|A],{V,D},R); 40 | rewind([{C,X},{arrow},{B,Y} |A],{V,D}, R) -> rewind([{func(arrow),{{B,Y},{C,X}}}|A],{V,D},R); 41 | rewind([{C,X},{B,Y}|A], {V,D}, R) when ?nah(C,B) -> rewind([{app,{{B,Y},{C,X}}}|A],{V,D},R); 42 | rewind([{_,_}]=A, {V,D}, R) when ?noh(A) -> {{V,D},om:flat([R|A])}; 43 | rewind(A, {_,_}, R) -> {error,{?reason2,hd(lists:flatten([R|A]))}}. 44 | 45 | % Syntax and Algorithm 46 | 47 | % I := #identifier 48 | % O := ∅ | ( O ) | 49 | % □ | ∀ ( I : O ) → O | 50 | % * | λ ( I : O ) → O | 51 | % I | O → O | O O 52 | 53 | % During forward pass we stack applications, then 54 | % on reaching close paren ")" we perform backward pass and stack arrows, 55 | % until neaarest unstacked open paren "(" appeared (then we just return 56 | % control to the forward pass). 57 | 58 | test() -> F = [ "(x : ( \\ (o:*) -> o ) -> p ) -> o", % colon 59 | "\\ (x : ( err (o:*) -> o ) -> p ) -> o", % -> 60 | "\\ (x:*)", % : 61 | "\\ (x : ( (o:*) -> o ) -> p ) -> o", % -> 62 | "\\ (x : ( \\ (o:*) -> o ) -> p ) err -> o", % colon 63 | "\\ (x : \\ (x: x -> l) -> o ) l -> z", % colon 64 | "\\ (x : ( (o:*) -> o ) -> p ) -> o" % colon 65 | ], 66 | 67 | T = [ "\\ (x : (\\ (o:*) -> o) l -> p ) -> o", 68 | "\\ (x : ( \\ (o: \\ (x : (\\ (o:*) -> o) l -> p ) -> o) -> o ) -> p ) -> o", 69 | "* -> a \\ (x : a (\\ (o:*) -> o) l -> p ) -> o", 70 | "\\(x : (\\ (o:*) -> o) -> p ) -> o" 71 | ], 72 | 73 | TT = lists:foldl(fun(X,Acc) -> {X,{M,_}=A} = {X,om:a(X)}, 74 | case M of error -> erlang:error(["test",X,"failed",A]); 75 | _ -> ok end, 76 | [{X,A}|Acc] end, [], T), 77 | 78 | FF =lists:foldl(fun(X,Acc) -> {X,{error,{M,A}}} = {X,om:a(X)}, 79 | [{M,X,A}|Acc] end, [], F), 80 | 81 | FF ++ TT. 82 | 83 | pad(D) -> lists:duplicate(D," "). 84 | 85 | print(any,_) -> ["any"]; 86 | print(none,_) -> ["none"]; 87 | print({remote,L},_) -> ["#", om:cat([L]) ]; 88 | print({var,{N,0}},_) -> [ om:cat([N]) ]; 89 | print({var,{N,I}},_) -> [ om:cat([N]), "@", integer_to_list(I) ]; 90 | print({star,2},_) -> [ "[]" ]; 91 | print({star,N},_) -> [ "*",om:cat([N]) ]; 92 | print({<<"→"/utf8>>,{I,O}},D) -> [ "(", print(I,D+1),"\n",pad(D),"→ ",print(O,D), ")\n" ]; 93 | print({app,{I,O}},D) -> [ "(", print(I,D)," ",print(O,D),")" ]; 94 | print({{<<"∀"/utf8>>,{N,_}},{any,O}},D) -> [ "( ∀ ", om:cat([N]),"\n",pad(D),"→ ",print(O,D),")" ]; 95 | print({{<<"∀"/utf8>>,{N,_}},{I,O}},D) -> [ "( ∀ (",om:cat([N]),": ",print(I,D+1),")\n",pad(D),"→ ",print(O,D),")" ]; 96 | print({{<<"λ"/utf8>>,{N,_}},{any,O}},D) -> [ "( λ ", om:cat([N]),"\n",pad(D),"→ ",print(O,D),")" ]; 97 | print({{<<"λ"/utf8>>,{N,_}},{I,O}},D) -> [ "( λ (",om:cat([N]),": ",print(I,D+1),")\n",pad(D),"→ ",print(O,D),")" ]. 98 | 99 | func(lambda) -> <<"λ"/utf8>>; 100 | func(pi) -> <<"∀"/utf8>>; 101 | func(arrow) -> <<"→"/utf8>>; 102 | func(star) -> <<"*"/utf8>>; 103 | func(Sym) -> Sym. 104 | 105 | ret({_,[X]}) -> X; 106 | ret(Y) -> Y. 107 | -------------------------------------------------------------------------------- /src/elixir/syntax/morte/om_tok.erl: -------------------------------------------------------------------------------- 1 | -module(om_tok). 2 | -description('Tokenizer'). 3 | -compile(export_all). 4 | -define(is_num(C), C>=$0, C=<$9 ). 5 | -define(is_space(C), C==$\r; C==$\s; C==$\t). 6 | -define(is_termi(C), C==$!; C==$$; C==$%; C==$:; C==$;; C==$~; C==$^; C==$?). 7 | -define(is_alpha(C), C>=$a, C=<$z; C>=$A, C=<$Z; C==$&; C==$|; C>=$0, C=<$9; C==$@; C==$#; 8 | C==$_; C==$/; C==$-; C==$+; C==$[; C==$]; C==$<; C==$>; C==$=; C==$.). 9 | 10 | tokens(P,<<>>, _, {_,C}, Acc) -> om:rev(stack(P,C,Acc)); 11 | tokens(P,<<"--"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{c,[]}, stack(P,C,Acc)); 12 | tokens(P,<<$\n, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L+1,{1,[]}, stack(P,C,Acc)); 13 | tokens(P,<<_, R/binary>>, L, {c,_}, Acc) -> tokens(P,R,L,{c,[]}, Acc); 14 | tokens(P,<<"->"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [arrow | stack(P,C, Acc)]); 15 | tokens(P,<<$(, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{t,[]}, [open | stack(P,C, Acc)]); 16 | tokens(P,<<$), R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{t,[]}, [close | stack(P,C, Acc)]); 17 | tokens(P,<<$*, R/binary>>, L, {a,C}, Acc) -> tokens(P,R,L,{a,[$*|C]}, Acc); 18 | tokens(P,<<$*, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{n,{star,C}}, stack(P,C,Acc)); 19 | tokens(P,<>, L, {n,{S,C}}, Acc) when ?is_num(X) -> tokens(P,R,L,{n,{S,[X|C]}}, Acc); 20 | tokens(P,<<_, R/binary>>, L, {n,{S,C}}, Acc) -> tokens(P,R,L,{1,[]}, stack(P,{S,[C]},Acc)); 21 | tokens(P,<<$:, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [colon | stack(P,C, Acc)]); 22 | tokens(P,<<"□"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [box | stack(P,C, Acc)]); 23 | tokens(P,<<"→"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [arrow | stack(P,C, Acc)]); 24 | tokens(P,<<$\\,$/, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [pi | stack(P,C, Acc)]); 25 | tokens(P,<<"∀"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [pi | stack(P,C, Acc)]); 26 | tokens(P,<<"forall"/utf8,R/binary>>,L,{_,C},Acc) -> tokens(P,R,L,{1,[]}, [pi | stack(P,C, Acc)]); 27 | tokens(P,<<"Π"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [pi | stack(P,C, Acc)]); 28 | tokens(P,<<$\\, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [lambda | stack(P,C, Acc)]); 29 | tokens(P,<<"λ"/utf8, R/binary>>, L, {_,C}, Acc) -> tokens(P,R,L,{1,[]}, [lambda | stack(P,C, Acc)]); 30 | tokens(P,<>, L, {a,C}, Acc) when ?is_alpha(X) -> tokens(P,R,L,{a,[X|C]}, Acc); 31 | tokens(P,<>, L, {_,C}, Acc) when ?is_alpha(X) -> tokens(P,R,L,{a,[X]}, stack(P,[C],Acc)); 32 | tokens(P,<>, L, {t,C}, Acc) when ?is_termi(X) -> tokens(P,R,L,{t,[X|C]}, Acc); 33 | tokens(P,<>, L, {_,C}, Acc) when ?is_termi(X) -> tokens(P,R,L,{t,[X]}, stack(P,C, [Acc])); 34 | tokens(P,<>, L, {_,C}, Acc) when ?is_space(X) -> tokens(P,R,L,{s,[C]}, Acc). 35 | 36 | stack(_,{_,C},Ac) -> index(C,Ac); 37 | stack(P,C,Ac) -> case om:rev(om:flat(C)) of [] -> Ac; 38 | "(" -> [open|Ac]; 39 | ")" -> [close|Ac]; 40 | [$#|A] -> inet(P,A,Ac); 41 | [X|A] when ?is_alpha(X) -> vars([X|A],Ac); 42 | [X|A] when ?is_termi(X) -> name([X|A],Ac); 43 | X -> atom(X,Ac) end. 44 | 45 | inet(P,X,Acc) -> [{remote,{P,X}}|Acc]. 46 | atom(X,Acc) -> [list_to_atom(X)|Acc]. 47 | name(X,Acc) -> [{var,{X,-1}}|Acc]. 48 | fix(X) -> case lists:flatten(lists:reverse(X)) of [] -> "1"; A -> A end. 49 | index(X,Acc) -> [{star,list_to_integer(fix(X))}|Acc]. 50 | ivar([N,I]) -> [N,I]; 51 | ivar([N]) -> [N,"0"]. 52 | vars(X,Acc) -> [Name,Index]= ivar(om:tokens(X,"@")), 53 | [{var,{list_to_atom(Name),list_to_integer(Index)}}|Acc]. 54 | -------------------------------------------------------------------------------- /src/elixir/typechecker/om_cache.erl: -------------------------------------------------------------------------------- 1 | -module(om_cache). 2 | -compile(export_all). 3 | 4 | ets(Tab, Key, []) -> ets:delete(Tab,Key); 5 | ets(Tab, Key, Value) -> ets:insert(Tab,{Key,Value}), Value. 6 | ets(Tab, Key) -> 7 | Res = ets:lookup(Tab,Key), 8 | Val = case Res of [] -> []; [Value] -> Value; Values -> Values end, 9 | case Val of [] -> []; 10 | {_,X} -> X end. 11 | 12 | % catch circular remote terms 13 | 14 | cache(X,Y,Z) -> 15 | case application:get_env(om,Y,false) of 16 | false -> application:set_env(om,Y,true), 17 | R = cache_(X,Y,Z), 18 | application:set_env(om,Y,false), 19 | R; 20 | true -> io:format("Circular: ~p",[Y]), 21 | application:set_env(om,Y,false), 22 | erlang:error(circ,list_to_binary(Y)) end. 23 | 24 | cache_(type,N,D) -> case ets(type,N) of [] -> ets(type,N,om_type:type(om_parse:ret(om:parse([],N)),D)); T -> T end; 25 | cache_(norm,N,_) -> case ets(norm,N) of [] -> ets(norm,N,om_type:norm(om_parse:ret(om:parse([],N)))); T -> T end; 26 | cache_(erased,N,D) -> case ets(erased,N) of [] -> ets(erased,N,om_erase:erase(om_parse:ret(om:parse([],N)),D)); T -> T end. 27 | -------------------------------------------------------------------------------- /src/elixir/typechecker/om_type.erl: -------------------------------------------------------------------------------- 1 | -module(om_type). 2 | -description('Type Checker'). 3 | -export([type/2, star/1, var/2, func/1, shift/3, subst/3, norm/1, eq/2, dep/3, hierarchy/2]). 4 | 5 | dep(_Arg,Out,impredicative) -> Out; 6 | dep(Arg,Out,predicative) -> erlang:max(Arg,Out). 7 | 8 | hierarchy(Arg,Out) -> dep(Arg,Out,application:get_env(om,hierarchy,impredicative)). 9 | 10 | star({star,N}) -> N; 11 | star(S) -> erlang:error({error, "*", S}). 12 | 13 | func({{<<"∀"/utf8>>,_},{_,_}}) -> true; 14 | func(T) -> erlang:error({error, <<"∀"/utf8>>, T }). 15 | 16 | var(N,B) -> var(N,B,proplists:is_defined(N,B)). 17 | var(_,_,true) -> true; 18 | var(N,B,false) -> erlang:error({error, "free var", N, proplists:get_keys(B) }). 19 | 20 | shift({var,{N,I}},N,P) when I>=P -> {var,{N,I+1}}; 21 | shift({{<<"∀"/utf8>>,{N,0}},{I,O}},N,P) -> {{<<"∀"/utf8>>,{N,0}},{shift(I,N,P),shift(O,N,P+1)}}; 22 | shift({{<<"λ"/utf8>>,{N,0}},{I,O}},N,P) -> {{<<"λ"/utf8>>,{N,0}},{shift(I,N,P),shift(O,N,P+1)}}; 23 | shift({Q,{L,R}},N,P) -> {Q,{shift(L,N,P),shift(R,N,P)}}; 24 | shift(T,_,_) -> T. 25 | 26 | 27 | subst(Term,Name,Value) -> subst(Term,Name,Value,0). 28 | subst({<<"→"/utf8>>, {I,O}},N,V,L) -> {<<"→"/utf8>>, {subst(I,N,V,L),subst(O,N,V,L)}}; 29 | subst({{<<"∀"/utf8>>,{N,0}},{I,O}},N,V,L) -> {{<<"∀"/utf8>>,{N,0}},{subst(I,N,V,L),subst(O,N,shift(V,N,0),L+1)}}; 30 | subst({{<<"∀"/utf8>>,{F,X}},{I,O}},N,V,L) -> {{<<"∀"/utf8>>,{F,X}},{subst(I,N,V,L),subst(O,N,shift(V,F,0),L)}}; 31 | subst({{<<"λ"/utf8>>,{N,0}},{I,O}},N,V,L) -> {{<<"λ"/utf8>>,{N,0}},{subst(I,N,V,L),subst(O,N,shift(V,N,0),L+1)}}; 32 | subst({{<<"λ"/utf8>>,{F,X}},{I,O}},N,V,L) -> {{<<"λ"/utf8>>,{F,X}},{subst(I,N,V,L),subst(O,N,shift(V,F,0),L)}}; 33 | subst({app, {F,A}}, N,V,L) -> {app, {subst(F,N,V,L),subst(A,N,V,L)}}; 34 | subst({var, {N,L}}, N,V,L) -> V; % index match 35 | subst({var, {N,I}}, N,_,L) when I>L -> {var, {N,I-1}}; % unshift 36 | subst(T, _,_,_) -> T. 37 | 38 | norm(none) -> none; 39 | norm(any) -> any; 40 | norm({<<"→"/utf8>>, {I,O}}) -> {{<<"∀"/utf8>>,{'_',0}},{norm(I),norm(O)}}; 41 | norm({{<<"∀"/utf8>>,{N,0}},{I,O}}) -> {{<<"∀"/utf8>>,{N,0}}, {norm(I),norm(O)}}; 42 | norm({{<<"λ"/utf8>>,{N,0}},{I,O}}) -> {{<<"λ"/utf8>>,{N,0}}, {norm(I),norm(O)}}; 43 | norm({app,{F,A}}) -> case norm(F) of 44 | {{<<"λ"/utf8>>,{N,0}},{_,O}} -> norm(subst(O,N,A)); 45 | NF -> {app,{NF,norm(A)}} end; 46 | norm({remote,N}) -> om:cache(norm,N,[]); 47 | norm(T) -> T. 48 | 49 | eq({{<<"∀"/utf8>>,{"_",0}},X},{<<"→"/utf8>>,Y}) -> eq(X,Y); 50 | eq({{<<"∀"/utf8>>,{N1,0}},{I1,O1}},{{<<"∀"/utf8>>,{N2,0}},{I2,O2}}) -> eq(I1,I2), eq(O1,subst(shift(O2,N1,0),N2,{var,{N1,0}},0)); 51 | eq({{<<"λ"/utf8>>,{N1,0}},{I1,O1}},{{<<"λ"/utf8>>,{N2,0}},{I2,O2}}) -> eq(I1,I2), eq(O1,subst(shift(O2,N1,0),N2,{var,{N1,0}},0)); 52 | eq({app,{F1,A1}},{app,{F2,A2}}) -> eq(F1,F2), eq(A1,A2); 53 | eq({star,N},{star,N}) -> true; 54 | eq({var,{N,I}},{var,{N,I}}) -> true; 55 | eq({remote,N},{remote,N}) -> true; 56 | eq(A,B) -> erlang:error({error, "==", A, B}). 57 | 58 | type({star,N},_) -> {star,N+1}; 59 | type({var,{N,I}},D) -> true = var(N,D), om:keyget(N,D,I); 60 | type({remote,N},D) -> om:cache(type,N,D); 61 | type({<<"→"/utf8>>,{I,O}},D) -> {star,hierarchy(star(type(I,D)),star(type(O,D)))}; 62 | type({{<<"∀"/utf8>>,{N,0}},{I,O}},D) -> {star,hierarchy(star(type(I,D)),star(type(O,[{N,norm(I)}|D])))}; 63 | type({{<<"λ"/utf8>>,{N,0}},{I,O}},D) -> star(type(I,D)), 64 | NI = norm(I), 65 | {{<<"∀"/utf8>>,{N,0}},{NI,type(O,[{N,NI}|D])}}; 66 | type({app,{F,A}},D) -> T = type(F,D), 67 | true = func(T), 68 | {{<<"∀"/utf8>>,{N,0}},{I,O}} = T, 69 | Q = type(A,D), 70 | true = eq(I,Q), 71 | norm(subst(O,N,A)). 72 | 73 | % 1. Substitution depends only on shift 74 | % 2. Normalization depends only on substitution 75 | % 3. The typechecker is all about the Typing, Equality and Substitution. 76 | % 4. The definitional equality is needed only for 77 | % application typechecking (argument against domain of function), 78 | % i.e. for beta-reduction. 79 | -------------------------------------------------------------------------------- /src/ocaml/henk.ml: -------------------------------------------------------------------------------- 1 | (* Henk: CoC 1988 with infinite hierarchy of predicative universes *) 2 | 3 | type term = 4 | | Var of string 5 | | Universe of int 6 | | Pi of string * term * term (* ∀ (x : a), b *) 7 | | Lam of string * term * term (* λ (x : a), b *) 8 | | App of term * term 9 | 10 | let rec string_of_term = function 11 | | Var x -> x 12 | | Universe u -> "U_" ^ string_of_int u 13 | | Pi (x, a, b) -> "∀ (" ^ x ^ " : " ^ string_of_term a ^ "), " ^ string_of_term b 14 | | Lam (x, a, t) -> "λ (" ^ x ^ " : " ^ string_of_term a ^ "), " ^ string_of_term t 15 | | App (t1, t2) -> "(" ^ string_of_term t1 ^ " " ^ string_of_term t2 ^ ")" 16 | 17 | type context = (string * term) list 18 | 19 | let universe = function 20 | | Universe i -> i 21 | | _ -> raise (Failure ("Expected a universe")) 22 | 23 | let rec subst x s = function 24 | | Var y -> if x = y then s else Var y 25 | | Pi (y, a, b) when x <> y -> Pi (y, subst x s a, subst x s b) 26 | | Lam (y, a, b) when x <> y -> Lam (y, subst x s a, subst x s b) 27 | | App (f, a) -> App (subst x s f, subst x s a) 28 | | t -> t 29 | 30 | let rec lookup x = function 31 | | [] -> raise (Failure ("Unbound variable: " ^ x)) 32 | | (y, typ) :: rest -> if x = y then typ else lookup x rest 33 | 34 | let rec equal ctx t1 t2 = match t1, t2 with 35 | | Var x, Var y -> x = y 36 | | Universe i, Universe j -> i <= j 37 | | Pi (x, a, b), Pi (y, a', b') 38 | | Lam (x, a, b), Lam (y, a', b') -> equal ctx a a' && equal ((x,a) :: ctx) b (subst y (Var x) b') 39 | | Lam (x, _, b), t -> equal ctx b (App (t, Var x)) 40 | | t, Lam (x, _, b) -> equal ctx (App (t, Var x)) b 41 | | App (f, a), App (f', a') -> equal ctx f f' && equal ctx a a' 42 | | _ -> false 43 | 44 | and reduce ctx t = match t with 45 | | App (Lam (x, _, b), a) -> subst x a b 46 | | App (Pi (x, _, b), a) -> subst x a b 47 | | App (f, a) -> App (reduce ctx f, reduce ctx a) 48 | | _ -> t 49 | 50 | and normalize ctx t = 51 | let t' = reduce ctx t in 52 | if equal ctx t t' then t else normalize ctx t' 53 | 54 | and infer ctx t = let res = match t with 55 | | Var x -> lookup x ctx 56 | | Universe i -> Universe (i + 1) 57 | | Pi (x, a, b) -> Universe (max (universe (infer ctx a)) (universe (infer ((x,a)::ctx) b))) 58 | | Lam (x, a, b) -> let _ = infer ctx a in Pi (x, a, infer ((x,a)::ctx) b) 59 | | App (f, a) -> match infer ctx f with | Pi (x, _, b) -> subst x a b | t -> raise (Failure "Requires a Pi type.") 60 | in normalize ctx res 61 | 62 | (* Test Suite *) 63 | 64 | let nat_type = 65 | Pi ("Nat", Universe 0, 66 | Pi ("Succ", Pi ("n", Var "Nat", Var "Nat"), 67 | Pi ("Zero", Var "Nat", Var "Nat"))) 68 | 69 | let zero = 70 | Lam ("Nat", Universe 0, 71 | Lam ("Succ", Pi ("n", Var "Nat", Var "Nat"), 72 | Lam ("Zero", Var "Nat", Var "Zero"))) 73 | 74 | let succ = 75 | Lam ("pred", nat_type, 76 | Lam ("Nat", Universe 0, 77 | Lam ("Succ", Pi ("n", Var "Nat", Var "Nat"), 78 | Lam ("Zero", Var "Nat", 79 | App (Var "Succ", App (App (App (Var "pred", Var "Nat"), Var "Succ"), Var "Zero")))))) 80 | 81 | let list_type = 82 | Pi ("List", Universe 0, 83 | Pi ("Cons", Pi ("head", nat_type, Pi ("tail", Var "List", Var "List")), 84 | Pi ("Nil", Var "List", Var "List"))) 85 | 86 | let sum = 87 | Lam ("xs", list_type, 88 | App (App (App (Var "xs", nat_type), 89 | Lam ("head", nat_type, 90 | Lam ("tail", nat_type, 91 | Lam ("Nat", Universe 0, 92 | Lam ("Succ", Pi ("n", Var "Nat", Var "Nat"), 93 | Lam ("Zero", Var "Nat", 94 | App (App (App (Var "head", Var "Nat"), App (App (Var "tail", Var "Nat"), Var "Succ")), 95 | Var "Zero"))))))), zero)) 96 | 97 | let one = 98 | Lam ("Nat", Universe 0, 99 | Lam ("Succ", Pi ("n", Var "Nat", Var "Nat"), 100 | Lam ("Zero", Var "Nat", 101 | App (Var "Succ", Var "Zero")))) 102 | 103 | let two = 104 | Lam ("Nat", Universe 0, 105 | Lam ("Succ", Pi ("n", Var "Nat", Var "Nat"), 106 | Lam ("Zero", Var "Nat", 107 | App (Var "Succ", 108 | App (Var "Succ", Var "Zero"))))) 109 | 110 | let nil = 111 | Lam ("List", Universe 1, 112 | Lam ("Cons", Pi ("head", nat_type, Pi ("tail", Var "List", Var "List")), 113 | Lam ("Nil", Var "List", 114 | Var "Nil"))) 115 | 116 | let cons head tail = 117 | Lam ("List", Universe 1, 118 | Lam ("Cons", Pi ("head", nat_type, Pi ("tail", Var "List", Var "List")), 119 | Lam ("Nil", Var "List", App (App (Var "Cons", head), tail)))) 120 | 121 | let list_one_two = cons one (cons two nil) 122 | 123 | let rec test_equal ctx t1 t2 = 124 | let t1' = normalize ctx t1 in 125 | let t2' = normalize ctx t2 in 126 | equal ctx t1' t2' 127 | 128 | let run_type_test name term expected_type = 129 | let ctx = [] in 130 | try let inferred = infer ctx term in 131 | let norm_inferred = normalize ctx inferred in 132 | let norm_expected = normalize ctx expected_type in 133 | Printf.printf "Test %s:\n- Term: %s\n- Inferred: %s\n- Expected: %s\n- Result: %s\n\n" 134 | name 135 | (string_of_term term) 136 | (string_of_term norm_inferred) 137 | (string_of_term norm_expected) 138 | (if test_equal [] norm_inferred norm_expected then "PASS" else "FAIL") 139 | with | Failure msg -> Printf.printf "Universe Test %s: Failed with error: %s\n\n" name msg 140 | 141 | let run_equality_test ctx name (t1, t2) = 142 | let result = test_equal ctx t1 t2 in 143 | Printf.printf "Equality Test %s:\n- Term1: %s\n- Term2: %s\n- Result: %s\n\n" 144 | name 145 | (string_of_term t1) 146 | (string_of_term t2) 147 | (if result then "PASS" else "FAIL") 148 | 149 | 150 | let beta = (App (Lam ("x", Universe 0, Var "x"), Var "y"), Var "y") 151 | let eta = (Lam ("x", Universe 0, App (Var "f", Var "x")), Var "f") 152 | let eta_domain = (Lam ("x", Universe 1, App (Var "f", Var "x")), Var "f") 153 | let invalid_eta = (Lam ("x", Universe 0, Universe 0), Universe 0) 154 | let invalid_eta_v = (Lam ("x", Universe 0, Var "u"), Var "u") 155 | let eta_subtle = (Lam ("x", Universe 0, Var "u"), Var "u") 156 | let tricky_eta = (Lam ("x", Universe 0, App (Var "f", Var "u")), Var "u") 157 | let invalid_tricky = (Lam ("x", Universe 0, App (Var "id", Var "u")), Var "u") 158 | let multi_beta = (App (App (Lam ("x", Universe 0, Lam ("y", Universe 0, Var "x")), Var "u"), Var "y"), Var "u") 159 | let predicative = Pi ("x", Universe 0, Universe 0) 160 | let neutral_eta = (Lam ("x", Universe 0, App (Var "f", Var "u")), App (Var "f", Var "u")) 161 | 162 | let () = 163 | let ctx = [("s", succ);("f", Pi ("x", Universe 0, Universe 0)); ("u", Universe 0); ("y", Universe 0); ("id", Pi ("x", Universe 0, Var "x"))] in 164 | run_type_test "Nat" nat_type (Universe 1); 165 | run_type_test "Zero" zero nat_type; 166 | run_type_test "Succ" succ (Pi ("pred", nat_type, nat_type)); 167 | run_type_test "Sum" sum (Pi ("xs", list_type, nat_type)); 168 | run_equality_test ctx "Beta" beta; 169 | run_equality_test ctx "Eta" eta; 170 | run_equality_test ctx "Invalid Eta" invalid_eta; 171 | run_equality_test ctx "Invalid Eta Var" invalid_eta_v; 172 | run_equality_test ctx "Tricky Eta" tricky_eta; 173 | run_equality_test ctx "Invalid Tricky Eta" invalid_tricky; 174 | run_equality_test ctx "Multi Beta" multi_beta; 175 | run_equality_test ctx "Eta Domain" eta_domain; 176 | run_type_test "CoC with Predicative Hierarchy" predicative (Universe 1); 177 | run_equality_test ctx "Neutral Eta" neutral_eta; 178 | -------------------------------------------------------------------------------- /src/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "aut-68" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [build-dependencies] 7 | lalrpop = "0.20.2" 8 | 9 | [dependencies] 10 | lalrpop-util = { version = "0.20.2", features = ["lexer", "unicode"] } 11 | log = "0.4.22" 12 | env_logger = "0.11.3" -------------------------------------------------------------------------------- /src/rust/build.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | lalrpop::process_root().unwrap(); 3 | println!("cargo:rerun-if-changed=src/parser.lalrpop") 4 | } 5 | -------------------------------------------------------------------------------- /src/rust/src/ast.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{HashMap, HashSet}; 2 | use std::fmt::{self, write, Debug, Display}; 3 | use std::hash::Hash; 4 | 5 | use log::debug; 6 | 7 | #[derive(Debug, Clone, PartialEq, Eq)] 8 | pub enum Henk { 9 | Universe(i64), 10 | Variable(String), 11 | App(Box, Box), 12 | Lambda(String, Box, Box), 13 | Forall(String, Box, Box), 14 | } 15 | 16 | impl Henk { 17 | 18 | pub fn type_check(self) -> Result { 19 | println!("AUT-68: {}", self); 20 | self.type_check_with_context(HashMap::new()) 21 | } 22 | 23 | pub fn type_check_with_context(self, context: HashMap) -> Result { 24 | // println!("Context: {:?}", context); 25 | match self { 26 | Henk::Universe(n) => Ok(Henk::Universe(n + 1)), 27 | Henk::Forall(bound, left, right) => { Ok(Henk::Universe(0)) } 28 | Henk::Variable(v) => match context.get(&v) { Some(ty) => Ok(ty.clone()), None => Err(format!("Cannot find variable {}.", &v)), }, 29 | Henk::App(left, right) => { 30 | match left.type_check_with_context(context.clone())? { 31 | Henk::Forall(bound, ty_in, ty_out) => { 32 | let right_ty = right.clone().type_check_with_context(context.clone())?; 33 | if right_ty.clone().nf().alpha_eq(&ty_in.clone().nf()) { Ok(ty_out.subst(&bound, &right)) } 34 | else { Err(format!("Expected something of type {}, found that of type {}.", ty_in, right_ty), ) } 35 | } 36 | left_ty => { Err(format!("Expected lambda, found value of type {}.", left_ty.nf())) } 37 | } 38 | } 39 | Henk::Lambda(bound, left, right) => { 40 | let left_type = left.clone().type_check_with_context(context.clone())?; 41 | let mut new_context = context; 42 | new_context.insert(bound.clone(), *left.clone()); 43 | let right_type = right.type_check_with_context(new_context)?; 44 | Ok(Henk::Forall(bound, left, Box::new(right_type))) 45 | } 46 | } 47 | } 48 | 49 | pub fn free_vars(&self) -> HashSet<&String> { 50 | fn closure_vars<'a>(bound: &'a String, left: &'a Box, right: &'a Box) -> HashSet<&'a String> { 51 | let mut tmp = right.free_vars(); 52 | tmp.remove(bound); 53 | tmp.union(&left.free_vars()).cloned().collect() 54 | } 55 | let mut set = HashSet::new(); 56 | match *self { 57 | Henk::Universe(v) => {} 58 | Henk::Variable(ref v) => { set = HashSet::new(); set.insert(v); } 59 | Henk::App(ref left, ref right) => { set = left.free_vars().union(&right.free_vars()).cloned().collect() } 60 | Henk::Lambda(ref bound, ref left, ref right) => { closure_vars(bound, left, right); } 61 | Henk::Forall(ref bound, ref left, ref right) => { closure_vars(bound, left, right); } 62 | } 63 | set 64 | } 65 | 66 | pub fn subst(self, from: &String, to: &Henk) -> Henk { 67 | fn lambda(bound: String, left: Box, right: Box) -> Henk { Henk::Lambda(bound, left, right) } 68 | fn forall(bound: String, left: Box, right: Box) -> Henk { Henk::Forall(bound, left, right) } 69 | fn substitute_closure<'a>(from: &String, to: &Henk, bound: &'a String, left: &'a Box, right: &'a Box, 70 | fun: fn (bound: String, left: Box, right: Box) -> Henk) -> Henk { 71 | if bound == from { fun(bound.clone(),Box::new(left.clone().subst(from, to)),right.clone(),) } 72 | else { 73 | if !to.free_vars().contains(bound) { fun(bound.clone(), Box::new(left.clone().subst(from, to)), Box::new(right.clone().subst(from, to)),) } 74 | else { 75 | let mut unused: String = bound.clone(); unused.push_str("'"); 76 | loop { 77 | let used: HashSet<&String> = right.free_vars().union(&to.free_vars()).cloned().collect(); 78 | if used.contains(&unused) { unused.push_str("'") } 79 | else { 80 | return fun(unused.clone(), Box::new(left.clone().subst(bound, &Henk::Variable(unused.clone()), )), 81 | Box::new(right.clone().subst(bound, &Henk::Variable(unused)), ), ).subst(from, to); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | match self { 88 | Henk::Universe(v) => Henk::Universe(v), 89 | Henk::Variable(v) => { if v == *from { to.clone() } else { Henk::Variable(v) } } 90 | Henk::App(left, right) => { Henk::App(Box::new(left.subst(from, to)), Box::new(right.subst(from, to))) } 91 | Henk::Lambda(ref bound, ref left, ref right) => { substitute_closure(from, to, bound, left, right, lambda) } 92 | Henk::Forall(ref bound, ref left, ref right) => { substitute_closure(from, to, bound, left, right, forall) } 93 | } 94 | } 95 | 96 | pub fn nf(self) -> Henk { 97 | fn spine(leftmost: Henk, stack: &[Henk]) -> Henk { 98 | match (leftmost, stack) { 99 | (Henk::App(left, right), _) => { let mut new_stack: Vec = stack.into(); new_stack.push(*right); spine(*left, &new_stack) } 100 | (Henk::Lambda(ref from, ref l, ref r), ref stack) if stack.is_empty() => { Henk::Lambda(from.clone(), Box::new(l.clone().nf()), Box::new(r.clone().nf()), ) } 101 | (Henk::Lambda(ref from, _, ref r), ref stack) => { let mut ns: Vec = (*stack).into(); let right = ns.pop().unwrap(); spine(r.clone().subst(&from, &right), &ns) } 102 | (Henk::Forall(ref b, ref l, ref r), ref stack) => stack.iter().fold(Henk::Forall(b.clone(), Box::new(l.clone().nf()), Box::new(r.clone().nf()), ), |x, y| Henk::App(Box::new(x), Box::new(y.clone().nf()))), 103 | (leftmost, _) => stack.iter().fold(leftmost, |l, r| Henk::App(Box::new(l), Box::new(r.clone().nf())) ), 104 | } 105 | } 106 | spine(self, &[]) 107 | } 108 | 109 | pub fn alpha_eq(&self, another: &Henk) -> bool { 110 | match (self, another) { 111 | (&Henk::Universe(v1), &Henk::Universe(v2)) => v1 == v2, 112 | (&Henk::Variable(ref v1), &Henk::Variable(ref v2)) => v1 == v2, 113 | (&Henk::App(ref left1, ref right1),&Henk::App(ref left2, ref right2),) => left1.alpha_eq(&left2) && right1.alpha_eq(&right2), 114 | (&Henk::Lambda(ref b1, ref l1, ref r1), &Henk::Lambda(ref b2, ref l2, ref r2),) => { l1.alpha_eq(l2) && r1.alpha_eq(&r2.clone().subst(&b2, &Henk::Variable(b1.clone())),) } 115 | (&Henk::Forall(ref b1, ref l1, ref r1), &Henk::Forall(ref b2, ref l2, ref r2),) => { l1.alpha_eq(l2) && r1.alpha_eq(&r2.clone().subst(&b2, &Henk::Variable(b1.clone())),) } 116 | _ => false, 117 | } 118 | } 119 | } 120 | 121 | impl Display for Henk { 122 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 123 | use Henk::*; 124 | match *self { 125 | Universe(i) => write!(f, "Universe {}", i), 126 | Variable(ref str) => write!(f, "{}", str), 127 | App (ref left, ref right) => write!(f, "({} {})", left, right), 128 | Lambda(ref bound, ref left, ref right) => write!(f, "({}: {}) {}", bound, left, right), 129 | Forall(ref bound, ref left, ref right) => write!(f, "[{}: {}] {}", bound, left, right), 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/rust/src/grammar.lalrpop: -------------------------------------------------------------------------------- 1 | use crate::ast::Henk; 2 | grammar; 3 | 4 | // Copyright (c) Groupoid Infinity 2024 Henk CoC-88 5 | 6 | // AUT = U | ( V : AUT ) AUT | AUT AUT 7 | // | V | [ V : AUT ] AUT | ( AUT ) 8 | 9 | Name: String = { r"[a-zA-Z_][a-zA-Z_\d]*" => <>.to_string() }; 10 | Variable: Henk = { => Henk::Variable(n) }; 11 | Universe: Henk = { => Henk::Universe(i64::from_str_radix(&n[1..],10).unwrap()), 12 | => Henk::Universe(0) }; 13 | 14 | Lambda: Henk = { "(" ":" ")" => Henk::Lambda(v,Box::new(t),Box::new(e)) }; 15 | Forall: Henk = { "[" ":" "]" => Henk::Forall(v,Box::new(t),Box::new(e)) }; 16 | 17 | // LR(1) Parsing Scheme 18 | 19 | Expr1: Henk = { Lambda, Forall, Expr2 }; 20 | Expr2: Henk = { => Henk::App(Box::new(l),Box::new(r)), Expr3 }; 21 | Expr3: Henk = { Variable, Universe, => e }; 22 | 23 | pub Expr: Henk = { Expr1 }; 24 | -------------------------------------------------------------------------------- /src/rust/src/main.rs: -------------------------------------------------------------------------------- 1 | use lalrpop_util::lalrpop_mod; 2 | 3 | lalrpop_mod!(pub grammar); 4 | pub mod ast; 5 | fn print(s: &str) { 6 | let res = grammar::ExprParser::new().parse(s).unwrap(); 7 | println!("Term: {:?}", res); 8 | println!("Type: {:?}", res.type_check()); 9 | println!(""); 10 | } 11 | 12 | fn main() { 13 | print("(x:*) x"); 14 | print("(x:*11) x"); 15 | print("(A:*)(H:A)(T:[L:*][C:[_:A][_:L]L][N:L]L)(L:*)(C:[_:A][_:L]L)(N:L) C H (T L C N)"); 16 | print("(A: *) (Head: A) (Tail: [List: *] [Cons: [_:A] [_: List] List] [Nil: List] List) (List: *) (Cons: [_:A] [_: List] List) (Nil: List) Cons Head (Tail List Cons Nil)"); 17 | print("[Nat : *] [Succ : [_:Nat] Nat] [Zero : Nat] Nat"); 18 | print("(pred : [Nat : *] [Succ : [_ : Nat] Nat] [Zero : Nat] Nat) (Nat : *) (Succ : [_: Nat] Nat) (Zero : Nat) Succ (pred Nat Succ Zero)"); 19 | print("[Nat:*] [Succ: [_:Nat] Nat] [Zero: Nat] Nat"); 20 | print("(x: [Nat:*] [Succ: [_:Nat] Nat] [Zero: Nat] Nat) (x ([Nat:*][Succ:[_:Nat]Nat][Zero:Nat]Nat) ((pred: [Nat:*] [Succ: [_:Nat] Nat] [Zero:Nat] Nat) (Nat2:*) (Succ2:[_:Nat2] Nat2) (Zero2: Nat2) Succ2 (pred Nat2 Succ2 Zero2)))"); 21 | print("(A: *) (x: A) (y: A) [Equ: [a:A] [b:A] *] [Refl: [z: A] Equ z z] Equ x y"); 22 | print("(A: *) (x: A) (Equ: [_:A] [_:A] *) (Refl: [z: A] (Equ z z)) Refl x"); 23 | } 24 | --------------------------------------------------------------------------------