pyrites/twelf-experiments/peano/notes-on-proofs.md
2026-04-15 17:10:03 +01:00

270 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Technical Notes on Distributivity Proof Attempts
## Current Status (Session 6)
### Latest Attempt: Using add-permute as Foundation
**Key Insight:** The existing `add-permute` lemma already captures exactly the pattern needed for the base case of distributivity:
```twelf
add-permute : add M' P R1 -> add N P R -> add N R1 R2 -> add M' R R2 -> type.
```
This says: if `M' + P = R1` and `N + P = R`, then `N + R1 = R2` and `M' + R = R2`.
For distributivity base case (A=0):
- We have: `add AB' AC' ABAC` (i.e., AB' + AC' = ABAC)
- We have: `add C AC' AC` (i.e., C + AC' = AC)
- We need: `add C ABAC R` and `add AB' AC R` for the same R
- This is exactly what add-permute gives us!
### The add-four-way Helper
Created a helper to generalize the pattern for the step case:
```twelf
add-four-way : add B C BC -> add AB' AC' ABAC -> add B AB' AB -> add C AC' AC
-> add BC ABAC R -> add AB AC R -> type.
```
**Base case (B=0):** Uses add-permute directly ✓
**Step case (B = s B'):** Structural recursion
- Given: `add (s B') C (s BC')` where `add B' C BC'`
- IH provides: `add BC' ABAC R'` and `add AB'' AC R'`
- Derive: `add (s BC') ABAC (s R')` and `add (s AB'') AC (s R')`
This helper loaded successfully with `%% OK %%` and passed totality checking!
### mult-distrib-left Using add-four-way
```twelf
mult-distrib-left : add B C BC -> mult A BC ABC -> mult A B AB -> mult A C AC
-> add AB AC ABC -> type.
```
**Base case (A=0):** Trivial - `0*(B+C) = 0 = 0 + 0 = 0*B + 0*C`
**Step case (A = s A'):**
- By definition: `(s A') * (B+C) = (B+C) + A'*(B+C)`
- By definition: `(s A') * B = B + A'*B`
- By definition: `(s A') * C = C + A'*C`
- By IH: `A'*(B+C) = A'*B + A'*C`, call this `ABAC`
- Need to show: `(B+C) + ABAC = (B + A'*B) + (C + A'*C)`
- This is exactly what add-four-way proves!
### The Mode Error
```
mult.elf:195.26-195.38 Error:
Occurrence of variable X9 in input (+) argument not necessarily ground
%% ABORT %%
```
Line 195 is the step case of mult-distrib-left.
**Analysis:** The variable X9 corresponds to `AB` (the result of `B + A'*B`). The issue is that in the mode declaration:
```twelf
%mode mult-distrib-left +D1 +D2 -D3 -D4 -D5.
```
We have `mult A B AB` as an output (D3 is marked `-`), which means AB is an output. But in the step case, we're calling:
```twelf
add-four-way Dadd_BC Dadd_AB'_AC' Dadd_B_AB' Dadd_C_AC' Dadd_BC_ABC Dadd_AB_AC
```
Where `Dadd_B_AB'` is `add B AB' AB`, and this is an **input** to add-four-way (marked `+` in its mode).
**The fundamental problem:**
- `mult A B AB` must be an OUTPUT of mult-distrib-left (we're constructing it)
- But `add B AB' AB` must be an INPUT to add-four-way (it needs it to compute)
- These are contradictory requirements!
## Why This Happens
The step case structure is:
1. `(s A') * B = B + A'*B` - this gives us `add B AB' AB` where AB' is the result of `A'*B`
2. We need this derivation `add B AB' AB` to pass to add-four-way
3. But we're simultaneously trying to **output** the multiplication `mult (s A') B AB`
The issue is that we need to know AB before we can call add-four-way, but AB is determined by the multiplication definition itself.
## The Root Cause: Output Factoring Mismatch
Looking at add-assoc as a model:
```twelf
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.
```
This works because:
- Input: `add A B AB` (AB is known from this derivation)
- Input: `add AB C ABC` (ABC is known from this derivation)
- Output: `add B C BC` (BC is computed)
- Output: `add A BC ABC` (same ABC, verified to match)
For distributivity, we're trying:
- Input: `add B C BC` (BC is known)
- Input: `mult A BC ABC` (ABC is known)
- Output: `mult A B AB` (AB needs to be computed AND used as input to helper)
- Output: `mult A C AC` (AC needs to be computed AND used as input to helper)
**The problem:** We need AB and AC to call add-four-way, but they're outputs!
## Possible Solutions
### Solution 1: Change the Mode Declaration
What if we make AB and AC inputs instead of outputs?
```twelf
%mode mult-distrib-left +D1 +D2 +D3 +D4 -D5.
```
**Problem:** Now the caller needs to provide the multiplications first. This defeats the purpose - we're trying to PROVE they exist and relate correctly.
### Solution 2: Reorder the Helper Call
What if we compute the multiplications first, then verify with add-four-way?
**Problem:** We can't "compute" them without constructing the full derivations, which is what we're trying to do in the theorem itself. Circular dependency.
### Solution 3: Use mult-total to Construct First
```twelf
<- mult-total A B Dmult_AB' %% Get A*B = AB
<- mult-total A C Dmult_AC' %% Get A*C = AC
<- add-four-way ... %% Then use in helper
```
**Problem:** mult-total gives us `mult A B AB` for some AB, but we need to extract the specific AB value to use in add-four-way. The derivation contains it, but Twelf's mode system doesn't let us "extract" it in the way we need.
### Solution 4: Reformulate add-four-way with mult Terms
Instead of having add-four-way take addition derivations, what if it takes multiplication derivations?
**Problem:** This makes add-four-way dependent on mult, which is backwards - it's really a lemma about addition rearrangement.
### Solution 5: Accept Incomplete and Document
The mathematical proof is sound. The issue is purely about Twelf's mode system and how it handles dependent outputs. This might be a fundamental limitation of the current formulation.
## Comparison with Agda
In Agda (from PLFA):
```agda
*-distrib-+ : (m n p : ) (m + n) * p m * p + n * p
*-distrib-+ zero n p = refl
*-distrib-+ (suc m) n p rewrite *-distrib-+ m n p | +-assoc p (m * p) (n * p) = refl
```
The `rewrite` tactic:
1. Uses propositional equality `≡`
2. Can substitute equals for equals anywhere
3. Doesn't require explicit derivation terms
In Twelf:
1. Relations, not functions
2. Explicit derivation terms required
3. Mode system requires strict input/output flow
4. Can't "rewrite" - must construct explicit derivation chains
## What Worked: mult-comm-exists vs mult-comm
**mult-comm** (failed - 50+ attempts):
```twelf
mult-comm : mult M N P -> mult N M P -> type.
```
Requires P to be both input (from type signature) and output (from construction).
**mult-comm-exists** (succeeded):
```twelf
mult-comm-exists : mult M N P -> mult N M Q -> type.
```
P is input, Q is output. Proves existence without equality.
## Lesson Learned
**Twelf's mode system requires a strict DAG of information flow.**
For a theorem with signature `+inputs -> -outputs`, every output must be:
1. Computable solely from the inputs
2. Not required as an input to intermediate lemmas
3. Not circularly dependent on other outputs
Distributivity violates rule 2: we need the output multiplications as inputs to the rearrangement helper.
## Possible Path Forward
### Idea: Two-phase proof
**Phase 1: Existence**
```twelf
mult-distrib-left-exists : add B C BC -> mult A BC ABC ->
mult A B AB -> mult A C AC -> type.
```
Just proves the three multiplications can coexist (all as inputs).
**Phase 2: Rearrangement**
```twelf
mult-distrib-rearrange : mult A BC ABC -> mult A B AB -> mult A C AC ->
add AB AC ABC -> type.
```
Given all three multiplications, prove they satisfy the distributive property.
But this still has the problem that phase 2 requires AB and AC as inputs to derive the addition...
### Idea: Extract results using functionality
Since mult is functional, `mult A B AB1` and `mult A B AB2` implies `AB1 = AB2`. We could:
1. Use mult-total to get `mult A B AB_exists`
2. Use add-four-way with the RESULT of mult (extracted somehow)
3. Use mult-func to verify consistency
But Twelf doesn't have a clean way to "extract" the result from a derivation term.
### Idea: Inline add-four-way into mult-distrib-left
Instead of calling add-four-way as a helper, inline its proof directly into the step case. This might give Twelf's mode checker more flexibility.
**Problem:** This creates a very complex proof with deeply nested recursion, and likely hits the same mode issues.
## Conclusion
After 18+ systematic attempts across 6 sessions:
1.**mult-comm-exists** - Proved by reformulating to avoid circular dependency
2.**add-permute** - Key rearrangement lemma
3.**mult-right-s** - Key lemma for commutativity
4.**add-four-way** - The exact rearrangement needed for distributivity
5.**mult-distrib-left** - Blocked on mode system constraints
The mathematical content is complete. The blocker is encoding it in a way that satisfies Twelf's mode system.
**Recommendation:** Consult Twelf experts or search for published Twelf developments that prove distributivity for a relational multiplication encoding. The issue is not the mathematics but the encoding strategy.
## Session 6 Specific Error Details
File: mult.elf, line 195
Error: "Occurrence of variable X9 in input (+) argument not necessarily ground"
X9 = AB (result of B + A'*B)
Context: Calling add-four-way in the step case of mult-distrib-left
Issue: AB is an output of mult-distrib-left but an input to add-four-way
The mode checker traces:
- mult-distrib-left has mode `+D1 +D2 -D3 -D4 -D5`
- D3 is `mult A B AB` (output)
- In step case, we construct `mult (s A') B AB` as `mult/s Dadd_B_AB' Dmult_AB'`
- Dadd_B_AB' is `add B AB' AB`
- This is passed as INPUT to add-four-way (position 3, marked +)
- But AB is only known AFTER we construct the output D3
- Circular dependency: need AB to call helper, but get AB from output
This is the precise technical reason the proof fails.