pyrites/twelf-experiments/peano/notes-on-proofs.md

270 lines
9.5 KiB
Markdown
Raw Normal View History

2026-04-15 17:10:03 +01:00
# 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.