Theory Relations

section‹Predicates and relations›

theory Relations
imports Var
begin
default_sort type

text ‹Unifying Theories of Programming (UTP) is a semantic framework based on 
an alphabetized relational calculus. An alphabetized predicate is a pair (alphabet, predicate) 
where the free variables appearing in the predicate are all in the alphabet.›

text ‹An alphabetized relation is an alphabetized predicate where the alphabet is
composed of input (undecorated) and output (dashed) variables. In this case the
predicate describes a relation between input and output variables.›

subsection‹Definitions›

text ‹In this section, the definitions of predicates, relations and 
standard operators are given.›

type_synonym  "alphabet"  = ""
type_synonym  predicate = " alphabet  bool"

definition  true::" predicate"
where "true  λA. True"

definition  false::" predicate"
where "false  λA. False"

definition  not::" predicate   predicate" ("¬ _" [40] 40)
where "¬ P   λA. ¬ (P A)"

definition  conj::" predicate   predicate   predicate" (infixr "" 35)
where "P  Q  λA. P A  Q A"

definition disj::" predicate   predicate   predicate" (infixr "" 30)
where "P  Q  λA. P A  Q A"

definition impl::" predicate   predicate   predicate" (infixr "" 25)
where "P  Q  λA. P A  Q A"

definition iff::" predicate   predicate   predicate" (infixr "" 25)
where "P  Q  λA. P A  Q A"

definition ex::"[  predicate]   predicate" (binder "" 10)
where "x. P x  λA.  x. (P x) A"

definition all::"[  predicate]   predicate" (binder "" 10)
where "x. P x  λ A. x. (P x) A"

type_synonym  condition = "( × )  bool"
type_synonym  relation  = "( × )  bool"

definition cond::" relation   condition   relation   relation" 
                                                          ("(3_  _  / _)" [14,0,15] 14)
where " (P  b  Q)  (b  P)  ((¬ b)  Q)"

definition comp::"(( × )  bool)  (( × )  bool)  ( × )  bool" 
                                                                          (infixr ";;" 25)
where "P ;; Q  λr. r : ({p. P p} O {q. Q q})"

definition Assign::"('a, 'b) var  'a  'b relation" 
  where "Assign x a  λ(A, A'). A' = (assign x a) A"

syntax
  "_assignment" :: "id  'a  'b relation"  ("_ :== _")
translations
  "y :== vv"   => "CONST Assign (VAR y) vv"

abbreviation (input) closure::" predicate  bool" ("[_]")
where "[ P ]   A. P A"

abbreviation (input) ndet::" relation   relation   relation" ("(_  _)")
where "P  Q  P  Q"

abbreviation (input) join::" relation   relation   relation" ("(_  _)")
where "P  Q  P  Q"

abbreviation (input) ndetS::" relation set   relation" ("( _)")
where " S  λA. A  {{p. P p} | P. P  S}"

abbreviation (input) conjS::" relation set   relation" ("( _)")
where " S  λA. A  {{p. P p} | P. P  S}"

abbreviation (input) skip_r::" relation" ("Πr")
where "Πr  λ (A, A') . A = A'"

abbreviation (input) Bot::" relation"
where "Bot  true"

abbreviation (input) Top::" relation"
where "Top  false"


lemmas utp_defs = true_def false_def conj_def disj_def not_def impl_def iff_def
                  ex_def all_def cond_def comp_def Assign_def


subsection ‹Proofs›


text ‹All useful proved lemmas over predicates and relations are presented here.
First, we introduce the most important lemmas that will be used by automatic tools to simplify
proofs. In the second part, other lemmas are proved using these basic ones.›


subsubsection ‹Setup of automated tools›

lemma true_intro: "true x" by (simp add: utp_defs)
lemma false_elim: "false x  C" by (simp add: utp_defs)
lemma true_elim: "true x  C  C" by (simp add: utp_defs)

lemma not_intro: "(P x  false x)  (¬ P) x" by (auto simp add: utp_defs)
lemma not_elim: "(¬ P) x  P x  C" by (auto simp add: utp_defs)
lemma not_dest: "(¬ P) x  ¬ P x" by (auto simp add: utp_defs)

lemma conj_intro: "P x  Q x  (P  Q) x" by (auto simp add: utp_defs)
lemma conj_elim: "(P  Q) x  (P x  Q x  C)  C" by (auto simp add: utp_defs)

lemma disj_introC: "(¬ Q x  P x)  (P  Q) x" by (auto simp add: utp_defs)
lemma disj_elim: "(P  Q) x  (P x  C)  (Q x  C)  C" by (auto simp add: utp_defs)

