Zulip Chat Archive

Stream: new members

Topic: Strange typing failure


Ching-Tsun Chou (May 02 2025 at 23:15):

Consider the following definitions:

import Mathlib.Data.Set.Card

class Automata (A : Type*) where
  State : Type*
  init : Set State
  next : State  A  Set State

class DetAutomata (A : Type*) extends Automata A where
  get_init : State
  get_next : State  A  State
  det_init : init = {get_init}
  det_next :  s a, next s a = {get_next s a}

variable {A : Type*}

def AutomataPSet (M : Automata A) : DetAutomata A where
  State := Set M.State
  init := {M.init}
  next := fun ps a  {  s  ps, M.next s a }
  get_init := M.init
  get_next := fun ps a   s  ps, M.next s a
  det_init := by simp
  det_next := by simp

variable (M : Automata A) (s : M.State) (p : (AutomataPSet M).State)
#check (p : Set M.State)
#check (s  p)

The last #check above produces this error message:

failed to synthesize
  Membership (Automata.State A) (Automata.State A)

Why? The penultimate #check verifies that p is a set of M.State. Why doesn't s ∈ p type-check?

Aaron Liu (May 02 2025 at 23:20):

Although the type of p is defeq to Set M.State, it is not reducibly defeq, and so typeclass inference will not see through.

Ching-Tsun Chou (May 02 2025 at 23:21):

How do I make work here?

Aaron Liu (May 02 2025 at 23:23):

You can make AutomataPSet reducible or you can write an instance of Membership (Automata.State A) (Automata.State A).

Aaron Liu (May 02 2025 at 23:24):

Probably a better way would be to not bundle the state, so you don't have this problem in the first place.

Ching-Tsun Chou (May 02 2025 at 23:26):

Thanks! What do you mean by "not bundling the state"?

Aaron Liu (May 02 2025 at 23:29):

class Automata (A : Type*) (State : Type*) where

Ching-Tsun Chou (May 02 2025 at 23:32):

I see. Actually I started with that approach. However, I wanted to have a definition like the following one, which becomes messier if I don't bundle the state.

def AutomataSum (M : I  Automata A) : Automata A where
  State := Σ i : I, (M i).State
  init :=  i : I, Sigma.mk i '' (M i).init
  next := fun i, s a  Sigma.mk i '' (M i).next s a

Aaron Liu (May 02 2025 at 23:34):

How does this become messier?

Ching-Tsun Chou (May 02 2025 at 23:42):

AutomataSum will need an additonal argument of an indexed family of states.

Ching-Tsun Chou (May 02 2025 at 23:50):

For another example, suppose I want to define AutomataSum of only 2 automata M1 amd M2. With the bundled approach, I need three arguments: A, M1, M2. With the unbundled approach, I need five arguments: A, S1, S2, M1, M2, where S1 and S2 are the state types of M1 and M2.

Aaron Liu (May 03 2025 at 00:20):

That can be implicit argument?

Ching-Tsun Chou (May 03 2025 at 00:30):

There is also the problem of how you define the State of AutomataSum and AutomataPSet, if State is an input instead of an output.

Ching-Tsun Chou (May 03 2025 at 00:32):

You end up with two parallel sets of definitions, one working on the state types and the other working on the automata classes.


Last updated: Dec 20 2025 at 21:32 UTC