What is the main symbol in Isabelle's set operator (‘) :: ('a => 'b) => 'a set => 'b set? - isabelle

I was wondering what is the symbol ‘ in the Isabelle tutorial main.pdf below (under the section "Set")?
(‘) :: ('a => 'b) => 'a set => 'b set
By looking into the symbols tab, the closest in shape I could find is \<acute> under the "Unsorted" category. I tried to evaluate the following expression, but it doesn't parse:
value "´ (λ(n::nat). n+1) {1,2}"
value "(λ(n::nat). n+1) ´ {1,2}"
Can anyone help to explain the usage here and what it does?

I believe that the symbol that you are looking for is `, not ‘ or ´. The symbol ` is an infix notation for the constant image that is defined in theory Set.thy in the main library of Isabelle/HOL. Hopefully, the name of the constant is self-explanatory. For completeness, I restate the definition in this answer:
definition image :: "('a ⇒ 'b) ⇒ 'a set ⇒ 'b set" (infixr "`" 90)
where "f ` A = {y. ∃x∈A. y = f x}"
Thence,
value "(λ(n::nat). n+1) ` {1,2}"
evaluates to "{2, 3}" :: "nat set", as expected.

Related

Is there a way to add syntax for a custom datatype in Isabelle?

So I have two custom datatypes:
datatype ('a, 't) action = ACTION (name: "'a") (args: "'t list") ("⌈_ _⌋")
and
datatype ('a, 't) multiaction = MULTIACTION "('a, 't) action multiset" ("⟨(_)⟩")
Both of them work with their given notations, however whenever I want to use these data structures in their pretty-printed format, it looks a little redundant. For example:
value "⟨{#⌈a b⌋, ⌈c d⌋#}⟩"
What I'd like to do is have the above typed without the multiset brackets, so that it looks like this:
value "⟨⌈a b⌋, ⌈c d⌋⟩"
What I've tried is using syntax:
syntax
"_maction" :: "args ⇒ ('a, 't) multiaction" ("⟨_⟩" [0] 60)
translations
"⟨x⟩" == "CONST MULTIACTION {#x#}"
But when I try it out with some datatypes:
value "⟨⌈''x'' [1,2,3::int]⌋⟩"
But I get a wellsortedness error, which I have no idea why it occurs. Can I please have some help with this?
Thanks in advance!
Perhaps, you are looking to lift the multiset syntax to multiaction? In this case, you may also wish to lift the relevant definitions for the multiset (as noted in the comments, ideally, you will wish to use the datatype/lift_definition infrastructure for this):
datatype ('a, 't) action = ACTION (name: "'a") (args: "'t list") ("⌈_ _⌋")
datatype ('a, 't) multiaction = MULTIACTION "('a, 't) action multiset"
(*this should not be lifted manually: use the integration of
the datatype and lifting infrastructure*)
fun add_multiaction ::
"('a, 'b) action ⇒ ('a, 'b) multiaction ⇒ ('a, 'b) multiaction"
where "add_multiaction x (MULTIACTION xs) = MULTIACTION (add_mset x xs)"
abbreviation MAempty :: "('a, 't) multiaction" ("⟨#⟩") where
"MAempty ≡ MULTIACTION {#}"
syntax
"_multiaction" :: "args ⇒ ('a, 't) multiaction" ("⟨(_)⟩")
translations
"⟨x, xs⟩" == "CONST add_multiaction x ⟨xs⟩"
"⟨x⟩" == "CONST add_multiaction x ⟨#⟩"
value "⟨⌈''x'' [1,2,3::int]⌋, ⌈''x'' [1,2,3::int]⌋⟩"
I have to admit I am not entirely certain if I fully understood what exactly you are trying to achieve: I am providing the first idea that came to my mind based on not-very-thorough understanding of the question.
Isabelle version: Isabelle2021-RC6

How to merge set of finite maps?