lemma impl_intro: "(P x  Q x)  (P  Q) x" by (auto simp add: utp_defs)
lemma impl_elimC: "(P  Q) x  (¬ P x  R)  (Q x  R)  R " by (auto simp add: utp_defs)

lemma iff_intro: "(P x  Q x)  (Q x  P x)  (P  Q) x" by (auto simp add: utp_defs)
lemma iff_elimC: 
"(P  Q) x  (P x  Q x  R)  (¬ P x  ¬ Q x  R)  R" by (auto simp add: utp_defs)

lemma all_intro: "(a. P a x)  (a. P a) x" by (auto simp add: utp_defs)
lemma all_elim: "(a. P a) x  (P a x  R)  R" by (auto simp add: utp_defs)

lemma ex_intro: "P a x  (a. P a) x" by (auto simp add: utp_defs)
lemma ex_elim: "(a. P a) x  (a. P a x  Q)  Q" by (auto simp add: utp_defs)

lemma comp_intro: "P (a, b)  Q (b, c)  (P ;; Q) (a, c)"
  by (auto simp add: comp_def)

lemma comp_elim: 
"(P ;; Q) ac  (a b c. ac = (a, c)  P (a, b)  Q (b, c)  C)  C"
  by (auto simp add: comp_def)

declare not_def [simp]

declare iff_intro [intro!]
  and not_intro [intro!]
  and impl_intro [intro!]
  and disj_introC [intro!]
  and conj_intro [intro!]
  and true_intro [intro!]
  and comp_intro [intro]

declare not_dest [dest!]
  and iff_elimC [elim!]
  and false_elim [elim!]
  and impl_elimC [elim!]
  and disj_elim [elim!]
  and conj_elim [elim!]
  and comp_elim [elim!]
  and true_elim [elim!]

declare all_intro [intro!] and ex_intro [intro]
declare ex_elim [elim!] and all_elim [elim]

lemmas relation_rules = iff_intro not_intro impl_intro disj_introC conj_intro true_intro
                        comp_intro not_dest iff_elimC false_elim impl_elimC all_elim
                        disj_elim conj_elim comp_elim all_intro ex_intro ex_elim 
                        


lemma split_cond: 
"A ((P  b  Q) x) = ((b x  A (P x))  (¬ b x  A (Q x)))"
  by (cases "b x") (auto simp add: utp_defs)

lemma split_cond_asm: 
"A ((P  b  Q) x) = (¬ ((b x  ¬ A (P x))  (¬ b x  ¬ A (Q x))))"
  by (cases "b x") (auto simp add: utp_defs)

lemmas cond_splits = split_cond split_cond_asm


subsubsection ‹Misc lemmas›

lemma cond_idem:"(P  b  P) = P"
  by (rule ext) (auto split: cond_splits)

lemma cond_symm:"(P  b  Q) = (Q  ¬ b  P)"
  by (rule ext) (auto split: cond_splits)

lemma cond_assoc: "((P  b  Q)  c  R) = (P  b  c  (Q  c  R))"
  by (rule ext) (auto split: cond_splits)

lemma cond_distr: "(P  b  (Q  c  R)) = ((P  b  Q)  c  (P  b  R))"
  by (rule ext) (auto split: cond_splits)

lemma cond_unit_T:"(P  true  Q) = P"
  by (rule ext) (auto split: cond_splits)

lemma cond_unit_F:"(P  false  Q) = Q"
  by (rule ext) (auto split: cond_splits)

lemma cond_L6: "(P  b  (Q  b  R)) = (P  b  R)"
  by (rule ext) (auto split: cond_splits)

lemma cond_L7: "(P  b  (P  c  Q)) = (P  b  c  Q)"
  by (rule ext) (auto split: cond_splits)

lemma cond_and_distr: "((P  Q)  b  (R  S)) = ((P  b  R)  (Q  b  S))"
  by (rule ext) (auto split: cond_splits)

lemma cond_or_distr: "((P  Q)  b  (R  S)) = ((P  b  R)  (Q  b  S))"
  by (rule ext) (auto split: cond_splits)

lemma cond_imp_distr: 
"((P  Q)  b  (R  S)) = ((P  b  R)  (Q  b  S))"
  by (rule ext) (auto split: cond_splits)

lemma cond_eq_distr: 
"((P  Q)  b  (R  S)) = ((P  b  R)  (Q  b  S))"
  by (rule ext) (auto split: cond_splits)

lemma comp_assoc: "(P ;; (Q ;; R)) = ((P ;; Q) ;; R)"
  by (rule ext) blast

