keyword: interpret
One of the primitive judgments.
(Not to be confused with the many other meanings of the term "instantiation")
The normal way of using Ivy is to declare uninterpreted types and to give the necessary axioms over those types to prove desired properties of a system. However, it is also possible in Ivy to associate types with sorts that are interpreted in the underlying theorem prover by declaring interpret <ty> -> <sort>
Concrete sorts that are currently available for interpreting Ivy types are:
int
: the integersnat
: the non-negative integers{X..Y}
: the subrange of integers fromX
toY
inclusive{a,b,c}
: an enumerated typebv[N]
: bit vectors of lengthN
, whereN > 0
Arithmetic on nat
is saturating. That is, any operation that would yield a neagtive number instead gives zero.
An arbitrary function or relation symbol can be interpreted. This is useful for symbols of the theory that have no pre-defined overloaded symbol in Ivy.
Examples:
Example: integers
type idx
interpret idx -> int
This says that Ivy type idx
should be interpreted using sort int
of the theorem prover. This does not mean that idx
is equated with the integers. If we also interpret type num
with int
, we still cannot compare values of type idx
and type num
. In effect, these two types are treated as distinct copies of the integers.
When we declare idx
as int
, certain overloaded functions and relations on idx
are also automatically interpreted by the corresponding operators on integers, as are numerals of that type. So, for example, +
is interpreted as addition and <
as "less than" in the theory of integers. Numerals are given their normal interpretations in the theory, so 0:idx = 1:idx
would be false.
Example: bit vectors
type t
type s
function extract_lo(X:t) : s
interpret t -> bv[8]
interpret s -> bv[4]
interpret extract_lo -> bfe[3][0]
Here bfe[3][0]
is the bit field extraction operator the takes the low order 4 bits of a bit vector.