Theory utp_usedby

section ‹ Used-by ›

theory utp_usedby
  imports utp_unrest
begin

text ‹ The used-by predicate is the dual of unrestriction. It states that the given lens is an 
  upper-bound on the size of state space the given expression depends on. It is similar to stating
  that the lens is a valid alphabet for the predicate. For convenience, and because the predicate
  uses a similar form, we will reuse much of unrestriction's infrastructure. ›
  
consts
  usedBy :: "'a  'b  bool"

syntax
  "_usedBy" :: "salpha  logic  logic  logic" (infix  20)

syntax_consts
  "_usedBy" == usedBy

translations
  "_usedBy x p" == "CONST usedBy x p"                                           
  "_usedBy (_salphaset (_salphamk (x +L y))) P"  <= "_usedBy (x +L y) P"

lift_definition usedBy_uexpr :: "('b  )  ('a, ) uexpr  bool" 
is "λ x e. ( b b'. e (b' L b on x) = e b)" .

adhoc_overloading usedBy usedBy_uexpr
  
lemma usedBy_lit [unrest]: "x  «v»"
  by (transfer, simp)

lemma usedBy_sublens:
  fixes P :: "('a, ) uexpr"
  assumes "x  P" "x L y" "vwb_lens y"
  shows "y  P"
  using assms 
  by (transfer, auto, metis Lens_Order.lens_override_idem lens_override_def sublens_obs_get vwb_lens_mwb)

lemma usedBy_svar [unrest]: "x  P  &x  P"
  by (transfer, simp add: lens_defs)
    
lemma usedBy_lens_plus_1 [unrest]: "x  P  x;y  P"
  by (transfer, simp add: lens_defs)

lemma usedBy_lens_plus_2 [unrest]: " x  y; y  P   x;y  P"
  by (transfer, auto simp add: lens_defs lens_indep_comm)
    
text ‹ Linking used-by to unrestriction: if x is used-by P, and x is independent of y, then
  P cannot depend on any variable in y. ›
    
lemma usedBy_indep_uses:
  fixes P :: "('a, ) uexpr"
  assumes "x  P" "x  y"
  shows "y  P"
  using assms by (transfer, auto, metis lens_indep_get lens_override_def)

lemma usedBy_var [unrest]:
  assumes "vwb_lens x" "y L x"
  shows "x  var y"
  using assms
  by (transfer, simp add: uexpr_defs pr_var_def)
     (metis lens_override_def sublens_obs_get vwb_lens_def wb_lens.get_put)    
  
lemma usedBy_uop [unrest]: "x  e  x  uop f e"
  by (transfer, simp)

lemma usedBy_bop [unrest]: " x  u; x  v   x  bop f u v"
  by (transfer, simp)

lemma usedBy_trop [unrest]: " x  u; x  v; x  w   x  trop f u v w"
  by (transfer, simp)

lemma usedBy_qtop [unrest]: " x  u; x  v; x  w; x  y   x  qtop f u v w y"
  by (transfer, simp)

text ‹ For convenience, we also prove used-by rules for the bespoke operators on equality,
  numbers, arithmetic etc. ›
    
lemma usedBy_eq [unrest]: " x  u; x  v   x  u =u v"
  by (simp add: eq_upred_def, transfer, simp)

lemma usedBy_zero [unrest]: "x  0"
  by (simp add: usedBy_lit zero_uexpr_def)

lemma usedBy_one [unrest]: "x  1"
  by (simp add: one_uexpr_def usedBy_lit)

lemma usedBy_numeral [unrest]: "x  (numeral n)"
  by (simp add: numeral_uexpr_simp usedBy_lit)

lemma usedBy_sgn [unrest]: "x  u  x  sgn u"
  by (simp add: sgn_uexpr_def usedBy_uop)

lemma usedBy_abs [unrest]: "x  u  x  abs u"
  by (simp add: abs_uexpr_def usedBy_uop)

lemma usedBy_plus [unrest]: " x  u; x  v   x  u + v"
  by (simp add: plus_uexpr_def unrest)

lemma usedBy_uminus [unrest]: "x  u  x  - u"
  by (simp add: uminus_uexpr_def unrest)

lemma usedBy_minus [unrest]: " x  u; x  v   x  u - v"
  by (simp add: minus_uexpr_def unrest)

lemma usedBy_times [unrest]: " x  u; x  v   x  u * v"
  by (simp add: times_uexpr_def unrest)

lemma usedBy_divide [unrest]: " x  u; x  v   x  u / v"
  by (simp add: divide_uexpr_def unrest)
    
lemma usedBy_ulambda [unrest]:
  "  x. v  F x   v  (λ x  F x)"
  by (transfer, simp)      

lemma unrest_var_sep [unrest]:
  "vwb_lens x  x  &x:y"
  by (transfer, simp add: lens_defs)
    
end