lemma conj_comp: 
"( a b c. P (a, b) = P (a, c))  (P  (Q ;; R)) = ((P  Q) ;; R)"
  by (rule ext) blast

lemma comp_cond_left_distr:
  assumes "x y z. b (x, y) = b (x, z)"
  shows "((P  b  Q) ;; R) = ((P ;; R)  b  (Q ;; R))"
  using assms by (auto simp: fun_eq_iff utp_defs)

lemma ndet_symm: "(P::'a relation)  Q = Q  P"
  by (rule ext) blast

lemma ndet_assoc: "P  (Q  R) = (P  Q)  R"
  by (rule ext) blast

lemma ndet_idemp: "P  P = P"
  by (rule ext) blast

lemma ndet_distr: "P  (Q  R) = (P  Q)  (P  R)"
  by (rule ext) blast

lemma cond_ndet_distr: "(P  b  (Q  R)) = ((P  b  Q)  (P  b  R))"
  by (rule ext) (auto split: cond_splits)

lemma ndet_cond_distr: "(P  (Q  b  R)) = ((P  Q)  b  (P  R))"
  by (rule ext) (auto split: cond_splits)

lemma comp_ndet_l_distr: "((P  Q) ;; R) = ((P ;; R)  (Q ;; R))"
  by (auto simp: fun_eq_iff utp_defs)

lemma comp_ndet_r_distr: "(P ;; (Q  R)) = ((P ;; Q)  (P ;; R))"
  by (auto simp: fun_eq_iff utp_defs)

lemma l2_5_1_A: "X  S. [X  ( S)]"
  by blast

lemma l2_5_1_B: "( X  S. [X  P])  [( S)  P]"
  by blast

lemma l2_5_1: "[( S)  P]  ( X  S. [X  P])"
  by blast

lemma empty_disj: " {} = Top"
  by (rule ext) blast

lemma l2_5_1_2: "[P  ( S)]  ( X  S. [P  X])"
  by blast

lemma empty_conj: " {} = Bot"
  by (rule ext) blast

lemma l2_5_2: "(( S)  Q) = ({P  Q | P. PS})"
  by (rule ext) blast

lemma l2_5_3: "(( S)  Q) = ({P  Q | P. P  S})"
  by (rule ext) blast

lemma l2_5_4: "(( S) ;; Q) = ({P ;; Q | P. P  S})"
  by (rule ext) blast

lemma l2_5_5: "(Q ;; ( S)) = ({Q ;; P | P. P  S})"
  by (rule ext) blast

lemma all_idem :"(b. a. P a) = (a. P a)"
  by (simp add: all_def)

lemma comp_unit_R [simp]: "(P ;; Πr) = P"
  by (auto simp: fun_eq_iff utp_defs)

lemma comp_unit_L [simp]: "(Πr ;; P) = P"
  by (auto simp: fun_eq_iff utp_defs)

lemmas comp_unit_simps = comp_unit_R comp_unit_L

lemma not_cond: "(¬(P  b  Q)) = ((¬ P)  b  (¬ Q))"
  by (rule ext) (auto split: cond_splits)

lemma cond_conj_not_distr: 
"((P  b  Q)  ¬(R  b  S)) = ((P  ¬R)  b  (Q  ¬S))"
  by (rule ext) (auto split: cond_splits)

lemma imp_cond_distr: "(R  (P  b  Q)) = ((R  P)  b  (R  Q))"
  by (rule ext) (auto split: cond_splits)

lemma cond_imp_dist: "((P  b  Q)  R) = ((P  R)  b  (Q  R))"
  by (rule ext) (auto split: cond_splits)

lemma cond_conj_distr: "((P  b  Q)  R) = ((P  R)  b  (Q  R))"
  by (rule ext) (auto split: cond_splits)

lemma cond_disj_distr: "((P  b  Q)  R) = ((P  R)  b  (Q  R))"
  by (rule ext) (auto split: cond_splits)

lemma cond_know_b: "(b  (P  b  Q)) = (b  P)"
  by (rule ext) (auto split: cond_splits)

lemma cond_know_nb: "((¬ (b))  (P  b  Q)) = ((¬ (b))  Q)"
  by (rule ext) (auto split: cond_splits)

lemma cond_ass_if: "(P  b  Q) = (((b)  P  b  Q))"
  by (rule ext) (auto split: cond_splits)

lemma cond_ass_else: "(P  b  Q) = (P  b  ((¬b)  Q))"
  by (rule ext) (auto split: cond_splits)

