Isabelle instantiation with type parameter - isabelle

I'm trying to get this to work
no_notation Nil ("[]") and Cons (infixr "#" 65) and append (infixr "#" 65) and plus (infixl "+" 65)
class plus =
fixes plus :: "'a ⇒ 'a ⇒ 'a" (infixl "+" 65)
datatype 'a list =
Nil ("[]")
| Cons 'a "'a list" (infixr "#" 65)
instantiation "'a list" :: plus
begin
primrec plus_list :: "'a list ⇒ 'a list ⇒ 'a list" where
"plus_list [] ys = ys" |
"plus_list (x#xs) ys = x # (plus_list xs ys)"
instance ..
end
essentially lists are free monoids under concatenation. How do I express this fact using type-classes?
At the moment I get
Undefined type name: "'a list"⌂
in this line
instantiation "'a list" :: plus
^^^^^^^^^
If I get rid of 'a I get
Bad number of arguments for type constructor: "Test.list"
Even if I try to specialize to nat list I get
Undefined type name: "nat list"⌂
I can see here
https://isabelle.in.tum.de/doc/classes.pdf
that it is possible. However, the notation used in this pdf is strange. I can't reproduce any of the examples provided. For instance this
class eq where
eq :: α ⇒ α ⇒ bool
I suppose it's meant to be something like
class eq where
eq :: "'a ⇒ 'a ⇒ bool"
but when I paste it to jEdit I get syntax error. Other Isabelle tutorials use a different notation, like
class eq =
fixes eq :: "'a ⇒ 'a ⇒ bool"
This pdf also provides example
instance (α::eq, β::eq) pair :: eq where
eq (x1, y1) (x2, y2) = eq x1 x2 ∧ eq y1 y2
which looks like what I am looking for. An instance of a higher-order type.

no_notation Nil ("[]") and Cons (infixr "#" 65) and append (infixr "#" 65) and plus (infixl "+" 65)
class plus =
fixes plus :: "'a ⇒ 'a ⇒ 'a" (infixl "+" 65)
datatype 'a list =
Nil ("[]")
| Cons 'a "'a list" (infixr "#" 65)
instantiation list :: (type) plus
begin
primrec plus_list :: "'a list ⇒ 'a list ⇒ 'a list" where
"plus_list [] ys = ys" |
"plus_list (x#xs) ys = x # (plus_list xs ys)"
instance ..
end

Related

What is INF in Isabelle

I found this definition in Isabelle
definition (in topological_space) nhds :: "'a ⇒ 'a filter"
where "nhds a = (INF S∈{S. open S ∧ a ∈ S}. principal S)"
What is INF? I can't find anything in query tab nor can I jump to definition with Ctrl+Click.
You already answered the question yourself: INF x∈A. f x is simply the infimum of f(x) ranging over all x ∈ A.
But let me explain as well what it means in this particular context: principal S is the filter for which eventually P (principal S) simply means that P holds on all values in the set S.
We now take the infimum of that over all the open sets that contain a certain point x. This then gives us a filter where eventually P (nhds x) means that there exists an open set that contains x and on which this property holds. In other words: P holds for any point sufficiently close to x (including x itself).
It is infimum of complete lattice
class Inf =
fixes Inf :: "'a set ⇒ 'a" ("⨅ _" [900] 900)
This syntax is declared as
syntax
"_INF1" :: "pttrns ⇒ 'b ⇒ 'b" ("(3INF _./ _)" [0, 10] 10)
"_INF" :: "pttrn ⇒ 'a set ⇒ 'b ⇒ 'b" ("(3INF _∈_./ _)" [0, 0, 10] 10)
"_SUP1" :: "pttrns ⇒ 'b ⇒ 'b" ("(3SUP _./ _)" [0, 10] 10)
"_SUP" :: "pttrn ⇒ 'a set ⇒ 'b ⇒ 'b" ("(3SUP _∈_./ _)" [0, 0, 10] 10)
syntax
"_INF1" :: "pttrns ⇒ 'b ⇒ 'b" ("(3⨅_./ _)" [0, 10] 10)
"_INF" :: "pttrn ⇒ 'a set ⇒ 'b ⇒ 'b" ("(3⨅_∈_./ _)" [0, 0, 10] 10)
"_SUP1" :: "pttrns ⇒ 'b ⇒ 'b" ("(3⨆_./ _)" [0, 10] 10)
"_SUP" :: "pttrn ⇒ 'a set ⇒ 'b ⇒ 'b" ("(3⨆_∈_./ _)" [0, 0, 10] 10)
It's in Complete_Lattices.thy (https://isabelle.in.tum.de/library/HOL/HOL/outline.pdf) under section "Syntactic infimum and supremum operations" .

