(* Title: HOL/Examples/Adhoc_Overloading.thy Author: Christian Sternagel *)
section‹Ad Hoc Overloading›
theory Adhoc_Overloading imports
Main "HOL-Library.Infinite_Set" begin
text‹Adhoc overloading allows to overload a constant depending on its type. Typically this involves to introduce an uninterpreted constant (used for input and output) and then add some variants (used internally).›
subsection‹Plain Ad Hoc Overloading›
text‹Consider the type of first-order terms.› datatype ('a, 'b) "term" =
Var 'b | Fun 'a "('a, 'b) term list"
text‹The set of variables of a term might be computed as follows.› fun term_vars :: "('a, 'b) term ==> 'b set"where "term_vars (Var x) = {x}" | "term_vars (Fun f ts) = ∪(set (map term_vars ts))"
text‹However, also for \emph{rules} (i.e., pairs of terms) and term rewrite systems (i.e., sets of rules), the set of variables makes sense. Thus we introduce an unspecified constant ‹vars›.›
consts vars :: "'a ==> 'b set"
text‹Which is then overloaded with variants for terms, rules, and TRSs.›
adhoc_overloading
vars ⇌ term_vars
value [nbe] "vars (Fun ''f'' [Var 0, Var 1])"
fun rule_vars :: "('a, 'b) term × ('a, 'b) term ==> 'b set"where "rule_vars (l, r) = vars l ∪ vars r"
adhoc_overloading
vars ⇌ rule_vars
value [nbe] "vars (Var 1, Var 0)"
definition trs_vars :: "(('a, 'b) term × ('a, 'b) term) set ==> 'b set"where "trs_vars R = ∪(rule_vars ` R)"
adhoc_overloading
vars ⇌ trs_vars
value [nbe] "vars {(Var 1, Var 0)}"
text‹Sometimes it is necessary to add explicit type constraints before a variant can be determined.› (*value "vars R" (*has multiple instances*)*) value"vars (R :: (('a, 'b) term × ('a, 'b) term) set)"
text‹It is also possible to remove variants.›
no_adhoc_overloading
vars ⇌ term_vars rule_vars
(*value "vars (Var 1)" (*does not have an instance*)*)
text‹As stated earlier, the overloaded constant is only used for input and output. Internally, always a variant is used, as can be observed by the configuration option ‹show_variants›.\
text‹As example we use permutations that are parametrized over an atom type 🍋‹'a›.\
definition perms :: "('a ==> 'a) set"where "perms = {f. bij f ∧ finite {x. f x ≠ x}}"
typedef 'a perm = "perms :: ('a ==> 'a) set" by standard (auto simp: perms_def)
text‹First we need some auxiliary lemmas.› lemma permsI [Pure.intro]: assumes"bij f"and"MOST x. f x = x" shows"f ∈ perms" using assms by (auto simp: perms_def) (metis MOST_iff_finiteNeg)
lemma perms_imp_bij: "f ∈ perms ==> bij f" by (simp add: perms_def)
lemma perms_imp_MOST_eq: "f ∈ perms ==> MOST x. f x = x" by (simp add: perms_def) (metis MOST_iff_finiteNeg)
text‹Then we add a locale for types 🍋‹'b› that support
appliciation of permutations.› locale permute = fixes permute :: "'a perm ==> 'b ==> 'b" assumes permute_zero [simp]: "permute 0 x = x" and permute_plus [simp]: "permute (p + q) x = permute p (permute q x)" begin
adhoc_overloading
PERMUTE ⇌ permute
end
text‹Permuting atoms.› definition permute_atom :: "'a perm ==> 'a ==> 'a"where "permute_atom p a = (Rep_perm p) a"
adhoc_overloading
PERMUTE ⇌ permute_atom
interpretation atom_permute: permute permute_atom by standard (simp_all add: permute_atom_def Rep_perm_simps)
text‹Permuting permutations.› definition permute_perm :: "'a perm ==> 'a perm ==> 'a perm"where "permute_perm p q = p + q - p"
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.