I have a function that has a particular set of mappings that I want to inspect. It's small enough where printing out the entire domain and range would be manageable. However, when I execute:
value "domain f"
I get an output looking like this:
"domain
(λu. if u = ⦇x = 8, y = 5⦈ then 1
else if u = ⦇x = 7, y = 5⦈ then 1
else if u = ⦇x = 6, y = 5⦈ then 1
else if u = ⦇x = 5, y = 5⦈ then 1
else if u = ⦇x = 8, y = 0⦈ then 1
...
And when I execute:
value "range f"
I get:
exception Match raised (line 244 of "generated code")
I thought domain
and range
would just return the obvious sets. Any advice here?
In my case, I'm actually using a function like a hash table, i.e. the function has a specific set of "keys" and "values" that I'm interested in observing. Moreso for debug purposes. That may be useful information for this.
Possibly other useful information - this function is a mapping from points to nat, i.e.:
record point =
x :: nat
y :: nat
definition f :: "point => nat"
And I'm trying to collect points which have a count of more than 1:
{p. (f p) > 1 }
This yields this error:
Wellsortedness error:
Type point not of sort enum
No type arity point_ext :: enum
As all functions in Isabelle/HOL are total, talking about the domain of a function f :: 'a => 'b
means talking about UNIV :: 'a set
. Therefore there is no constant domain
defined by the library (Note that domain
is printed blue in the output window. range f
is then defined simply as the image of UNIV
under f
. If you need partiality, you need to model this explicitly, for example with a function f' :: 'a => 'b option
. To get domain and range of such partial functions use dom
and ran
defined in Map.thy
(Included in Main).
For your first output: domain
is just a free variable, and therefore Isabelle cannot proceed with the evaluation.
The value
command works by invoking the code generator and running the generated ML code. If it gives an error, most of the times that means what you supplied is not executable or at least Isabelle does not know how.
For value "range f"
the generated code tries to compute the range by taking the image of UNIV :: point
under f
but there is only a code equation for finite sets, therefore it fails. Maybe there is a more clever way to find range f
, but Isabelle does no magic :(.
You can take a look at (something probably similar to) the generated code:
definition "R = range (\<lambda> x::bool . True::bool)"
export_code "R" in SML
For your last example, the 'obvious' way of computing the set is, once again, to compute f p > 1
for all points p
. To do this the code generator would like to enumerate all values of the type. This would be provided by the class enum
for finite types. As your point
type contains infinite values it does not instantiate enum
and the code generator cannot proceed.
I see, that all makes sense. For what I'm trying to do, I think an association list might make more sense. It was just convenient to use a function to start.
Alex Weisberger has marked this topic as resolved.
Last updated: Dec 21 2024 at 16:20 UTC