Open awalterschulze opened 1 year ago
Have you considered using computed fields for this? (example: https://github.com/leanprover/lean4/blob/8a302e6135bc1b0f1f2901702664c56cd424ebc2/src/Lean/Expr.lean#L461-L464) they allow you define functions on your inductives that get pre computed upon creation of an inductive value so they behave like a field but you do not have to do the proofs you are attempting about them.
I don't think computed_field will work, but I tried it
inductive Desc where
| intro
(name: String)
(params: List Desc)
with
@[computed_field]
hash : @& Desc → UInt64
| .intro name params => hash_list (31 * 17 + hash_string name) (List.map (fun d => d.hash) params)
deriving Repr
For this I do need to add the whole hash function, which I was trying to avoid, to keep the example small, but it isn't that big
def hash_list (innit: UInt64) (list: List UInt64): UInt64 :=
List.foldl (fun acc h => 31 * acc + h) innit list
def hash_string (s: String): UInt64 :=
hash_list 0 (List.map (Nat.toUInt64 ∘ Char.toNat) (String.toList s))
def hash_with_name (name: String) (params: List Desc): UInt64 :=
hash_list (31 * 17 + hash_string name) (List.map Desc.hash params)
Unfortunately I got an error: error: computed fields require at least two constructors
Also I got another error, which might be fixable:
fail to show termination for
Desc.hash
with errors
structural recursion cannot be used
failed to prove termination, use `termination_by` to specify a well-founded relation
The second one is fixable. It is because Lean's termination checker is right now not capable of understanding that mapping a function recursively onto a list does terminate on its own.
I do not know why Lean requires a thing to have at least two ctors for a computed field to work out. Maybe @Kha or @gebner ?
It looks like it is possible to write
inductive IsSmart : Desc → Prop
| isSmart: ∀
(name: String)
(params: List Desc)
(hash: UInt64),
desc = Desc.intro name hash params
→ hash = hash_with_name name params
→ (∀ param, param ∈ params → IsSmart param)
→ IsSmart desc
And not get any of the problems
I think the issue can now be renamed to something to request a more descriptive error message that might guide the user to this solution?
I found the solution on Zulip chat https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.E2.9C.94.20lean4.20struggling.20with.20recursive.20properties
I found the solution on Zulip chat https://leanprover.zulipchat.com/#narrow/stream/270676-lean4/topic/.E2.9C.94.20lean4.20struggling.20with.20recursive.20properties
@awalterschulze if the solution in the Zulip thread was satisfactory, please consider closing this issue.
The solution on Zulip chat unblocks me.
I am keeping it open because maybe:
Prerequisites
Description
I want to declare a property that a recursive structure was constructed using a smart constructor. The smart constructor mainly constructs a hash field and the property would allow me to trust the hash field's value was properly precomputed.
I get an error:
error: unexpected inductive type occurrence
I only get the error if I include the line
→ Forall IsSmart params
. So I suspect it has something to do with two recursive inductive types calling each other.I first asked about this on stack exchange, thinking I was doing something wrong. https://proofassistants.stackexchange.com/questions/2045/unexpected-inductive-type-occurrence-error-for-recursive-inductive-type/2057#2057
I also tried their suggestion of using
mutual
, but that didn't work https://gist.github.com/awalterschulze/f3e95406063c0e5e6bff97343c93b2b0I am wondering if this is a bug in Lean or if I am doing something wrong?
Steps to Reproduce
Expected behavior: [What you expect to happen]
I expect this to compile without any issues, since it is possible to do this in Coq:
https://github.com/katydid/proofs/blob/old-coq/src/Symbolic/Ast/SmartFunc.v#L8-L18
Actual behavior: [What actually happens]
error: unexpected inductive type occurrence
Reproduces how often: [What percentage of the time does it reproduce?]
100%
Versions
Additional Information
Any additional information, configuration or data that might be necessary to reproduce the issue.