Repository navigation
Conversation
A valid nested inductive whose two nested occurrences differ only by a beta-redex, so the kernel makes two auxiliary types, and a theorem that reduces a recursor application through both.
713dec3 to
5ac15cc
Compare
Two valid inductive types whose constructor field mentions the type being declared only inside a beta-redex that reduces it away, once positively and once negatively.
|
@DmitryKorolev: |
|
I wouldn't recommend writing a test based on this behaviour. What the official kernel does is not really sane in the first place. It all comes down to whether you preprocess an inductive signature into beta-normal form, and do a syntactic check. It's highly implementation specific and cursed |
Whether a redex inside a nested occurrence makes a separate auxiliary type is an artefact of the official kernel's syntactic test, not something a checker must reproduce.
|
Fair, it may not be sane, but agreed: I've moved |
|
I just found that |
…ge elimination (#320) Four `corner-cases` tests, all `outcome: either`. This replaces #319: `nested-redex-aux` is unchanged from there, and `vanishing-occurrence` is now a corner case. My comment there was wrong: it is not a duplicate of `positivity-whnf` but its counterpart. There the vanishing occurrence sits under an arrow inside the field and the official kernel rejects; here it is at the head of the field, where whnf removes it, and the official kernel accepts. - `nested-redex-aux`: two nested occurrences that differ only by a beta-redex give the official kernel two auxiliary types. sokonanoda rejects, by design (intgrah/sokonanoda#12). - `vanishing-occurrence`: the type being declared occurs only inside a redex at the head of a field. In #319's CI, kefir, kefir-wasm and metalean-fast rejected it (metalean-fast reports a positivity failure), and eink0rn because the export says `isRec = true` while it derives `false`: the official kernel computes `isRec` without reducing, but checks positivity after reducing. The other 27 checkers accepted. - `imax-nested-absorption`: `imax u v = imax (imax u v) v` and `imax u v = imax v (imax u v)` hold for every assignment, but the official kernel's normalization does not establish them. Locally the nanoda family, con-leche, con-ron, sokonanoda and nano-lean accept; official, lean4lean, Pestka, tenet and kefir reject. Unlike `imax-right-successor`, no right operand is a successor. - `large-elim-maybe-prop`: a large recursor for `MaybePropBox.{u} (α : Sort u) : Sort u | mk : α → MaybePropBox α`, used by `get`. The official kernel only gives this type a recursor into `Prop`; the export uses the kernel's recursor for level `u + 1`, rewritten to `u`. It is sound because the field is a proof whenever the type is a proposition, the same argument as in `proj-maybe-prop`. con-leche and con-ron accept it; their rule is `blockLargeElimAllowed` in `ConLeche/Kernel/Inductives/BlockRec.lean`; everything else I ran rejects (nanoda master and nanoclo panic). The `.lean` files compile with the arena toolchain (4.34.1); the `.ndjson` is a Lean 4.35.0 export of the `u + 1` version with the recursor's level edited by hand.
Adds a test to
corner-cases/withoutcome: either: the nested inductivebuilt with
addDecl(the elaborator never writes such a field), and a theoremnestedRedexthat reducesNestedRedex.recona [b [leaf]]to11. The kernel finds nested occurrences syntactically, so the twoListoccurrences become two auxiliary types and the recursor has three motives. No checker entry changes.A checker that normalises constructor types before collecting nested occurrences merges the two, derives a recursor with two motives and rejects the theorem. sokonanoda does this; its author considers such fields not valid nested inductives and the official kernel's answer an artefact of its syntactic test (intgrah/sokonanoda#12), hence
eitherrather thanaccept. The official kernel, lean4lean, nanoda, nanobruijn, nanoclo, Pestka, tenet, kefir, con-leche and con-ron accept it (checked locally against an export made with Lean 4.35.0). The file compiles on the arena's 4.34.1 toolchain; I have not runlka.py.The theorem is built as a term too, because the elaborator does not see the auxiliary recursor
NestedRedex.rec_1in the file that added the block.Second commit:
other/vanishing-occurrence, alsooutcome: accept. Two inductive types whose constructor field mentions the type being declared only inside a redex that reduces it away:The kernel puts the field in weak head normal form before it looks for occurrences, finds
Natand accepts both, the second one even though the unreduced field has a negative occurrence. kefir (8fb94a9) rejects both inductives; the other 15 checkers I ran accept. kefir also rejectslet X := VanishPos; NatandNat → (fun _ : Type => Nat) VanishPos, and accepts(fun X : Type => X) VanishPos, where the occurrence survives reduction. kefir has issues disabled, so this test is the report.