Theory Lifting_Definition_Option_Examples
theory Lifting_Definition_Option_Examples
imports
Main
begin
section ‹Examples›
subsection ‹A simple restricted type without type-parameters›
typedef "restricted" = "{ i :: int. i mod 2 = 0}" morphisms base "restricted"
by (intro exI[of _ 4]) auto
setup_lifting type_definition_restricted
text ‹Let us start with just using a sufficient criterion for testing for even numbers,
without actually generating them, i.e., where the generator is just the identity function.›
lift_definition(code_dt) restricted_of_simple :: "int ⇒ restricted option" is
"λ x :: int. if x ∈ {0, 2, 4, 6} then Some x else None" by auto
text ‹We can also take several input arguments for the test, and generate a more complex value.›
lift_definition(code_dt) restricted_of_many_args :: "nat ⇒ int ⇒ bool ⇒ restricted option" is
"λ x y (b :: bool). if int x + y = 5 then Some ((int x + 1) * (y + 1)) else None"
by clarsimp presburger
text ‹No problem to use type parameters.›
lift_definition(code_dt) restricted_of_poly :: "'b list ⇒ restricted option" is
"λ xs :: 'b list. if length xs = 2 then Some (int (length (xs))) else None" by auto
subsection ‹Examples with type-parameters in the restricted type.›
typedef 'f restrictedf = "{ xs :: 'f list. length xs < 3}" morphisms basef restrictedf
by (intro exI[of _ Nil]) auto
setup_lifting type_definition_restrictedf
text ‹It does not matter, if we take the same or different type-parameters in the lift-definition.›
lift_definition(code_dt) test1 :: "'g ⇒ nat ⇒ 'g restrictedf option" is
"λ (e :: 'g) x. if x < 2 then Some (replicate x e) else None" by auto
lift_definition(code_dt) test2 :: "'f ⇒ nat ⇒ 'f restrictedf option" is
"λ (e :: 'f) x. if x < 2 then Some (replicate x e) else None" by auto
text ‹Tests with multiple type-parameters.›
typedef ('a,'f) restr = "{ (xs :: 'a list,ys :: 'f list) . length xs = length ys}"
morphisms base' restr
by (rule exI[of _ "([], [])"], auto)
setup_lifting type_definition_restr
lift_definition(code_dt) restr_of_pair :: "'g ⇒ 'e list ⇒ nat ⇒ nat ⇒ ('e,nat) restr option" is
"λ (z :: 'g) (xs :: 'e list) (y :: nat) n. if length xs = n then Some (xs,replicate n y) else None"
by auto
subsection ‹Example from \isafor/\ceta›
text ‹An argument filter is a mapping @{term π} from n-ary function symbols into
lists of positions, i.e., where each position is between 0 and n-1. In \isafor,
(Isabelle's Formalization of Rewriting) and \ceta
\<^cite>‹"DBLP:conf/tphol/ThiemannS09"›, the corresponding certifier for
term rewriting related properties,
this is modelled as follows, where a partial argument filter in a map is extended to a full one
by means of an default filter.›
typedef 'f af = "{ (π :: 'f × nat ⇒ nat list). (∀ f n. set (π (f,n)) ⊆ {0 ..< n})}"
morphisms af Abs_af by (rule exI[of _ "λ _. []"], auto)
setup_lifting type_definition_af
type_synonym 'f af_impl = "(('f × nat) × nat list)list"
fun fun_of_map_fun :: "('a ⇒ 'b option) ⇒ ('a ⇒ 'b) ⇒ ('a ⇒ 'b)" where
"fun_of_map_fun m f a = (case m a of Some b ⇒ b | None ⇒ f a)"
lift_definition(code_dt) af_of :: "'f af_impl ⇒ 'f af option" is
"λ s :: 'f af_impl. if (∀ fidx ∈ set s. (∀ i ∈ set (snd fidx). i < snd (fst fidx)))
then Some (fun_of_map_fun (map_of s) (λ (f,n). [0 ..< n])) else None"
using map_of_SomeD by (fastforce split: option.splits)
subsection ‹Code generation tests and derived theorems›
export_code
restricted_of_many_args
restricted_of_simple
restricted_of_poly
test1
test2
restr_of_pair
af_of
in Haskell
lemma restricted_of_simple_Some:
"restricted_of_simple x = Some r ⟹ base r = x"
using restricted_of_simple.rep_eq[of x]
apply (split if_splits)
apply (simp_all only: option.map option.inject option.simps(3))
done
end