I can merge two finite maps as follows:
value "fmadd
(fmap_of_list [(1::nat,2::nat)])
(fmap_of_list [(2::nat,3::nat)])"
But when I try to merge a set of maps:
value "ffold fmadd fmempty {|
fmap_of_list [(1::nat,2::nat)],
fmap_of_list [(2::nat,3::nat)]|}"
I get the following error:
Wellsortedness error:
Type nat ⇀⇩f nat not of sort finite
No type arity fmap :: finite
According to definition of fmap, it's domain is finite:
typedef ('a, 'b) fmap = "{m. finite (dom m)} :: ('a ⇀ 'b) set"
morphisms fmlookup Abs_fmap
proof
show "Map.empty ∈ {m. finite (dom m)}"
by auto
qed
But why fmap is not finite?
To answer your immediate question:
But why fmap is not finite?
Every fmap has a finite domain, but it is not necessarily the case that there are only finitely many values of type ('a, 'b) fmap. For example, there are infinitely many finitely-sized mappings from nat to nat.
The problem you're observing is deeper than that: I believe there is no proper code setup for ffold. If I try to compute
ffold funion fempty {|
fset_of_list [(1::nat,2::nat)],
fset_of_list [(2::nat,3::nat)]|}
... the error message is similar. For now, I would recommend rewriting it as fold on lists:
fold fmadd [
fmap_of_list [(1::nat,2::nat)],
fmap_of_list [(2::nat,3::nat)]] fmempty
It's not the same but it might be useful for your application.

Constraining type variables in locales

The Isabelle library contains the classes real_inner and real_normed_vector, the latter of which is declared a subclass of the former in ~~src/HOL/Library/Inner_Product.thy.
Now, suppose we have a locale
locale foo =
fixes goo :: "'a::{real_normed_vector} => bool"
and wish to extend this locale with some new constants, and also constraining the sort of 'a to be real_inner at the same time, like so:
locale extended = foo +
fixes ext :: "'a::{real_inner} => nat"
Is there a way to do this? Trying to do this using the examples above sees Isabelle give goo the type 'b::{real_normed_vector} => bool in extended, when I instead require the type 'a::{real_inner} => bool.
You can do it like this:
locale extended = foo goo
for goo :: "'a :: real_inner ⇒ bool" +
fixes ext :: "'a => nat"

Working with generic definitions in Isabelle

I am working with limits and I am unable to prove the following
definition func :: "real ⇒ real"
where "func = real"
lemma "(λh. (func (x+h))) -- 0 --> (func (x))"
unfolding func_def
apply (auto intro!: tendsto_eq_intros)
However if I replace the definition of func to
definition func :: "real ⇒ real"
where "func x = x"
the lemma is solved.
How can I solve this lemma when working with generic definitions?
I believe, here the problem is that the function real has just a generic (overloaded) syntax, i.e., real :: 'a => real, but it is not necessarily defined for all possible types 'a. This is easily seen when using find_theorems: when searching for lemmas on real :: nat => real, you get plenty of results whereas searching for real :: real => real doesn't give you a single result.
find_theorems "real :: real => real"
find_theorems "real :: nat => real"
Consequently, you can not even prove a simple lemma like func x = x, since it is not specified that real :: real => real really is the identity function.

"invalid map function" when defining a corecursive tree

I’m doing my first experiments with codatatype, but I’m stuck rather early. I started with this definition of a branching, possibly infinite tree:
codatatype (lset: 'a) ltree = Node (lnext : "'a ⇒ 'a ltree option")
and some definitions work fine:
primcorec lempty :: "'a ltree"
where "lnext lempty = (λ _ . None)"
primcorec single :: "'a ⇒ 'a ltree"
where "lnext (single x) = (λ _ . None)(x := Some lempty)"
but this does not work:
primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = (λ _ . None)(x := Some (many x))"
as I get the error message
primcorec error:
Invalid map function in "[x ↦ many x]"
I could work around it by writing
primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = (λ x'. if x' = x then Some (many x) else None)"
which makes be believe that primcorec needs to “know something about” the function update operator, similar to how fun needs fundef_cong lemmas and inductive needs mono lemmas. But what exactly?
If the codatatype recurses through other type constructors, then primcorec expects that the recursive calls are properly nested in the map functions of these type constructors. In the example, the recursion goes through the function type and the option type, whose map functions are op o and map_option. Consequently, the recursive call to many should have the form op o (map_option many). Hence, the following definition works:
primcorec many :: "'a ⇒ 'a ltree"
where "lnext (many x) = map_option many ∘ [x ↦ x]"
For convenience, primcorec supports a few more syntactic input formats. In particular, the map function for the function type can be also written using lambda abstractions. Additionally, it supports case distinctions and ifs. This is why your second version is accepted. However, when you look at the generated definition many_def, you will see that it is more complicated than with the explicit map functions.
primcorec does not suport registration of arbitrary functions, so you cannot use fun_upd in the original form. Primitive corecursion is syntactical. Maybe in the future there will be a corecursive counterpart to function.
The map functions are explained in the tutorial on datatypes and in this paper.

Resources