Я определил очень простую объектно-ориентированную модель.Модель определяет набор классов и набор ассоциаций.
nonterminal fmaplets and fmaplet
syntax
"_fmaplet" :: "['a, 'a] ⇒ fmaplet" ("_ /↦⇩f/ _")
"_fmaplets" :: "['a, 'a] ⇒ fmaplet" ("_ /[↦⇩f]/ _")
"" :: "fmaplet ⇒ fmaplets" ("_")
"_FMaplets" :: "[fmaplet, fmaplets] ⇒ fmaplets" ("_,/ _")
"_FMapUpd" :: "['a ⇀ 'b, fmaplets] ⇒ 'a ⇀ 'b" ("_/'(_')" [900, 0] 900)
"_FMap" :: "fmaplets ⇒ 'a ⇀ 'b" ("(1[_])")
syntax (ASCII)
"_fmaplet" :: "['a, 'a] ⇒ fmaplet" ("_ /|->f/ _")
"_fmaplets" :: "['a, 'a] ⇒ fmaplet" ("_ /[|->f]/ _")
translations
"_FMapUpd m (_FMaplets xy ms)" ⇌ "_FMapUpd (_FMapUpd m xy) ms"
"_FMapUpd m (_fmaplet x y)" ⇌ "CONST fmupd x y m"
"_FMap ms" ⇌ "_FMapUpd (CONST fmempty) ms"
"_FMap (_FMaplets ms1 ms2)" ↽ "_FMapUpd (_FMap ms1) ms2"
"_FMaplets ms1 (_FMaplets ms2 ms3)" ↽ "_FMaplets (_FMaplets ms1 ms2) ms3"
datatype classes1 =
Object | Person | Employee | Customer | Project | Task | Sprint
abbreviation "associations ≡ [
STR ''ProjectManager'' ↦⇩f [
STR ''projects'' ↦⇩f (Project, 0::nat, 100::nat),
STR ''manager'' ↦⇩f (Employee, 1, 1)],
STR ''ProjectMember'' ↦⇩f [
STR ''member_of'' ↦⇩f (Project, 0, 100),
STR ''members'' ↦⇩f (Employee, 1, 20)],
STR ''ManagerEmployee'' ↦⇩f [
STR ''line_manager'' ↦⇩f (Employee, 0, 1),
STR ''project_manager'' ↦⇩f (Employee, 0, 100),
STR ''employees'' ↦⇩f (Employee, 3, 7)],
STR ''ProjectCustomer'' ↦⇩f [
STR ''projects'' ↦⇩f (Project, 0, 100),
STR ''customer'' ↦⇩f (Customer, 1, 1)],
STR ''ProjectTask'' ↦⇩f [
STR ''project'' ↦⇩f (Project, 1, 1),
STR ''tasks'' ↦⇩f (Task, 0, 100)],
STR ''SprintTaskAssignee'' ↦⇩f [
STR ''sprint'' ↦⇩f (Sprint, 0, 10),
STR ''tasks'' ↦⇩f (Task, 0, 5),
STR ''assignee'' ↦⇩f (Employee, 0, 1)]]"
Я также определил предикат class_roles
, который связывает класс с набором ассоциаций и концами, доступными из этого класса:
lemma fmember_code_predI [code_pred_intro]:
"x |∈| xs" if "Predicate_Compile.contains (fset xs) x"
using that by (simp add: Predicate_Compile.contains_def fmember.rep_eq)
code_pred fmember
by (simp add: Predicate_Compile.contains_def fmember.rep_eq)
definition "assoc_end_class ≡ fst"
inductive assoc_refer_class where
"role |∈| fmdom ends ⟹
fmlookup ends role = Some end ⟹
assoc_end_class end = ? ⟹
assoc_refer_class ends ? role"
code_pred [show_modes] assoc_refer_class .
inductive class_roles where
"assoc |∈| fmdom assocs ⟹
fmlookup assocs assoc = Some ends ⟹
assoc_refer_class ends ? from ⟹
role |∈| fmdom ends ⟹
fmlookup ends role = Some end ⟹
role ≠ from ⟹
class_roles assocs ? assoc from role"
code_pred [show_modes] class_roles .
values "{(x, y, z, a). class_roles associations x y z a}"
Этот предикат может быть оценен очень быстро (см. Последнюю строку выше).
Мне нужно доказать, что все концы ассоциации уникальны для каждого класса.Для простоты я пытаюсь доказать это для Employee
класса:
lemma fmupd_to_rhs:
"fmupd k x xm = y ⟷ y = fmupd k x xm"
by auto
lemma class_roles_unique:
"class_roles associations Employee assoc1 from role ⟹
class_roles associations Employee assoc2 from role ⟹ assoc1 = assoc2"
apply (erule class_roles.cases; erule class_roles.cases;
erule assoc_refer_class.cases; erule assoc_refer_class.cases)
unfolding fmupd_to_rhs
apply (simp)
apply (elim disjE)
apply auto[1]
apply auto[1]
apply auto[1]
(* And so on... Proving of each case is very slow *)
Проблема в том, что он очень медленный.Можно ли упростить предикат class_roles
, используя леммы, сгенерированные code_pred
?Или вы могли бы предложить лучший подход, чтобы доказать эту лемму?