Skip to content

Commit 4c78c98

Browse files
explain missing coinduction feature
1 parent 976b2a0 commit 4c78c98

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,9 @@ def derive_emptystr {α: Type u} {a: α} {w: List α}:
127127

128128
For non Lean users: `<;>` is similar to the Monad bind operator (`>>=`) over proof goals. It takes a list of goals to prove and applies the following tactics to each of the goals, which each produce another list of goals, which are all joined together into one list.
129129

130-
## Termination Checking
130+
## Coinduction / Termination Checking
131131

132-
[Automatic.lean](./Sodal/Automatic.lean) has a lot of termination checking issues.
133-
We can safely define Automatic.Lang:
132+
Lean does not have coinduction, which seems to be required for defining `Automatic.Lang`. We attempt an inductive defintion:
134133

135134
```lean
136135
inductive Lang {α: Type u} : Language.Lang α -> Type (u+1) where
@@ -140,7 +139,10 @@ inductive Lang {α: Type u} : Language.Lang α -> Type (u+1) where
140139
: Lang R
141140
```
142141

143-
But when we try to instantiate it using any operator, we get termination checking issues, for example given `emptyset`:
142+
143+
But this results in a lot of termination checking issues, when instantiating operators in [Automatic.lean](./Sodal/Automatic.lean).
144+
145+
For example, when we instantiate `emptyset`:
144146
```
145147
-- ∅ : Lang ◇.∅
146148
def emptyset {α: Type u}: Lang (@Language.emptyset.{u} α) := Lang.mk
@@ -163,7 +165,8 @@ no parameters suitable for structural recursion
163165
well-founded recursion cannot be used, 'Automatic.emptyset' does not take any (non-fixed) arguments
164166
```
165167

166-
Getting around this issue requires the use of `unsafe`:
168+
This seems to be a fundamental issue in regards to how inductive types work.
169+
We can get around this issue by using `unsafe`:
167170

168171
```
169172
-- ∅ : Lang ◇.∅
@@ -175,7 +178,7 @@ def emptyset {α: Type u}: Lang (@Language.emptyset.{u} α) := Lang.mk
175178
(derive := fun _ => emptyset)
176179
```
177180

178-
This was probably inevitable, given that the Agda version of Lang in [Automatic.lagda](https://github.com/conal/paper-2021-language-derivatives/blob/main/Automatic.lagda#L40-L44) required coinduction, which is not a feature of Lean:
181+
This issue was probably inevitable, given that the Agda version of Lang in [Automatic.lagda](https://github.com/conal/paper-2021-language-derivatives/blob/main/Automatic.lagda#L40-L44) required coinduction, which is not a feature of Lean:
179182

180183
```agda
181184
record Lang (P : ◇.Lang) : Set (suc ℓ) where
@@ -185,7 +188,7 @@ record Lang (P : ◇.Lang) : Set (suc ℓ) where
185188
δ : (a : A) → Lang (◇.δ P a)
186189
```
187190

188-
Also this representation encountered issues with Agda's termination checker, but only when defining the derivative of the concat operator, not all operators as in Lean, which was fixed using a sized version of the record:
191+
Note, the Agda representation also encountered issues with Agda's termination checker, but only when defining the derivative of the concat operator, not all operators as in Lean. Also this was fixable in Agda using a sized version of the record:
189192

190193
```agda
191194
record Lang i (P : ◇.Lang) : Set (suc ℓ) where
@@ -195,7 +198,9 @@ record Lang i (P : ◇.Lang) : Set (suc ℓ) where
195198
δ : ∀ {j : Size< i} → (a : A) → Lang j (◇.δ P a)
196199
```
197200

198-
We hope to find help to remove the use of `unsafe` in Lean.
201+
We hope to find help to remove the use of `unsafe` in Lean or that it is possible to fix using a future `coinductive` feature.
202+
203+
Apparently there are libraries in Lean that support coinduction, but none that support indexed coinductive types, which is what we require in this case.
199204

200205
## Thank you
201206

0 commit comments

Comments
 (0)