Datatypes, sort-erased #
A datatype sort is declared, in three steps: a constructor declaration collects its selectors, a
datatype declaration collects its constructors, and Srt.datatype turns that into a sort. Once the
sort exists, Srt.getDatatype reflects it back as a Datatype whose constructors and selectors
carry the terms that build and take apart its values.
A declared sort is fresh, never nominal. Declaring the same datatype twice gives two different sorts that print identically, and cvc5 rejects any term mixing them:
Subexpressions must have the same type: Type 1: Pair, Type 2: Pair
So Srt.datatype, Srt.datatypes and Solver.declareDatatype record each datatype's name in the
scope, and refuse a name already taken; Srt.ofName finds the sort again by its name.
A record sort is the exception: cvc5 builds the same record sort from the same fields, so it is
not declared. Records are still datatypes underneath, and Cvc.Untyped.Theory.Record builds on
what is here.
Recursion goes through addSelectorSelf for a datatype referring to itself, and
addSelectorUnresolved with Srt.datatypes for a mutually recursive group.
Declaring #
Create a datatype constructor declaration.
nameThe name of the datatype constructor.
Equations
- Cvc.Datatype.Ctor.Decl.mk name = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkDatatypeConstructorDecl name
Instances For
Adds a selector named name, of codomain sort srt.
Equations
- d.addSelector name srt = Cvc.runUnsafe'✝ ((Cvc.Datatype.Ctor.Decl.toUnsafe✝ d).addSelector name (Cvc.Srt.toUnsafe✝ srt))
Instances For
Adds a selector whose codomain is the datatype being declared.
Equations
- d.addSelectorSelf name = Cvc.runUnsafe'✝ ((Cvc.Datatype.Ctor.Decl.toUnsafe✝ d).addSelectorSelf name)
Instances For
Adds a selector whose codomain is another datatype of the same mutually recursive group.
Equations
- d.addSelectorUnresolved name unresDatatypeName = Cvc.runUnsafe'✝ ((Cvc.Datatype.Ctor.Decl.toUnsafe✝ d).addSelectorUnresolved name unresDatatypeName)
Instances For
Create a datatype declaration.
nameThe name of the datatype.paramsA list of sort parameters.isCoDatatypeTrue if a codatatype is to be constructed.
Equations
- Cvc.Datatype.Decl.mk name params isCoDatatype = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkDatatypeDecl name params isCoDatatype
Instances For
Add datatype constructor declaration.
ctorThe datatype constructor declaration to add.
Equations
- d.addCtor ctor = Cvc.runUnsafe'✝ ((Cvc.Datatype.Decl.toUnsafe✝ d).addConstructor (Cvc.Datatype.Ctor.Decl.toUnsafe✝ ctor))
Instances For
Get the number of constructors for this datatype declaration.
Equations
Instances For
Determine if this datatype declaration is parametric.
Warning: this function is experimental and may change in future versions.
Equations
Instances For
Determine if this datatype declaration is resolved (has already been used to declare a datatype).
Equations
Instances For
Declares a datatype sort from its constructors.
The short path: no parameters and no mutual recursion. Srt.datatype is the general one.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Reflecting #
Srt.getDatatype is the way in, from a sort that Srt.isDatatype holds of.
Get the codomain sort of this selector.
Instances For
The constructor term of a parametric datatype, at the given instance of it.
Equations
- c.getInstantiatedTerm retSort = Cvc.runUnsafe'✝ ((Cvc.Datatype.Ctor.toUnsafe✝ c).getInstantiatedTerm (Cvc.Srt.toUnsafe✝ retSort))
Instances For
The number of selectors of this datatype constructor.
Equations
Instances For
Get the datatype selector with the given name.
This is a linear search through the selectors, so in case of multiple, similarly-named selectors, the first is returned.
nameThe name of the datatype selector.
Equations
- c.getSelector name = Cvc.runUnsafe'✝ ((Cvc.Datatype.Ctor.toUnsafe✝ c).getSelector name)
Instances For
The datatype selector at index idx.
Equations
- c.getSelectorAt idx = (Cvc.Datatype.Ctor.toUnsafe✝ c).getSelectorAt idx
Instances For
Equations
- Cvc.Datatype.Ctor.instForInSelectorOfMonad = { forIn := @Cvc.Datatype.Ctor.instForInSelectorOfMonad._aux_1 inst✝¹ m inst✝ }
Get the datatype constructor with the given name.
This is a linear search through the constructors, so in case of multiple, similarly-named constructors, the first is returned.
nameThe name of the datatype constructor.
Equations
- dt.getCtorNamed name = Cvc.runUnsafe'✝ ((Cvc.Datatype.toUnsafe✝ dt).getConstructor name)
Instances For
Get the number of constructors of this datatype.
Equations
Instances For
Get the datatype constructor at a given index.
idxThe index of the datatype constructor to return.
Equations
- dt.getCtorAt idx = (Cvc.Datatype.toUnsafe✝ dt).getConstructorAt idx
Instances For
Equations
- Cvc.Datatype.instForInCtorOfMonad = { forIn := @Cvc.Datatype.instForInCtorOfMonad._aux_1 inst✝¹ m inst✝ }
Looks a selector up by name, across every constructor.
Equations
- dt.getSelector name = Cvc.runUnsafe'✝ ((Cvc.Datatype.toUnsafe✝ dt).getSelector name)
Instances For
The sort parameters of this datatype, failing unless it is parametric.
Equations
Instances For
Determine if this datatype is parametric.
Warning: this function is experimental and may change in future versions.
Equations
Instances For
Determine if this datatype corresponds to a co-datatype.
Equations
Instances For
Determine if this datatype corresponds to a tuple.
Equations
- dt.isTuple = (Cvc.Datatype.toUnsafe✝ dt).isTuple
Instances For
Determine if this datatype corresponds to a record.
Warning: this function is experimental and may change in future versions.
Equations
- dt.isRecord = (Cvc.Datatype.toUnsafe✝ dt).isRecord
Instances For
Whether this datatype is well-founded.
A datatype that is not a codatatype is well-founded when it has a value of finite size.
Equations
Instances For
Building and taking apart values #
Each of these takes the relevant term off a Ctor or Selector as its first argument,
which is how cvc5 spells datatype application.
Applies a constructor to its arguments.
Equations
- ctor.applyCtor args = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.APPLY_CONSTRUCTOR (#[ctor] ++ args)
Instances For
Reads a field out of a datatype value.
Undefined where the value was not built by the selector's own constructor, which is what
applyTester is for.
Equations
- sel.applySelector dt = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.APPLY_SELECTOR #[sel, dt]
Instances For
Whether a datatype value was built by a given constructor.
Equations
- tester.applyTester dt = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.APPLY_TESTER #[tester, dt]
Instances For
The datatype value with one field replaced.
Equations
- updater.applyUpdater dt newValue = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.APPLY_UPDATER #[updater, dt, newValue]
Instances For
Applies a constructor to its arguments.
Instances For
Reads a field out of a datatype value.
Undefined where the value was not built by the selector's own constructor, which is what
applyTester is for.
Equations
- sel.apply dt = do let __do_lift ← sel.getTerm __do_lift.applySelector dt
Instances For
The datatype value with one field replaced.
Equations
- sel.applyUpdate dt newValue = do let __do_lift ← sel.getUpdaterTerm __do_lift.applyUpdater dt newValue
Instances For
Matching #
A match term picks a body by the constructor its scrutinee was built with. Each case pairs a
pattern with the body to use when it applies, and mkMatch collects them. A case binds its
constructor's fields to bound variables (Term.mkBVar).
cvc5 checks that the cases cover every constructor, unless one of them is a catch-all, and that all of the bodies have the same sort.
Cases are tried in order, so a catch-all placed before another case shadows it — the same reading
Lean's own match has. cvc5 accepts a catch-all in any position, including as the only case.
ctorOf, checkArity and mkBVarAt find a constructor by name and bind its fields, which is
what smt! match expands to; hand-written matches can use them too.
The constructor of the given name, of the datatype this term's sort denotes.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A fresh bound variable at the sort of the constructor's field at idx.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A match case for a constructor taking no field.
pattern is that constructor applied to nothing. A constructor that does take fields needs
matchBindCase, which binds them.
Equations
- pattern.matchCase body = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.MATCH_CASE #[pattern, body]
Instances For
A match case binding the variables its pattern mentions.
pattern is either a constructor applied to exactly bvars, or a single bound variable — which
makes the case a catch-all, matching whatever the earlier cases left over. body is free to
mention the bound variables.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The body of whichever case matches the scrutinee.
Every case must come from matchCase or matchBindCase, and the resulting term has the sort the
bodies share.
Equations
- scrutinee.mkMatch cases _h = Cvc.runUnsafe✝ fun (tm : cvc5.TermManager) => tm.mkTerm cvc5.Kind.MATCH (#[scrutinee] ++ cases)
Instances For
The view of a datatype operation #
Written by hand, and generic over every datatype: which constructors and fields a datatype has is a
fact about its declaration, so they come back by name. Records, tuples and nullables are datatypes
to cvc5 too, so this covers them, a record's fields and a tuple's components being selectors like
any other — a record's constructor answers the name cvc5 gives it, __cvc5_record_….
A datatype operation, taken apart one level, sort-erased.
- construct
[Ω]
(ctor : String)
(args : Terms)
: View.Datatype
A constructor applied to its arguments, none for a constant constructor.
- selectField
[Ω]
(field : String)
(arg : Term)
: View.Datatype
A field read off a datatype term.
- updateField
[Ω]
(field : String)
(arg value : Term)
: View.Datatype
argwith its field replaced byvalue. - testCtor
[Ω]
(ctor : String)
(arg : Term)
: View.Datatype
Whether
argwas built by the constructorctor.
Instances For
Takes a term apart one level, if it is a datatype operation.
Equations
- One or more equations did not get rendered due to their size.
Instances For
smt! match #
match … with | ctor x y => … | _ => … over a datatype, binding each constructor's fields
without the writer having to make bound variables.
The catch-all is spelled _ and nothing else: a bare identifier is always a constructor name, so
| nil => … means the constructor. The body of a catch-all can mention the scrutinee directly.
One variable bound by a pattern, optionally at a stated sort.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
A variable whose sort is inferred.
Equations
- Cvc.smtPatArg = Lean.ParserDescr.node `Cvc.smtPatArg 1022 (Lean.ParserDescr.const `ident)
Instances For
A variable at a stated sort, (x : Lst); typed layer only, refused sort-erased.
Equations
- One or more equations did not get rendered due to their size.
Instances For
One alternative of a match.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
An alternative matching one constructor, binding one variable per field.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The catch-all alternative, taken when no earlier one matches.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Matches a datatype term against its constructors.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Whether an identifier is referenced anywhere in a piece of syntax.
Used on a match body, before it is expanded, to tell whether a variable the pattern binds is mentioned at all — which in the typed layer is what decides whether its index can be inferred.
Binders shadow, so this stops at one: a nested alternative or let that rebinds the name is
talking about a different variable, and descending into its body would report an occurrence that
is not one.
Parses a pattern's variables into their binders and their sort ascriptions, where given.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Expands one alternative of a sort-erased match into a term building that case.
The body sees each variable the pattern binds, under the name the writer gave it, as a term. A variable is made at its field's declared sort, so a sort ascription is refused.
Equations
- One or more equations did not get rendered due to their size.