Theory Labels

section ‹Labels›

theory Labels imports Com begin

text ‹Labels describe a mapping from the inner node label 
  to the matching command›

inductive labels :: "cmd  nat  cmd  bool"
where

Labels_Base:
  "labels c 0 c"

| Labels_LAss:
  "labels (V:=e) 1 Skip"

| Labels_Seq1: 
  "labels c1 l c  labels (c1;;c2) l (c;;c2)"

| Labels_Seq2: 
  "labels c2 l c  labels (c1;;c2) (l + #:c1) c"

| Labels_CondTrue:
  "labels c1 l c  labels (if (b) c1 else c2) (l + 1) c"

| Labels_CondFalse:
  "labels c2 l c  labels (if (b) c1 else c2) (l + #:c1 + 1) c"

| Labels_WhileBody:
  "labels c' l c  labels (while(b) c') (l + 2) (c;;while(b) c')"

| Labels_WhileExit:
  "labels (while(b) c') 1 Skip"

| Labels_Call:
  "labels (Call p es rets) 1 Skip"


lemma label_less_num_inner_nodes:
  "labels c l c'  l < #:c"
proof(induct c arbitrary:l c')
  case Skip 
  from labels Skip l c' show ?case by(fastforce elim:labels.cases)
next
  case (LAss V e) 
  from labels (V:=e) l c' show ?case by(fastforce elim:labels.cases)
next
  case (Seq c1 c2)
  note IH1 = l c'. labels c1 l c'  l < #:c1
  note IH2 = l c'. labels c2 l c'  l < #:c2
  from labels (c1;;c2) l c' IH1 IH2 show ?case
    by simp(erule labels.cases,auto,force)
next
  case (Cond b c1 c2)
  note IH1 = l c'. labels c1 l c'  l < #:c1
  note IH2 = l c'. labels c2 l c'  l < #:c2
  from labels (if (b) c1 else c2) l c' IH1 IH2 show ?case
    by simp(erule labels.cases,auto,force)
next
  case (While b c)
  note IH = l c'. labels c l c'  l < #:c
  from labels (while (b) c) l c' IH show ?case
    by simp(erule labels.cases,fastforce+)
next
  case (Call p es rets) 
  thus ?case by simp(erule labels.cases,fastforce+)
qed


declare One_nat_def [simp del]

lemma less_num_inner_nodes_label:
  assumes "l < #:c" obtains c' where "labels c l c'"
proof(atomize_elim)
  from l < #:c show "c'. labels c l c'"
  proof(induct c arbitrary:l)
    case Skip
    from l < #:Skip have "l = 0" by simp
    thus ?case by(fastforce intro:Labels_Base)
  next
    case (LAss V e)
    from l < #:(V:=e) have "l = 0  l = 1" by auto
    thus ?case by(auto intro:Labels_Base Labels_LAss)
  next
    case (Seq c1 c2)
    note IH1 = l. l < #:c1  c'. labels c1 l c'
    note IH2 = l. l < #:c2  c'. labels c2 l c'
    show ?case
    proof(cases "l < #:c1")
      case True
      from IH1[OF this] obtain c' where "labels c1 l c'" by auto
      hence "labels (c1;;c2) l (c';;c2)" by(fastforce intro:Labels_Seq1)
      thus ?thesis by auto
    next
      case False
      hence "#:c1  l" by simp
      then obtain l' where "l = l' + #:c1" and "l' = l - #:c1" by simp
      from l = l' + #:c1 l < #:c1;;c2 have "l' < #:c2" by simp
      from IH2[OF this] obtain c' where "labels c2 l' c'" by auto
      with l = l' + #:c1 have "labels (c1;;c2) l c'" 
        by(fastforce intro:Labels_Seq2)
      thus ?thesis by auto
    qed
  next
    case (Cond b c1 c2)
    note IH1 = l. l < #:c1  c'. labels c1 l c'
    note IH2 = l. l < #:c2  c'. labels c2 l c'
    show ?case
    proof(cases "l = 0")
      case True
      thus ?thesis by(fastforce intro:Labels_Base)
    next
      case False
      hence "0 < l" by simp
      then obtain l' where "l = l' + 1" and "l' = l - 1" by simp
      thus ?thesis
      proof(cases "l' < #:c1")
        case True
        from IH1[OF this] obtain c' where "labels c1 l' c'" by auto
        with l = l' + 1 have "labels (if (b) c1 else c2) l c'"
          by(fastforce dest:Labels_CondTrue)
        thus ?thesis by auto
      next
        case False
        hence "#:c1  l'" by simp
        then obtain l'' where "l' = l'' + #:c1" and "l'' = l' - #:c1" by simp
        from l' = l'' + #:c1 l = l' + 1 l < #:if (b) c1 else c2
        have "l'' < #:c2" by simp
        from IH2[OF this] obtain c' where "labels c2 l'' c'" by auto
        with l' = l'' + #:c1 l = l' + 1 have "labels (if (b) c1 else c2) l c'"
          by(fastforce dest:Labels_CondFalse)
        thus ?thesis by auto
      qed
    qed
  next
    case (While b c')
    note IH = l. l < #:c'  c''. labels c' l c''
    show ?case
    proof(cases "l < 1")
      case True
      hence "l = 0" by simp
      thus ?thesis by(fastforce intro:Labels_Base)
    next
      case False
      show ?thesis
      proof(cases "l < 2")
        case True
        with ¬ l < 1 have "l = 1" by simp
        thus ?thesis by(fastforce intro:Labels_WhileExit)
      next
        case False
        with ¬ l < 1 have "2  l" by simp
        then obtain l' where "l = l' + 2" and "l' = l - 2" 
          by(simp del:add_2_eq_Suc')
        from l = l' + 2 l < #:while (b) c' have "l' < #:c'" by simp
        from IH[OF this] obtain c'' where "labels c' l' c''" by auto
        with l = l' + 2 have "labels (while (b) c') l (c'';;while (b) c')"
          by(fastforce dest:Labels_WhileBody)
        thus ?thesis by auto
      qed
    qed
  next
    case (Call p es rets)
    show ?case
    proof(cases "l < 1")
      case True
      hence "l = 0" by simp
      thus ?thesis by(fastforce intro:Labels_Base)
    next
      case False
      with l < #:Call p es rets have "l = 1" by simp
      thus ?thesis by(fastforce intro:Labels_Call)
    qed
  qed
qed


lemma labels_det:
  "labels c l c' (c''. labels c l c'' c' = c'')"
proof(induct rule:labels.induct)
  case (Labels_Base c c'') 
  from labels c 0 c'' obtain l where "labels c l c''" and "l = 0" by auto
  thus ?case by(induct rule:labels.induct,auto)
next
  case (Labels_Seq1 c1 l c c2)
  note IH = c''. labels c1 l c''  c = c''
  from labels c1 l c have "l < #:c1" by(fastforce intro:label_less_num_inner_nodes)
  with labels (c1;;c2) l c'' obtain cx where "c'' = cx;;c2  labels c1 l cx"
    by(fastforce elim:labels.cases intro:Labels_Base)
  hence [simp]:"c'' = cx;;c2" and "labels c1 l cx" by simp_all
  from IH[OF labels c1 l cx] show ?case by simp
next
  case (Labels_Seq2 c2 l c c1)
  note IH = c''. labels c2 l c''  c = c''
  from labels (c1;;c2) (l + #:c1) c'' labels c2 l c have "labels c2 l c''" 
    by(auto elim:labels.cases dest:label_less_num_inner_nodes)
  from IH[OF this] show ?case .
next
  case (Labels_CondTrue c1 l c b c2)
  note IH = c''. labels c1 l c''   c = c''
  from labels (if (b) c1 else c2) (l + 1) c'' labels c1 l c have "labels c1 l c''"
    by(fastforce elim:labels.cases dest:label_less_num_inner_nodes)
  from IH[OF this] show ?case .
next
  case (Labels_CondFalse c2 l c b c1)
  note IH = c''. labels c2 l c''   c = c''
  from labels (if (b) c1 else c2) (l + #:c1 + 1) c'' labels c2 l c
  have "labels c2 l c''"
    by(fastforce elim:labels.cases dest:label_less_num_inner_nodes)
  from IH[OF this] show ?case .
next
  case (Labels_WhileBody c' l c b)
  note IH = c''. labels c' l c''  c = c''
  from labels (while (b) c') (l + 2) c'' labels c' l c 
  obtain cx where "c'' = cx;;while (b) c'  labels c' l cx" 
    by -(erule labels.cases,auto)
  hence [simp]:"c'' = cx;;while (b) c'" and "labels c' l cx" by simp_all
  from IH[OF labels c' l cx] show ?case by simp
qed (fastforce elim:labels.cases)+



definition label :: "cmd  nat  cmd"
  where "label c n  (THE c'. labels c n c')"


lemma labels_THE:
  "labels c l c'  (THE c'. labels c l c') = c'"
by(fastforce intro:the_equality dest:labels_det)


lemma labels_label:"labels c l c'  label c l = c'"
by(fastforce intro:labels_THE simp:label_def)


end