lemma not_true_eq_false: "(¬ true) = false"
  by (rule ext) blast

lemma not_false_eq_true: "(¬ false) = true"
  by (rule ext) blast

lemma conj_idem: "((P:: predicate)  P) = P"
  by (rule ext) blast

lemma disj_idem: "((P:: predicate)  P) = P"
  by (rule ext) blast

lemma conj_comm: "((P:: predicate)  Q) = (Q  P)"
  by (rule ext) blast

lemma disj_comm: "((P:: predicate)  Q) = (Q  P)"
  by (rule ext) blast

lemma conj_subst: "P = R  ((P:: predicate)  Q) = (R  Q)"
  by (rule ext) blast

lemma disj_subst: "P = R  ((P:: predicate)  Q) = (R  Q)"
  by (rule ext) blast

lemma conj_assoc:"(((P:: predicate)  Q)  S) = (P  (Q  S))"
  by (rule ext) blast

lemma disj_assoc:"(((P:: predicate)  Q)  S) = (P  (Q  S))"
  by (rule ext) blast

lemma conj_disj_abs:"((P:: predicate)  (P  Q)) = P"
  by (rule ext) blast

lemma disj_conj_abs:"((P:: predicate)  (P  Q)) = P"
  by (rule ext) blast

lemma conj_disj_distr:"((P:: predicate)  (Q  R)) = ((P  Q)  (P  R))"
  by (rule ext) blast

lemma disj_conj_dsitr:"((P:: predicate)  (Q  R)) = ((P  Q)  (P  R))"
  by (rule ext) blast

lemma true_conj_id:"(P  true) = P"
  by (rule ext) blast

lemma true_dsij_zero:"(P  true) = true"
  by (rule ext) blast

lemma true_conj_zero:"(P  false) = false"
  by (rule ext) blast

lemma true_dsij_id:"(P  false) = P"
  by (rule ext) blast

lemma imp_vacuous: "(false  u) = true"
  by (rule ext) blast

lemma p_and_not_p: "(P  ¬ P) = false"
  by (rule ext) blast

lemma conj_disj_not_abs: "((P:: predicate)  ((¬P)  Q)) = (P  Q)"
  by (rule ext) blast

lemma p_or_not_p: "(P  ¬ P) = true"
  by (rule ext) blast

lemma double_negation: "(¬ ¬ (P:: predicate)) = P"
  by (rule ext) blast

lemma not_conj_deMorgans: "(¬ ((P:: predicate)  Q)) = ((¬ P)  (¬ Q))"
  by (rule ext) blast

lemma not_disj_deMorgans: "(¬ ((P:: predicate)  Q)) = ((¬ P)  (¬ Q))"
  by (rule ext) blast

lemma p_imp_p: "(P  P) = true"
  by (rule ext) blast

lemma imp_imp: "((P:: predicate)  (Q  R)) = ((P  Q)  R)"
  by (rule ext) blast

lemma imp_trans: "((P  Q)  (Q  R)  P  R) = true"
  by (rule ext) blast

lemma p_equiv_p: "(P  P) = true"
  by (rule ext) blast

lemma equiv_eq: "((((P:: predicate)  Q)  (¬P  ¬Q)) = true)  (P = Q)"
  by (auto simp add: fun_eq_iff utp_defs)

lemma equiv_eq1: "(((P:: predicate)  Q) = true)  (P = Q)"
  by (auto simp add: fun_eq_iff utp_defs)

lemma cond_subst: "b = c  (P  b  Q) = (P  c  Q)"
  by simp

lemma ex_disj_distr: "((x. P x)  (x. Q x)) = (x. (P x  Q x))"
  by (rule ext) blast

lemma all_disj_distr: "((x. P x)  (x. Q)) = (x. (P x  Q))"
  by (rule ext) blast

lemma all_conj_distr: "((x. P x)  (x. Q x)) = (x. (P x  Q x))"
  by (rule ext) blast

lemma all_triv: "(x. P) = P"
  by (rule ext) blast

lemma closure_true: "[true]"
  by blast

lemma closure_p_eq_true: "[P]  (P = true)"
  by (simp add: fun_eq_iff utp_defs)

lemma closure_equiv_eq: "[P  Q]  (P = Q)"
  by (simp add: fun_eq_iff utp_defs)

lemma closure_conj_distr: "([P]  [Q]) = [P  Q]"
  by blast

lemma closure_imp_distr: "[P  Q]  [P]  [Q]"
  by blast

lemma true_iff[simp]: "(P  true) = P"
  by blast

lemma true_imp[simp]: "(true  P) = P"
  by blast

end