Isabelle: How can I use solver this error?

**I'm using isabelle to proof security boot of device. lemma AF1_aux fail to pass the proof.
When I change if event_enabled s be to if false, it pass. I can't move forward.
Any guidance would be very helpful!
Here is the simple code**
section ‹boot security›
theory boot_sec
imports Main
begin
locale M_HLR =
(* declare the initial state *)
fixes Initial_State :: 's
(* next state function *)
fixes next_state :: "'s ⇒ 'be ⇒ 's"
(* Auxiliary function for present Stable State *)
fixes success :: "'s ⇒ bool"
(* Security Requirements *)
assumes AF1: "∃s. ∀b. next_state s b = s"
datatype Status = INIT | READ_ROM | END
record State =
status :: Status
datatype Behavior = Read_ROM |
Gen_SessionKey
definition read_rom :: "State ⇒ State" where
"read_rom s ≡ s ⦇status := READ_ROM ⦈"
definition gen_sessionkey :: "State ⇒ State" where
"gen_sessionkey s ≡ s ⦇status := END ⦈"
definition event_enabled :: "State ⇒ Behavior ⇒ bool" where
"event_enabled s be ≡ if status s = END then False else True"
definition exec_be :: "State ⇒ Behavior ⇒ State" where
"exec_be s be ≡
if event_enabled s be
then
( case be of
Read_ROM ⇒ read_rom s |
Gen_SessionKey ⇒ gen_sessionkey s )
else s"
lemma AF1_aux: "status s = END ⟹ ∀be. exec_be s be = s"
by(simp add: exec_be_def)
theorem AF1: "∃s. ∀be. exec_be s be = s"
by (meson AF1_aux State.select_convs(1))
end
The output is
theorem AF1_aux: status ?s = END ⟹ ∀be. exec_be ?s be = ?s
Failed to finish proof⌂:
goal (1 subgoal):
1. status s = END ⟹ ∀be. event_enabled s be ⟶ (case be of Read_ROM ⇒ read_rom s | Gen_SessionKey ⇒ gen_sessionkey s) = s

Can I construct a while structure algebraically using class and locale?

