I want to model the following Scala hierarchy in the Inox solver interface:
abstract class Element()
abstract class nonZero() extends Element
final case class Zero() extends Element
final case class One() extends nonZero()
final case class notOne() extends nonZero()
How can I model nonZero?
If I model it as an constructor
def mkConstructor(id: Identifier, flags: Flag*)
(tParamNames: String*)
(sort: Option[Identifier])
(fieldBuilder: Seq[TypeParameter] => Seq[ValDef]) = {
val tParams = tParamNames map TypeParameter.fresh
val tParamDefs = tParams map (TypeParameterDef(_))
val fields = fieldBuilder(tParams)
new ADTConstructor(id, tParamDefs, sort, fields, flags.toSet)
}
Then I'm not able to specify that it has other constructors extending it. Whereas if I model it as a sort:
def mkSort(id: Identifier, flags: Flag*)
(tParamNames: String*)
(cons: Seq[Identifier]) = {
val tParams = tParamNames map TypeParameter.fresh
val tParamDefs = tParams map (TypeParameterDef(_))
new ADTSort(id, tParamDefs, cons, flags.toSet)
}
Then I cannot specify that it is a subtype of Element.
Why do I need this for
I need this hierarchy because I need to state properties as this:
The set of non zero elements of the field with one, inverse and multiplication by a non zero element forms a group.
I would need then some mechanism to generate a type to restrict the constructors of a sort, in this case, restrict the constructors of Element
to One
and notZeroOne()
. In that case I would be modelling:
abstract class Element()
final case class Zero() extends Element
final case class One() extends Element()
final case class notZeroOne() extends Element()
What is the cleanest solution for this?