added twelf experiments

This commit is contained in:
Felix Dilke 2026-04-14 19:55:28 +01:00
parent 7364f393bd
commit f1581679ad
13 changed files with 1195 additions and 2133 deletions

View File

@ -1 +0,0 @@
/nix/store/10mznhvw5lmlnm4qk4fxkqf05zapc087-ghc-shell-for-haskell-exps-0.1.0.0-0-env

File diff suppressed because it is too large Load Diff

1
haskell-experiments/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.direnv/

View File

@ -0,0 +1,279 @@
# Peano Arithmetic in Twelf
This directory contains a formalization of Peano arithmetic and basic number theory in Twelf, including definitions, proofs of fundamental properties, and statements of advanced theorems.
## Quick Start
### Loading All Files
Using the Twelf server interactively:
```bash
twelf-server
```
Then at the Twelf prompt:
```
loadFile nat.elf
loadFile add.elf
loadFile mult.elf
loadFile exp.elf
loadFile order.elf
loadFile div.elf
loadFile prime.elf
loadFile theorems.elf
```
Or load all files at once with a script:
```bash
twelf-server <<'EOF'
loadFile nat.elf
loadFile add.elf
loadFile mult.elf
loadFile exp.elf
loadFile order.elf
loadFile div.elf
loadFile prime.elf
loadFile theorems.elf
EOF
```
### Running Computations
Once files are loaded, you can compute with `%solve`:
```
%solve _ : add (s (s z)) (s (s (s z))) N. -- 2 + 3 = ?
%solve _ : mult (s (s z)) (s (s (s z))) N. -- 2 * 3 = ?
%solve _ : exp (s (s z)) (s (s (s z))) N. -- 2^3 = ?
%solve _ : factorial (s (s (s (s z)))) N. -- 4! = ?
```
## File Structure
Files must be loaded in order due to dependencies:
| File | Description | Dependencies |
|------|-------------|--------------|
| `nat.elf` | Natural numbers (Peano axioms), equality | none |
| `add.elf` | Addition, commutativity, associativity | nat.elf |
| `mult.elf` | Multiplication, basic properties | nat.elf, add.elf |
| `exp.elf` | Exponentiation | nat.elf, add.elf, mult.elf |
| `order.elf` | Less-than, less-equal, trichotomy | nat.elf |
| `div.elf` | Divisibility, GCD, division with remainder | nat.elf, add.elf, mult.elf, order.elf |
| `prime.elf` | Primes, factorial, prime factorization | all above |
| `theorems.elf` | Computational tests, theorem summary | all above |
| `sources.cfg` | Configuration file for batch loading | - |
## Definitions
### Natural Numbers (`nat.elf`)
```
nat : type.
z : nat. -- zero
s : nat -> nat. -- successor
```
Numbers: `z` = 0, `s z` = 1, `s (s z)` = 2, etc.
Abbreviations: `one`, `two`, `three`, `four`, `five`
### Addition (`add.elf`)
```
add : nat -> nat -> nat -> type.
add/z : add z N N. -- 0 + N = N
add/s : add (s M) N (s P) <- add M N P. -- (1+M) + N = 1 + (M + N)
```
### Multiplication (`mult.elf`)
```
mult : nat -> nat -> nat -> type.
mult/z : mult z N z. -- 0 * N = 0
mult/s : mult (s M) N R <- mult M N P <- add N P R. -- (1+M) * N = N + M*N
```
### Exponentiation (`exp.elf`)
```
exp : nat -> nat -> nat -> type.
exp/z : exp N z (s z). -- N^0 = 1
exp/s : exp N (s M) R <- exp N M P <- mult N P R. -- N^(1+M) = N * N^M
```
### Ordering (`order.elf`)
```
lt : nat -> nat -> type. -- less than
lt/z : lt z (s N). -- 0 < 1+N
lt/s : lt (s M) (s N) <- lt M N. -- M < N implies 1+M < 1+N
le : nat -> nat -> type. -- less than or equal
le/z : le z N. -- 0 <= N
le/s : le (s M) (s N) <- le M N. -- M <= N implies 1+M <= 1+N
```
### Divisibility (`div.elf`)
```
divides : nat -> nat -> type.
divides/intro : divides D N <- mult D K N. -- D | N iff N = D * K for some K
```
### Primes (`prime.elf`)
```
prime : nat -> type.
prime/two : prime (s (s z)). -- 2 is prime
prime/three : prime (s (s (s z))). -- 3 is prime
prime/five : prime (s (s (s (s (s z))))). -- 5 is prime
prime/seven : prime (s (s (s (s (s (s (s z))))))). -- 7 is prime
```
## Verified Theorems
These theorems have complete proofs checked by Twelf's totality checker (`%total`):
### Addition Properties
- **add-total**: Addition always produces a result
- **add-comm**: M + N = N + M (commutativity)
- **add-assoc**: (A + B) + C = A + (B + C) (associativity)
- **add-right-z**: N + 0 = N (right identity)
- **add-right-s**: M + (S N) = S(M + N)
- **add-cancel-left**: A + B = A + C implies B = C (left cancellation)
- **add-func**: Addition is deterministic
### Multiplication Properties
- **mult-total**: Multiplication always produces a result
- **mult-right-z**: N * 0 = 0
- **mult-left-one**: 1 * N = N
- **mult-right-one**: N * 1 = N
### Exponentiation Properties
- **exp-total**: Exponentiation always produces a result
- **exp-one**: N^1 = N
- **exp-base-one**: 1^N = 1
- **exp-base-zero**: 0^(S N) = 0
### Order Properties
- **le-refl**: N <= N (reflexivity)
- **le-trans**: A <= B and B <= C implies A <= C (transitivity)
- **le-antisym**: A <= B and B <= A implies A = B (antisymmetry)
- **lt-trans**: A < B and B < C implies A < C
- **trichotomy-total**: For all M, N: exactly one of M < N, M = N, M > N
### Divisibility Properties
- **one-divides**: 1 | N for all N
- **divides-zero**: N | 0 for all N
- **divides-refl**: N | N for all N
### Factorial
- **factorial-total**: Factorial always produces a result
## Theorems Stated But Not Fully Proven
The following theorems are stated with proof sketches but require additional infrastructure:
### Multiplication Commutativity
- **mult-comm**: M * N = N * M
- Requires the `mult-right-s` lemma (M * (S N) = M + M * N)
### Distributivity
- **mult-distrib-left**: A * (B + C) = A*B + A*C
- Provable by induction on A
### Multiplication Associativity
- **mult-assoc**: (A * B) * C = A * (B * C)
- Requires distributivity
### Number Theory
- **has-prime-divisor-total**: Every N > 1 has a prime divisor
- **infinitude-of-primes**: For any prime P, there exists a prime Q > P
- **euclid-lemma**: If P is prime and P | AB, then P | A or P | B
- **fundamental-theorem-existence**: Every N > 1 has a prime factorization
- **fundamental-theorem-uniqueness**: Prime factorization is unique up to ordering
## How Twelf Proofs Work
Twelf uses the "judgments as types" methodology. A theorem is represented as a type family, and its proof is a term of that type.
### Example: Addition Commutativity
```
add-comm : add M N P -> add N M P -> type.
%mode add-comm +D1 -D2.
```
This declares that `add-comm` takes a derivation `D1` showing `add M N P` and produces a derivation `D2` showing `add N M P`.
The `%mode` declaration specifies that `D1` is an input (+) and `D2` is an output (-).
### Totality Checking
```
%worlds () (add-comm _ _).
%total D (add-comm D _).
```
- `%worlds ()` declares the proof works in the empty world (no hypothetical assumptions)
- `%total D (add-comm D _)` verifies the proof terminates and covers all cases, with recursion on `D`
## Understanding the Output
When you run `%solve`, Twelf shows the derivation tree:
```
%solve _ : add two three N.
```
Output:
```
add (s (s z)) (s (s (s z))) (s (s (s (s (s z)))))
= add/s (add/s add/z).
```
This shows:
- The result: 2 + 3 = 5
- The proof: apply `add/s` twice, then `add/z`
## Extending This Formalization
### Adding New Theorems
1. Identify what lemmas are needed
2. Define the theorem type with appropriate mode
3. Write cases for each constructor
4. Add `%worlds` and `%total` declarations
### Common Patterns
**Induction on a natural number:**
```
my-theorem : {N:nat} ... -> type.
%mode my-theorem +N ...
my-theorem/z : my-theorem z ...
my-theorem/s : my-theorem (s N) ... <- my-theorem N ...
%worlds () (my-theorem _ _).
%total N (my-theorem N _).
```
**Induction on a derivation:**
```
my-theorem : some-relation A B -> another-relation A B -> type.
%mode my-theorem +D1 -D2.
my-theorem/case1 : my-theorem some-relation/c1 another-relation/c1.
my-theorem/case2 : my-theorem (some-relation/c2 D) (another-relation/c2 D')
<- my-theorem D D'.
%worlds () (my-theorem _ _).
%total D (my-theorem D _).
```
## References
- [Twelf Wiki](http://twelf.org/wiki/Main_Page)
- [Twelf User's Guide](http://twelf.org/wiki/User%27s_Guide)
- Harper & Licata, "Mechanizing Metatheory in a Logical Framework"

View File

@ -0,0 +1,122 @@
%% add.elf - Addition on Natural Numbers
%%
%% Addition is defined recursively:
%% 0 + N = N
%% (S M) + N = S (M + N)
add : nat -> nat -> nat -> type.
%mode add +N +M -R.
add/z : add z N N.
add/s : add (s M) N (s P)
<- add M N P.
%% Addition is total (always produces a result)
add-total : {M:nat} {N:nat} add M N P -> type.
%mode add-total +M +N -D.
add-total/z : add-total z N add/z.
add-total/s : add-total (s M) N (add/s D)
<- add-total M N D.
%worlds () (add-total _ _ _).
%total M (add-total M _ _).
%% ============================================================
%% LEMMAS FOR COMMUTATIVITY
%% ============================================================
%% Right identity: N + 0 = N
add-right-z : {N:nat} add N z N -> type.
%mode add-right-z +N -D.
add-right-z/z : add-right-z z add/z.
add-right-z/s : add-right-z (s N) (add/s D)
<- add-right-z N D.
%worlds () (add-right-z _ _).
%total N (add-right-z N _).
%% Right successor: M + (S N) = S (M + N)
%% If add M N P, then add M (s N) (s P)
add-right-s : add M N P -> add M (s N) (s P) -> type.
%mode add-right-s +D1 -D2.
add-right-s/z : add-right-s add/z add/z.
add-right-s/s : add-right-s (add/s D1) (add/s D2)
<- add-right-s D1 D2.
%worlds () (add-right-s _ _).
%total D (add-right-s D _).
%% ============================================================
%% COMMUTATIVITY OF ADDITION
%% ============================================================
%% Main theorem: M + N = N + M
%% If add M N P, then add N M P
add-comm : add M N P -> add N M P -> type.
%mode add-comm +D1 -D2.
add-comm/z : add-comm add/z D
<- add-right-z _ D.
add-comm/s : add-comm (add/s D1) D3
<- add-comm D1 D2
<- add-right-s D2 D3.
%worlds () (add-comm _ _).
%total D (add-comm D _).
%% ============================================================
%% ASSOCIATIVITY OF ADDITION
%% ============================================================
%% Associativity using output factoring
%% We prove: forall A B C AB ABC. add A B AB -> add AB C ABC ->
%% exists BC. add B C BC /\ add A BC ABC
%%
%% This formulation allows Twelf to find BC as an output.
add-assoc : add A B AB -> add AB C ABC -> add B C BC -> add A BC ABC -> type.
%mode add-assoc +D1 +D2 -D3 -D4.
add-assoc/z : add-assoc add/z D D add/z.
add-assoc/s : add-assoc (add/s D1) (add/s D2) D3 (add/s D4)
<- add-assoc D1 D2 D3 D4.
%worlds () (add-assoc _ _ _ _).
%total D (add-assoc D _ _ _).
%% ============================================================
%% CANCELLATION LAWS
%% ============================================================
%% Left cancellation: if A + B = A + C then B = C
add-cancel-left : add A B R -> add A C R -> nat-eq B C -> type.
%mode add-cancel-left +D1 +D2 -E.
add-cancel-left/z : add-cancel-left add/z add/z nat-eq/refl.
add-cancel-left/s : add-cancel-left (add/s D1) (add/s D2) E
<- add-cancel-left D1 D2 E.
%worlds () (add-cancel-left _ _ _).
%total D (add-cancel-left D _ _).
%% ============================================================
%% FUNCTIONALITY (Determinism)
%% ============================================================
%% Helper: equality lifts through successor
nat-eq-s : nat-eq M N -> nat-eq (s M) (s N) -> type.
%mode nat-eq-s +E1 -E2.
nat-eq-s/refl : nat-eq-s nat-eq/refl nat-eq/refl.
%worlds () (nat-eq-s _ _).
%total {} (nat-eq-s _ _).
%% Addition is functional: if add M N P and add M N Q then P = Q
add-func : add M N P -> add M N Q -> nat-eq P Q -> type.
%mode add-func +D1 +D2 -E.
add-func/z : add-func add/z add/z nat-eq/refl.
add-func/s : add-func (add/s D1) (add/s D2) E'
<- add-func D1 D2 E
<- nat-eq-s E E'.
%worlds () (add-func _ _ _).
%total D (add-func D _ _).

View File

@ -0,0 +1,103 @@
%% div.elf - Divisibility on Natural Numbers
%%
%% We define:
%% - divides D N: D divides N (D | N), meaning N = D * K for some K
%% ============================================================
%% DIVISIBILITY
%% ============================================================
%% D divides N if there exists K such that D * K = N
divides : nat -> nat -> type.
divides/intro : divides D N
<- mult D K N.
%% ============================================================
%% BASIC DIVISIBILITY FACTS
%% ============================================================
%% 1 divides everything: 1 | N
one-divides : {N:nat} divides (s z) N -> type.
%mode one-divides +N -D.
one-divides/base : one-divides N (divides/intro Dmult)
<- mult-left-one N Dmult.
%worlds () (one-divides _ _).
%total {} (one-divides _ _).
%% Everything divides 0: N | 0
divides-zero : {N:nat} divides N z -> type.
%mode divides-zero +N -D.
%% For any N, mult N z z holds (mult/z pattern doesn't work here)
%% We need to use mult-right-z
divides-zero/base : divides-zero N (divides/intro D)
<- mult-right-z N D.
%worlds () (divides-zero _ _).
%total {} (divides-zero _ _).
%% N divides itself: N | N (reflexivity)
divides-refl : {N:nat} divides N N -> type.
%mode divides-refl +N -D.
divides-refl/base : divides-refl N (divides/intro Dmult)
<- mult-right-one N Dmult.
%worlds () (divides-refl _ _).
%total {} (divides-refl _ _).
%% ============================================================
%% DIVISION WITH REMAINDER (EUCLIDEAN DIVISION)
%% ============================================================
%% For D > 0 and any N, there exist unique Q, R with N = D*Q + R and R < D
%% We represent this as: divmod N D Q R means N = D*Q + R and R < D
divmod : nat -> nat -> nat -> nat -> type.
%% Base case: if N < D, then Q = 0, R = N
divmod/lt : divmod N D z N
<- lt N D.
%% Recursive case: if N >= D, we need to compute (N - D) div D
%% This requires a subtraction relation, which we'll define
%% Subtraction: sub A B C means A = B + C (so C = A - B when B <= A)
sub : nat -> nat -> nat -> type.
sub/z : sub N z N.
sub/s : sub (s A) (s B) C
<- sub A B C.
%% Now we can define divmod for the recursive case
divmod/ge : divmod N D (s Q) R
<- le D N %% D <= N
<- sub N D M %% M = N - D
<- divmod M D Q R. %% M = D*Q + R, so N = D*(Q+1) + R
%% ============================================================
%% GCD (Greatest Common Divisor)
%% ============================================================
%% Euclidean algorithm: gcd(A, 0) = A, gcd(A, B) = gcd(B, A mod B)
%% We define gcd using the Euclidean algorithm
%% gcd A B G means G is the GCD of A and B
gcd : nat -> nat -> nat -> type.
gcd/z : gcd A z A. %% gcd(A, 0) = A
gcd/s : gcd A (s B) G
<- divmod A (s B) Q R %% A = (s B)*Q + R with R < s B
<- gcd (s B) R G. %% G = gcd(s B, R)
%% ============================================================
%% COPRIMALITY
%% ============================================================
%% A and B are coprime if gcd(A, B) = 1
coprime : nat -> nat -> type.
coprime/intro : coprime A B
<- gcd A B (s z).

View File

@ -0,0 +1,114 @@
%% exp.elf - Exponentiation on Natural Numbers
%%
%% Exponentiation is defined recursively:
%% N^0 = 1
%% N^(S M) = N * N^M
exp : nat -> nat -> nat -> type.
%mode exp +Base +Exponent -Result.
exp/z : exp N z (s z). %% N^0 = 1
exp/s : exp N (s M) R
<- exp N M P %% P = N^M
<- mult N P R. %% R = N * P = N * N^M = N^(M+1)
%% Exponentiation is total
exp-total : {N:nat} {M:nat} exp N M P -> type.
%mode exp-total +N +M -D.
exp-total/z : exp-total N z exp/z.
exp-total/s : exp-total N (s M) (exp/s Dmult Dexp)
<- exp-total N M Dexp
<- mult-total N _ Dmult.
%worlds () (exp-total _ _ _).
%total M (exp-total _ M _).
%% ============================================================
%% BASIC EXPONENTIATION PROPERTIES
%% ============================================================
%% N^1 = N
exp-one : {N:nat} exp N (s z) N -> type.
%mode exp-one +N -D.
exp-one/base : exp-one N (exp/s Dmult exp/z)
<- mult-right-one N Dmult.
%worlds () (exp-one _ _).
%total {} (exp-one _ _).
%% 1^N = 1
exp-base-one : {N:nat} exp (s z) N (s z) -> type.
%mode exp-base-one +N -D.
exp-base-one/z : exp-base-one z exp/z.
exp-base-one/s : exp-base-one (s N) (exp/s Dmult Dexp)
<- exp-base-one N Dexp
<- mult-left-one (s z) Dmult.
%worlds () (exp-base-one _ _).
%total N (exp-base-one N _).
%% 0^(S N) = 0 (0 to any positive power is 0)
exp-base-zero : {N:nat} exp z (s N) z -> type.
%mode exp-base-zero +N -D.
exp-base-zero/z : exp-base-zero z (exp/s mult/z exp/z).
exp-base-zero/s : exp-base-zero (s N) (exp/s mult/z Dexp)
<- exp-base-zero N Dexp.
%worlds () (exp-base-zero _ _).
%total N (exp-base-zero N _).
%% ============================================================
%% EXPONENT LAWS
%% ============================================================
%% Law 1: N^(A+B) = N^A * N^B
%% exp-add : exp N A PA -> exp N B PB -> add A B AB ->
%% mult PA PB PAB -> exp N AB PAB -> type.
%% We'll prove this by induction on B
exp-add : {N:nat} {A:nat} {B:nat} {PA:nat} {PB:nat} {AB:nat} {PAB:nat}
exp N A PA -> exp N B PB -> add A B AB ->
mult PA PB PAB -> exp N AB PAB -> type.
%mode exp-add +N +A +B +PA +PB +AB +PAB +Da +Db +Dadd +Dmult -Dab.
%% Base case: B = 0
%% N^(A+0) = N^A = N^A * 1 = N^A * N^0
exp-add/z : exp-add N A z PA (s z) A PA
Da exp/z Dadd Dmult Da
<- add-right-z A Dadd'
%% Need: Dadd : add A z A
%% Have: Dadd' : add A z A from add-right-z
%% Need: Dmult : mult PA (s z) PA
<- mult-right-one PA Dmult'.
%% The full proof requires showing the inductive step which involves
%% associativity of multiplication. We state it here for completeness.
%% Law 2: (N^A)^B = N^(A*B)
%% This is the power of a power rule
%% Law 3: (M*N)^A = M^A * N^A
%% This is the power of a product rule
%% These proofs follow similar patterns but require the multiplication
%% lemmas we've developed.
%% ============================================================
%% USEFUL COMPUTATIONS
%% ============================================================
%% Let's verify some concrete exponentiations
%% 2^2 = 4
%% 2^3 = 8
%% We can use Twelf's %solve to compute these:
%% %solve D22 : exp two two R.
%% Should give R = four
%% %solve D23 : exp two three R.
%% Should give R = s (s (s (s (s (s (s (s z))))))) = 8

View File

@ -0,0 +1,106 @@
%% mult.elf - Multiplication on Natural Numbers
%%
%% Multiplication is defined recursively:
%% 0 * N = 0
%% (S M) * N = N + (M * N)
mult : nat -> nat -> nat -> type.
%mode mult +M +N -R.
mult/z : mult z N z.
mult/s : mult (s M) N R
<- mult M N P
<- add N P R.
%% Multiplication is total
mult-total : {M:nat} {N:nat} mult M N P -> type.
%mode mult-total +M +N -D.
mult-total/z : mult-total z N mult/z.
mult-total/s : mult-total (s M) N (mult/s Dadd Dmult)
<- mult-total M N Dmult
<- add-total N _ Dadd.
%worlds () (mult-total _ _ _).
%total M (mult-total M _ _).
%% ============================================================
%% BASIC MULTIPLICATION LEMMAS
%% ============================================================
%% Right zero: N * 0 = 0
mult-right-z : {N:nat} mult N z z -> type.
%mode mult-right-z +N -D.
mult-right-z/z : mult-right-z z mult/z.
mult-right-z/s : mult-right-z (s N) (mult/s add/z D)
<- mult-right-z N D.
%worlds () (mult-right-z _ _).
%total N (mult-right-z N _).
%% Left identity: 1 * N = N
mult-left-one : {N:nat} mult (s z) N N -> type.
%mode mult-left-one +N -D.
mult-left-one/base : mult-left-one N (mult/s Dadd mult/z)
<- add-right-z N Dadd.
%worlds () (mult-left-one _ _).
%total {} (mult-left-one _ _).
%% Right identity: N * 1 = N
mult-right-one : {N:nat} mult N (s z) N -> type.
%mode mult-right-one +N -D.
mult-right-one/z : mult-right-one z mult/z.
mult-right-one/s : mult-right-one (s N) (mult/s (add/s add/z) D)
<- mult-right-one N D.
%worlds () (mult-right-one _ _).
%total N (mult-right-one N _).
%% ============================================================
%% COMMUTATIVITY OF MULTIPLICATION
%% ============================================================
%% Commutativity requires the lemma: M * (S N) = M + M * N
%% This is subtle because our definition gives: (S M) * N = N + M * N
%%
%% The full proof requires careful organization of lemmas involving
%% associativity and commutativity of addition. We state the theorem:
%%
%% mult-comm : mult M N P -> mult N M P -> type.
%%
%% The proof structure would be:
%% 1. Base case: 0 * N = 0 = N * 0 (uses mult-right-z)
%% 2. Step case: (S M) * N = N + M*N, and by IH M*N = N*M
%% Need N * (S M) = N + N*M = N + M*N (by IH), which matches.
%% But N * (S M) by definition requires mult-right-s lemma.
%%
%% The mult-right-s lemma (M * (S N) = M + M*N) proof requires
%% showing that addition commutes/associates appropriately through
%% the recursive structure.
%% For computational verification, we can test specific cases:
%% mult 2 3 should equal mult 3 2, both giving 6.
%% ============================================================
%% NOTES ON ADVANCED PROPERTIES
%% ============================================================
%% Associativity: (A * B) * C = A * (B * C)
%% Requires: Left distributivity A * (B + C) = A*B + A*C
%% Left Distributivity: A * (B + C) = A*B + A*C
%% Proof by induction on A:
%% - Base: 0 * (B + C) = 0 = 0 + 0 = 0*B + 0*C
%% - Step: (S A) * (B + C) = (B + C) + A*(B+C)
%% By IH: = (B + C) + (A*B + A*C)
%% By assoc: = B + (C + A*B) + A*C
%% By comm: = B + (A*B + C) + A*C
%% By assoc: = (B + A*B) + (C + A*C)
%% = (S A)*B + (S A)*C
%% Right Distributivity: (A + B) * C = A*C + B*C
%% Follows from left distributivity and commutativity

View File

@ -0,0 +1,47 @@
%% nat.elf - Natural Numbers (Peano Axioms)
%%
%% We define the natural numbers inductively:
%% - z (zero) is a natural number
%% - s N (successor of N) is a natural number if N is
%%
%% This gives us: z, s z, s (s z), s (s (s z)), ...
%% = 0, 1, 2, 3, ...
nat : type.
z : nat.
s : nat -> nat.
%% Equality on natural numbers (identity)
nat-eq : nat -> nat -> type.
nat-eq/refl : nat-eq N N.
%% Inequality (not equal)
nat-neq : nat -> nat -> type.
nat-neq/zs : nat-neq z (s _).
nat-neq/sz : nat-neq (s _) z.
nat-neq/ss : nat-neq (s N) (s M) <- nat-neq N M.
%% Some convenient abbreviations for small numbers
%abbrev one = s z.
%abbrev two = s (s z).
%abbrev three = s (s (s z)).
%abbrev four = s (s (s (s z))).
%abbrev five = s (s (s (s (s z)))).
%% Predecessor (partial - undefined for zero)
pred : nat -> nat -> type.
pred/s : pred (s N) N.
%% Case analysis principle: every nat is either z or s of something
nat-case : nat -> type.
nat-case/z : nat-case z.
nat-case/s : nat-case (s N).
%% Every natural number has a case
nat-case-total : {N:nat} nat-case N -> type.
%mode nat-case-total +N -C.
nat-case-total/z : nat-case-total z nat-case/z.
nat-case-total/s : nat-case-total (s N) nat-case/s.
%worlds () (nat-case-total _ _).
%total N (nat-case-total N _).

View File

@ -0,0 +1,165 @@
%% order.elf - Ordering Relations on Natural Numbers
%%
%% We define:
%% - lt (less than): M < N
%% - le (less than or equal): M <= N
%% ============================================================
%% LESS THAN
%% ============================================================
%% M < N is defined inductively:
%% - 0 < S(N) for any N
%% - S(M) < S(N) if M < N
lt : nat -> nat -> type.
lt/z : lt z (s N). %% 0 < S(N) for any N
lt/s : lt (s M) (s N) %% S(M) < S(N) if M < N
<- lt M N.
%% ============================================================
%% LESS THAN OR EQUAL
%% ============================================================
le : nat -> nat -> type.
le/z : le z N. %% 0 <= N for any N
le/s : le (s M) (s N) %% S(M) <= S(N) if M <= N
<- le M N.
%% le is reflexive
le-refl : {N:nat} le N N -> type.
%mode le-refl +N -D.
le-refl/z : le-refl z le/z.
le-refl/s : le-refl (s N) (le/s D)
<- le-refl N D.
%worlds () (le-refl _ _).
%total N (le-refl N _).
%% le is transitive
le-trans : le A B -> le B C -> le A C -> type.
%mode le-trans +D1 +D2 -D3.
le-trans/z : le-trans le/z _ le/z.
le-trans/s : le-trans (le/s D1) (le/s D2) (le/s D3)
<- le-trans D1 D2 D3.
%worlds () (le-trans _ _ _).
%total D (le-trans D _ _).
%% Helper: equality lifts through successor
nat-eq-s' : nat-eq M N -> nat-eq (s M) (s N) -> type.
%mode nat-eq-s' +E1 -E2.
nat-eq-s'/refl : nat-eq-s' nat-eq/refl nat-eq/refl.
%worlds () (nat-eq-s' _ _).
%total {} (nat-eq-s' _ _).
%% le is antisymmetric: if M <= N and N <= M then M = N
le-antisym : le M N -> le N M -> nat-eq M N -> type.
%mode le-antisym +D1 +D2 -E.
le-antisym/z : le-antisym le/z le/z nat-eq/refl.
le-antisym/s : le-antisym (le/s D1) (le/s D2) E
<- le-antisym D1 D2 E'
<- nat-eq-s' E' E.
%worlds () (le-antisym _ _ _).
%total D (le-antisym D _ _).
%% ============================================================
%% RELATIONSHIPS BETWEEN lt AND le
%% ============================================================
%% lt implies le: if M < N then M <= N
lt-to-le : lt M N -> le M N -> type.
%mode lt-to-le +D1 -D2.
lt-to-le/z : lt-to-le lt/z le/z.
lt-to-le/s : lt-to-le (lt/s D1) (le/s D2)
<- lt-to-le D1 D2.
%worlds () (lt-to-le _ _).
%total D (lt-to-le D _).
%% M < S(N) iff M <= N
lt-s-to-le : lt M (s N) -> le M N -> type.
%mode lt-s-to-le +D1 -D2.
lt-s-to-le/z : lt-s-to-le lt/z le/z.
lt-s-to-le/s : lt-s-to-le (lt/s D1) (le/s D2)
<- lt-s-to-le D1 D2.
%worlds () (lt-s-to-le _ _).
%total D (lt-s-to-le D _).
le-to-lt-s : le M N -> lt M (s N) -> type.
%mode le-to-lt-s +D1 -D2.
le-to-lt-s/z : le-to-lt-s le/z lt/z.
le-to-lt-s/s : le-to-lt-s (le/s D1) (lt/s D2)
<- le-to-lt-s D1 D2.
%worlds () (le-to-lt-s _ _).
%total D (le-to-lt-s D _).
%% ============================================================
%% TRICHOTOMY
%% ============================================================
%% For any M, N: exactly one of M < N, M = N, M > N holds
trichotomy : nat -> nat -> type.
trichotomy/lt : trichotomy M N <- lt M N.
trichotomy/eq : trichotomy M N <- nat-eq M N.
trichotomy/gt : trichotomy M N <- lt N M.
%% Helper to lift trichotomy through successor
trichotomy-lift : trichotomy M N -> trichotomy (s M) (s N) -> type.
%mode trichotomy-lift +T1 -T2.
trichotomy-lift/lt : trichotomy-lift (trichotomy/lt D) (trichotomy/lt (lt/s D)).
trichotomy-lift/eq : trichotomy-lift (trichotomy/eq nat-eq/refl)
(trichotomy/eq nat-eq/refl).
trichotomy-lift/gt : trichotomy-lift (trichotomy/gt D) (trichotomy/gt (lt/s D)).
%worlds () (trichotomy-lift _ _).
%total {} (trichotomy-lift _ _).
trichotomy-total : {M:nat} {N:nat} trichotomy M N -> type.
%mode trichotomy-total +M +N -T.
trichotomy-total/zz : trichotomy-total z z (trichotomy/eq nat-eq/refl).
trichotomy-total/zs : trichotomy-total z (s N) (trichotomy/lt lt/z).
trichotomy-total/sz : trichotomy-total (s M) z (trichotomy/gt lt/z).
trichotomy-total/ss : trichotomy-total (s M) (s N) T'
<- trichotomy-total M N T
<- trichotomy-lift T T'.
%worlds () (trichotomy-total _ _ _).
%total M (trichotomy-total M _ _).
%% ============================================================
%% BASIC LEMMAS
%% ============================================================
%% lt is transitive
lt-trans : lt A B -> lt B C -> lt A C -> type.
%mode lt-trans +D1 +D2 -D3.
lt-trans/zs : lt-trans lt/z (lt/s _) lt/z.
lt-trans/ss : lt-trans (lt/s D1) (lt/s D2) (lt/s D3)
<- lt-trans D1 D2 D3.
%worlds () (lt-trans _ _ _).
%total D (lt-trans D _ _).
%% lt is irreflexive: not (N < N)
%% We express this as: lt N N implies any conclusion
%% (In Twelf, we can't directly state "not", but we can show
%% there's no derivation of lt N N)
%% N is not less than zero - this is witnessed by the fact that
%% there is no constructor for lt that produces lt _ z.
%% We cannot state "lt N z -> void" directly in Twelf since void
%% isn't a built-in. Instead, the absence of matching cases proves it.

View File

@ -0,0 +1,120 @@
%% prime.elf - Prime Numbers and Related Theorems
%%
%% A prime number P > 1 is a natural number whose only divisors are 1 and P.
%% ============================================================
%% DEFINITION OF PRIME
%% ============================================================
%% A number is "greater than 1"
gt-one : nat -> type.
gt-one/intro : gt-one (s (s N)). %% N >= 2 means N > 1
%% A number is composite if it has a non-trivial divisor
%% composite N means: exists D such that 1 < D < N and D | N
composite : nat -> type.
composite/intro : composite N
<- gt-one D %% D > 1
<- lt D N %% D < N
<- divides D N. %% D | N
%% A number is prime if P > 1 and not composite
%% We'll define small primes directly and provide a general characterization
prime : nat -> type.
prime/two : prime (s (s z)). %% 2 is prime
prime/three : prime (s (s (s z))). %% 3 is prime
prime/five : prime (s (s (s (s (s z))))). %% 5 is prime
prime/seven : prime (s (s (s (s (s (s (s z))))))). %% 7 is prime
%% ============================================================
%% FACTORIAL
%% ============================================================
factorial : nat -> nat -> type.
%mode factorial +N -R.
factorial/z : factorial z (s z). %% 0! = 1
factorial/s : factorial (s N) R
<- factorial N F %% F = N!
<- mult (s N) F R. %% R = (N+1) * N! = (N+1)!
factorial-total : {N:nat} factorial N F -> type.
%mode factorial-total +N -D.
factorial-total/z : factorial-total z factorial/z.
factorial-total/s : factorial-total (s N) (factorial/s Dmult Dfact)
<- factorial-total N Dfact
<- mult-total (s N) _ Dmult.
%worlds () (factorial-total _ _).
%total N (factorial-total N _).
%% ============================================================
%% PRIME FACTORIZATION (Representation)
%% ============================================================
%% A list of natural numbers
nat-list : type.
nil : nat-list.
cons : nat -> nat-list -> nat-list.
%% Product of a list
list-product : nat-list -> nat -> type.
%mode list-product +L -P.
list-product/nil : list-product nil (s z).
list-product/cons : list-product (cons N L) P
<- list-product L Q
<- mult N Q P.
%% All elements of a list are prime
all-prime : nat-list -> type.
all-prime/nil : all-prime nil.
all-prime/cons : all-prime (cons P L)
<- prime P
<- all-prime L.
%% A prime factorization of N is a list L where:
%% 1. All elements of L are prime
%% 2. The product of L equals N
prime-factorization : nat -> nat-list -> type.
prime-factorization/intro : prime-factorization N L
<- all-prime L
<- list-product L N.
%% ============================================================
%% THEOREMS (Statements)
%% ============================================================
%% Theorem: Every N > 1 has a prime divisor
%% has-prime-divisor N P means P is prime and P | N
has-prime-divisor : nat -> nat -> type.
has-prime-divisor/intro : has-prime-divisor N P
<- prime P
<- divides P N.
%% Theorem (Euclid): There are infinitely many primes
%% For any N, there exists a prime P > N
%% This is expressed as: for any list of primes, there's a prime not in the list
%% Theorem (Fundamental Theorem of Arithmetic):
%% 1. Existence: Every N > 1 has a prime factorization
%% 2. Uniqueness: The factorization is unique up to ordering
%% Euclid's Lemma: If P is prime and P | AB, then P | A or P | B
%% This is key to proving uniqueness of factorization
%% ============================================================
%% COMPUTATIONAL EXAMPLES
%% ============================================================
%% These can be verified using %solve:
%% 2! = 2
%% 3! = 6
%% 4! = 24
%% 5! = 120
%% Example factorizations:
%% 6 = 2 * 3 = cons 2 (cons 3 nil)
%% 12 = 2 * 2 * 3 = cons 2 (cons 2 (cons 3 nil))

View File

@ -0,0 +1,15 @@
%% sources.cfg - Twelf configuration file for Peano Arithmetic
%%
%% Load this file with: twelf-server < sources.cfg
%% Or in Twelf server: Config.read "sources.cfg"
%%
%% The files must be loaded in dependency order.
nat.elf
add.elf
mult.elf
exp.elf
order.elf
div.elf
prime.elf
theorems.elf

View File

@ -0,0 +1,123 @@
%% theorems.elf - Verified Computations and Theorem Summary
%%
%% This file demonstrates computational verification using %solve
%% and summarizes the proof status of all theorems.
%% ============================================================
%% COMPUTATIONAL VERIFICATIONS
%% ============================================================
%% Basic arithmetic
%solve add-2-3 : add two three N.
%% Result: N = five
%solve add-3-2 : add three two N.
%% Result: N = five (commutativity)
%solve mult-2-3 : mult two three N.
%% Result: N = s (s (s (s (s (s z))))) = 6
%solve mult-3-2 : mult three two N.
%% Result: N = 6 (commutativity)
%% Exponentiation
%solve exp-2-3 : exp two three N.
%% Result: N = 8
%solve exp-3-2 : exp three two N.
%% Result: N = 9
%% Factorial (defined in prime.elf)
%solve fact-3 : factorial three N.
%% Result: N = 6
%solve fact-4 : factorial four N.
%% Result: N = 24
%% Order relations
%solve two-lt-five : lt two five.
%% Result: lt/s (lt/s lt/z)
%solve three-le-three : le three three.
%% Result: le/s (le/s (le/s le/z))
%% Divisibility
%solve two-div-four : divides two four.
%% Result: divides/intro (mult two two four)
%% ============================================================
%% VERIFIED THEOREMS (Twelf %total checked)
%% ============================================================
%% From nat.elf:
%% nat-case-total: every nat is z or s of something
%% From add.elf:
%% add-total: addition always produces a result
%% add-right-z: N + 0 = N
%% add-right-s: M + (S N) = S(M + N)
%% add-comm: M + N = N + M
%% add-assoc: (A + B) + C = A + (B + C)
%% add-cancel-left: A + B = A + C implies B = C
%% add-func: addition is deterministic
%% From mult.elf:
%% mult-total: multiplication always produces a result
%% mult-right-z: N * 0 = 0
%% mult-left-one: 1 * N = N
%% mult-right-one: N * 1 = N
%% From exp.elf:
%% exp-total: exponentiation always produces a result
%% exp-one: N^1 = N
%% exp-base-one: 1^N = 1
%% exp-base-zero: 0^(S N) = 0
%% From order.elf:
%% le-refl: N <= N
%% le-trans: A <= B and B <= C implies A <= C
%% le-antisym: A <= B and B <= A implies A = B
%% lt-to-le: A < B implies A <= B
%% lt-s-to-le: A < S(B) implies A <= B
%% le-to-lt-s: A <= B implies A < S(B)
%% trichotomy-total: for all M, N: M < N or M = N or M > N
%% lt-trans: A < B and B < C implies A < C
%% From div.elf:
%% one-divides: 1 | N for all N
%% divides-zero: N | 0 for all N
%% divides-refl: N | N for all N
%% From prime.elf:
%% factorial-total: factorial always produces a result
%% ============================================================
%% THEOREMS STATED BUT NOT FULLY PROVEN
%% ============================================================
%% Multiplication:
%% mult-comm: M * N = N * M
%% (Requires mult-right-s lemma with careful
%% associativity/commutativity reasoning)
%%
%% mult-assoc: (A * B) * C = A * (B * C)
%% (Requires distributivity)
%%
%% mult-distrib-l: A * (B + C) = A*B + A*C
%% (Provable with induction on A)
%% Number theory:
%% has-prime-divisor-total: every N > 1 has a prime divisor
%% (Requires strong/well-founded induction)
%%
%% infinitude-of-primes: for any prime P, there exists prime Q > P
%% (Classic Euclidean proof using factorial)
%%
%% euclid-lemma: if P prime and P | AB then P | A or P | B
%% (Requires Bezout's identity or equivalent)
%%
%% fundamental-theorem-existence: every N > 1 has prime factorization
%% (Follows from has-prime-divisor with induction)
%%
%% fundamental-theorem-uniqueness: prime factorization is unique
%% (Requires Euclid's lemma)