I am constructing program statements from algebraic structures, rather than using definitions or functions.That is to set their properties in Isabelle using locale or class commands.
Now I need to construct a while statement.
I know I can define it in command of functions, or I can define it using kleene algebra. But, as I said before, I just want to describe the nature of a class or locale.
So I wrote this code:
consts skip :: "'a" ("II")
type_synonym 'a proc = "'a "
class sequen =
fixes seq :: "'a proc ⇒'a proc ⇒'a proc " (infixl ";;" 60)
assumes seq_assoc : "(x ;; y) ;; z = x ;; (y ;; z)"
and seq_skip_left : "II ;; x = x"
and seq_skip_right : "x ;; II = x"
definition ifprog :: " 'a proc ⇒ bool ⇒ 'a proc ⇒ 'a proc " ("(_ ◃ _ ▹ _)" [52,0,53] 52)
where "x ◃ bexp ▹ y ≡ (THE z::'a proc . (bexp = True ⟶ z = x) ∧ (bexp = False ⟶ z = y))"
locale while_unfold =
sequen seq
for seq :: "'a proc ⇒'a proc ⇒'a proc " +
fixes while ::"bool ⇒ 'a proc ⇒ 'a proc" ("while _ do _ od")
assumes while_ltera : "while bexp do P od = (P ;; (while bexp do P od)) ◃ bexp ▹ II"
If that were possible, I wouldn't be asking questions here, I've got a problem :
Type unification failed: Variable 'a::type not of sort sequen
And then, these details are:
Type unification failed: Variable 'a::type not of sort sequen
Type error in application: incompatible operand type
Operator: (;;) :: ??'a ⇒ ??'a ⇒ ??'a
Operand: P :: 'a
How can I avoid this problem, or can this descriptive method be used to construct statements that have an iterative function, such as while.
I have not looked at the content of the class/locale, but the error message seems to be self-explanatory: type unification failed due to an incompatible sort constraint for the type variable 'a. Unless you rely on type inference, the sort constraint needs to be provided explicitly:
consts skip :: "'a" ("II")
type_synonym 'a proc = "'a "
class sequen =
fixes seq :: "'a proc ⇒'a proc ⇒'a proc " (infixl ";;" 60)
assumes seq_assoc : "(x ;; y) ;; z = x ;; (y ;; z)"
and seq_skip_left : "II ;; x = x"
and seq_skip_right : "x ;; II = x"
(*sequen_class.seq has the type
"'a::sequen ⇒ 'a::sequen ⇒ 'a::sequen",
which includes the sort constraint sequen for the type variable 'a:*)
declare [[show_sorts]]
term sequen_class.seq
definition ifprog :: " 'a proc ⇒ bool ⇒ 'a proc ⇒ 'a proc " ("(_ ◃ _ ▹ _)" [52,0,53] 52)
where "x ◃ bexp ▹ y ≡ (THE z::'a proc . (bexp = True ⟶ z = x) ∧ (bexp = False ⟶ z = y))"
(*note the sort constraint*)
locale while_unfold =
sequen seq
for seq :: "'a::sequen proc ⇒'a proc ⇒'a proc " +
fixes while ::"bool ⇒ 'a proc ⇒ 'a proc" ("while _ do _ od")
assumes while_ltera : "while bexp do P od = (P ;; (while bexp do P od)) ◃ bexp ▹ II"
(*alternatively, consider using a class instead of a locale, although,
most certainly, the best choice depends on your application*)
class while_unfold' =
sequen +
fixes while ::"bool ⇒ 'a proc ⇒ 'a proc" ("while _ do _ od")
assumes while_ltera : "while bexp do P od = (P ;; (while bexp do P od)) ◃ bexp ▹ II"
For more information about classes and sort constraints see sections 3.3.6 and 5.8 in the Isabelle/Isar Reference Manual. You can also take a look at section 2 in the The Isabelle/Isar Implementation.
Isabelle version: Isabelle2020

How to define an abstract collection data type?

There are 4 kinds of collections in my theory. For each collection type I defined count and for_all operations:
theory MyCollections
imports Main
"~~/src/HOL/Library/Dlist"
"~~/src/HOL/Library/Multiset"
begin
typedef 'a mybag = "UNIV :: 'a multiset set" .. (* not unique, not ordered *)
typedef 'a myseq = "UNIV :: 'a list set" .. (* not unique, ordered *)
typedef 'a myset = "UNIV :: 'a set set" .. (* unique, not ordered *)
typedef 'a myord = "UNIV :: 'a dlist set" .. (* unique, ordered *)
setup_lifting type_definition_mybag
setup_lifting type_definition_myseq
setup_lifting type_definition_myset
setup_lifting type_definition_myord
lift_definition mybag_count :: "'a mybag ⇒ 'a ⇒ nat" is "Multiset.count" .
lift_definition myseq_count :: "'a myseq ⇒ 'a ⇒ nat" is "count_list" .
lift_definition myset_count :: "'a myset ⇒ 'a ⇒ nat" is "(λxs x. if x ∈ xs then 1 else 0)" .
lift_definition myord_count :: "'a myord ⇒ 'a ⇒ nat" is "(λxs x. if Dlist.member xs x then 1 else 0)" .
lift_definition mybag_for_all :: "'a mybag ⇒ ('a ⇒ bool) ⇒ bool" is "Multiset.Ball" .
lift_definition myseq_for_all :: "'a myseq ⇒ ('a ⇒ bool) ⇒ bool" is "(λxs f. list_all f xs)" .
lift_definition myset_for_all :: "'a myset ⇒ ('a ⇒ bool) ⇒ bool" is "Ball" .
lift_definition myord_for_all :: "'a myord ⇒ ('a ⇒ bool) ⇒ bool" is "(λxs f. list_all f (list_of_dlist xs))" .
I need to define polymorphic operations (includes and includes_all) for these collection types:
lift_definition mybag_includes :: "'a mybag ⇒ 'a ⇒ bool" is
"(λxs x. mybag_count xs x > 0)" .
lift_definition myseq_includes :: "'a myseq ⇒ 'a ⇒ bool" is
"(λxs x. myseq_count xs x > 0)" .
lift_definition myset_includes :: "'a myset ⇒ 'a ⇒ bool" is
"(λxs x. myset_count xs x > 0)" .
lift_definition myord_includes :: "'a myord ⇒ 'a ⇒ bool" is
"(λxs x. myord_count xs x > 0)" .
lift_definition mybag_mybag_includes_all :: "'a mybag ⇒ 'a mybag ⇒ bool" is
"(λxs ys. mybag_for_all ys (mybag_includes xs))" .
lift_definition mybag_myseq_includes_all :: "'a mybag ⇒ 'a myseq ⇒ bool" is
"(λxs ys. myseq_for_all ys (mybag_includes xs))" .
(* ... and 14 more similar operations for other type combinations *)
Some test cases:
value "mybag_myseq_includes_all (Abs_mybag {#1::nat,2,4,5,3,4#}) (Abs_myseq [1::nat,2])"
value "mybag_myseq_includes_all (Abs_mybag {#1::nat,2,4,5,3,4#}) (Abs_myseq [1::nat,7])"
The problem is that these operations are structurally identical and I don't want to duplicate them. I try to define an abstract collection type:
typedecl 'a mycol
consts
mycol_count :: "'a mycol ⇒ 'a ⇒ nat"
mycol_for_all :: "'a mycol ⇒ ('a ⇒ bool) ⇒ bool"
definition mycol_includes :: "'a mycol ⇒ 'a ⇒ bool" where
"mycol_includes xs x ≡ mycol_count xs x > 0"
definition mycol_includes_all :: "'a mycol ⇒ 'a mycol ⇒ bool" where
"mycol_includes_all xs ys ≡ mycol_for_all xs (mycol_includes ys)"
But I have no idea how to derive concrete collection types from the abstract one:
typedef 'a mybag = "{xs :: 'a mycol. ???}" ..
typedef 'a myseq = "{xs :: 'a mycol. ???}" ..
typedef 'a myset = "{xs :: 'a mycol. ???}" ..
typedef 'a myord = "{xs :: 'a mycol. ???}" ..
Once you have axiomatized the abstract collections type, you cannot refine it inside the logic any more. So the proposed approach does not work. But if you leave the container type abstract (as a type variable), then this is possible. I recommend to do that using locales:
locale container =
fixes count :: "'container => 'a => nat"
and for_all :: "'container => ('a => bool) => bool"
begin
definition "includes" where "includes C x <--> count C x > 0"
definition includes_all where "includes_all C C' <--> for_all C (includes C')"
end
Then, you can define your different collection types as usual and obtain the common operations by locale interpretation. For example,
interpretation mybag: container mybag_count mybag_forall .
generates the abbreviations mybag.includes and mybag.includes_all. Additionally, all theorems that are proven in the locale container are also specialized to mybag and prefixed with mybag.

How to invoke functions in Isabelle/HOL?

Here is a theory I've taken from Isabelle Tutorial. It has ways to prove theorems but I was wondering how one would call the app function below with two lists.
theory ToyList
imports Main
begin
datatype 'a list = Nil | Cons 'a "'a list"
fun app :: "'a list ⇒ 'a list ⇒ 'a list" where
"app Nil ys = ys" |
"app (Cons x xs) ys = Cons x (app xs ys)"
I tried theorem app_test[simp] : "app (xs # ys ) # zs = xs # ys # zs" and other ways but didn't work.

Resources