Theory Optics

text‹This is an excerpt of the Optics library 
     🌐‹https://www.isa-afp.org/entries/Optics.html› by Frank Zeyda and
     Simon Foster. It provides a rich infrastructure for ‹algebraic lenses›,
     an abstract theory allowing to describe parts of memory and their 
     independence. We use it to abstractly model typed program variables and
     framing conditions. 

     Optics provides a rich framework for lense compositions and sub-lenses
     which we will not use in the context of Clean; even the offered concept
     of a list-lense, a possible means to model the stack-infrastructure 
     required for local variables, is actually richer than needed.

     Since Clean strives for minimality, we restrict ourselves to this "proxy"
     theory for Optics.
›

theory Optics
  imports Lens_Laws
begin


fun      upd_hd :: "('a  'a)  'a list  'a list" 
  where "upd_hd f [] = []"
      | "upd_hd f (a#S) = f a # S"

lemma [simp] :"tl (upd_hd f S) = tl S" 
  by (metis list.sel(3) upd_hd.elims)


definition upd2put :: "(('d  'b)  'a  'c)  'a  'b  'c"
  where   "upd2put f = (λσ. λ b. f (λ_. b) σ)"

definition createL 
  where "createL getv updv = lens_get = getv,lens_put = upd2put updv"

definition "hdL = createL hd upd_hd"   (* works since no partial lenses needed in Clean*)

definition "map_nth i = (λf l. list_update l i (f (l ! i)))"


find_theorems "list_update"


lemma [simp]: "map_nth i f [] = []"
  by(simp_all add: map_nth_def)

lemma [simp]: "map_nth i f (a#R) = (case i of 0  (f a) # R | Suc j  a # map_nth j f R)"
  by(simp add: Nitpick.case_nat_unfold map_nth_def)

lemma [simp]: "map_nth n (λx. x) S = S"
  by(induct S, simp_all add: map_nth_def)
 
lemma [simp]: "length(map_nth n f S) = length S"
  by(simp add: map_nth_def)

lemma [simp]: "n < length S  (map_nth n f S) ! n = f (S ! n)"
  by (simp add: map_nth_def)

lemma [simp]: "n < length S  m < length S  nm  (map_nth m f S) ! n = S ! n"
  by (simp add: map_nth_def)

lemma [simp]: "n < length S  (map_nth n f (map_nth n g S)) = (map_nth n (f o g) S)"
  by (simp add: map_nth_def)

(* and more *)

lemma indep_list_lift : 
     "X  createL getv updv 
       (λf σ. updv (λ_. f (getv σ)) σ) = updv 
       X  createL (hd  getv ) (updv  upd_hd)"
  unfolding createL_def o_def Lens_Laws.lens_indep_def upd2put_def
  by (auto,metis (no_types)) (metis (no_types))

end