Theory Printer_Isabelle

(******************************************************************************
 * A Meta-Model for the Isabelle API
 *
 * Copyright (c) 2011-2018 Université Paris-Saclay, Univ. Paris-Sud, France
 *               2013-2017 IRT SystemX, France
 *               2011-2015 Achim D. Brucker, Germany
 *               2016-2018 The University of Sheffield, UK
 *               2016-2017 Nanyang Technological University, Singapore
 *               2017-2018 Virginia Tech, USA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 *     * Neither the name of the copyright holders nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************)

section‹Instantiating the Printer for Isabelle›

theory  Printer_Isabelle
imports Meta_Isabelle
        Printer_Pure
        Printer_SML
begin

context Print
begin

fun of_semi__typ where "of_semi__typ e = (λ
    Typ_base s  To_string s
  | Typ_apply name l  ‹%s %s› (let s = String_concat ‹, › (List.map of_semi__typ l) in
                                 case l of [_]  s | _  ‹(%s)› s)
                                (of_semi__typ name)
  | Typ_apply_bin s ty1 ty2  ‹%s %s %s› (of_semi__typ ty1) (To_string s) (of_semi__typ ty2)
  | Typ_apply_paren s1 s2 ty  ‹%s%s%s› (To_string s1) (of_semi__typ ty) (To_string s2)) e"

definition "of_datatype _ = (λ Datatype n l 
  ‹datatype %s = %s›
    (To_string n)
    (String_concat ‹
                        | ›
      (L.map
        (λ(n,l).
         ‹%s %s›
           (To_string n)
           (String_concat ‹ › (L.map (λx. ‹\"%s\"› (of_semi__typ x)) l))) l) ))"

definition "of_type_synonym _ = (λ Type_synonym n v l 
  ‹type_synonym %s = \"%s\"› (if v = [] then 
                                To_string n
                              else
                                of_semi__typ (Typ_apply (Typ_base n) (L.map Typ_base v)))
                             (of_semi__typ l))"

fun of_semi__term where "of_semi__term e = (λ
    Term_rewrite e1 symb e2  ‹%s %s %s› (of_semi__term e1) (To_string symb) (of_semi__term e2)
  | Term_basic l  ‹%s› (String_concat ‹ › (L.map To_string l))
  | Term_annot e s  ‹(%s::%s)› (of_semi__term e) (of_semi__typ s)
  | Term_bind symb e1 e2  ‹(%s%s. %s)› (To_string symb) (of_semi__term e1) (of_semi__term e2)
  | Term_fun_case e_case l  ‹(%s %s)›
      (case e_case of None  ‹λ›
                    | Some e  ‹case %s of› (of_semi__term e))
      (String_concat ‹
    | › (List.map (λ (s1, s2)  ‹%s ⇒ %s› (of_semi__term s1) (of_semi__term s2)) l))
  | Term_apply e l  ‹%s %s› (of_semi__term e) (String_concat ‹ › (List.map (λ e  ‹%s› (of_semi__term e)) l))
  | Term_paren p_left p_right e  ‹%s%s%s› (To_string p_left) (of_semi__term e) (To_string p_right)
  | Term_if_then_else e_if e_then e_else  ‹if %s then %s else %s› (of_semi__term e_if) (of_semi__term e_then) (of_semi__term e_else)
  | Term_term l pure  of_pure_term (L.map To_string l) pure) e"

definition "of_type_notation _ = (λ Type_notation n e 
  ‹type_notation %s (\"%s\")› (To_string n) (To_string e))"

definition "of_instantiation _ = (λ Instantiation n n_def expr 
  let name = To_string n in
  ‹instantiation %s :: object
begin
  definition %s_%s_def : \"%s\"
  instance ..
end›
    name
    (To_string n_def)
    name
    (of_semi__term expr))"

definition "of_overloading _ = (λ Overloading n_c e_c n e 
  ‹overloading %s ≡ \"%s\"
begin
  definition %s : \"%s\"
end› (To_string n_c) (of_semi__term e_c) (To_string n) (of_semi__term e))"

definition "of_consts _ = (λ Consts n ty symb 
  ‹consts %s :: \"%s\" (\"%s %s\")› (To_string n) (of_semi__typ ty) (To_string Consts_value) (To_string symb))"

definition "of_definition _ = (λ
    Definition e  ‹definition \"%s\"› (of_semi__term e)
  | Definition_where1 name (abbrev, prio) e  ‹definition %s (\"(1%s)\" %d)
  where \"%s\"› (To_string name) (of_semi__term abbrev) (To_nat prio) (of_semi__term e)
  | Definition_where2 name abbrev e  ‹definition %s (\"%s\")
  where \"%s\"› (To_string name) (of_semi__term abbrev) (of_semi__term e))"

definition "(of_semi__thm_attribute_aux_gen :: String.literal × String.literal  _  _  _) m lacc s = 
 (let s_base = (λs lacc. ‹%s[%s]› (To_string s) (String_concat ‹, › (L.map (λ(s, x). ‹%s %s› s x) lacc))) in
  s_base s (m # lacc))"

definition "of_semi__thm_attribute_aux_gen_where l = 
 (‹where›, String_concat ‹ and › (L.map (λ(var, expr). ‹%s = \"%s\"›
                                                          (To_string var)
                                                          (of_semi__term expr)) l))"

definition "of_semi__thm_attribute_aux_gen_of l =
 (‹of›, String_concat ‹ › (L.map (λexpr. ‹\"%s\"› (of_semi__term expr)) l))"

(* NOTE all 'let' declarations can be put at the beginning *)
   (*let f_where = (λl. (‹where›, String_concat ‹ and ›
                                        (L.map (λ(var, expr). ‹%s = \"%s\"›
                                                        (To_string var)
                                                        (of_semi__term expr)) l)))
     ; f_of = (λl. (‹of›, String_concat ‹ ›
                                  (L.map (λexpr. ‹\"%s\"›
                                                        (of_semi__term expr)) l)))
     ; f_symmetric = (‹symmetric›, ‹›)
     ; s_base = (λs lacc. ‹%s[%s]› (To_string s) (String_concat ‹, › (L.map (λ(s, x). ‹%s %s› s x) lacc))) in
   *)
fun of_semi__thm_attribute_aux where "of_semi__thm_attribute_aux lacc e =
  (λ Thm_thm s  To_string s
   | Thm_thms s  To_string s

   | Thm_THEN (Thm_thm s) e2  of_semi__thm_attribute_aux_gen (‹THEN›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_THEN (Thm_thms s) e2  of_semi__thm_attribute_aux_gen (‹THEN›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_THEN e1 e2  of_semi__thm_attribute_aux ((‹THEN›, of_semi__thm_attribute_aux [] e2) # lacc) e1

   | Thm_simplified (Thm_thm s) e2  of_semi__thm_attribute_aux_gen (‹simplified›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_simplified (Thm_thms s) e2  of_semi__thm_attribute_aux_gen (‹simplified›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_simplified e1 e2  of_semi__thm_attribute_aux ((‹simplified›, of_semi__thm_attribute_aux [] e2) # lacc) e1

   | Thm_symmetric (Thm_thm s)  of_semi__thm_attribute_aux_gen (‹symmetric›, ‹›) lacc s 
   | Thm_symmetric (Thm_thms s)  of_semi__thm_attribute_aux_gen (‹symmetric›, ‹›) lacc s
   | Thm_symmetric e1  of_semi__thm_attribute_aux ((‹symmetric›, ‹›) # lacc) e1

   | Thm_where (Thm_thm s) l  of_semi__thm_attribute_aux_gen (of_semi__thm_attribute_aux_gen_where l) lacc s
   | Thm_where (Thm_thms s) l  of_semi__thm_attribute_aux_gen (of_semi__thm_attribute_aux_gen_where l) lacc s
   | Thm_where e1 l  of_semi__thm_attribute_aux (of_semi__thm_attribute_aux_gen_where l # lacc) e1

   | Thm_of (Thm_thm s) l  of_semi__thm_attribute_aux_gen (of_semi__thm_attribute_aux_gen_of l) lacc s
   | Thm_of (Thm_thms s) l  of_semi__thm_attribute_aux_gen (of_semi__thm_attribute_aux_gen_of l) lacc s
   | Thm_of e1 l  of_semi__thm_attribute_aux (of_semi__thm_attribute_aux_gen_of l # lacc) e1

   | Thm_OF (Thm_thm s) e2  of_semi__thm_attribute_aux_gen (‹OF›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_OF (Thm_thms s) e2  of_semi__thm_attribute_aux_gen (‹OF›, of_semi__thm_attribute_aux [] e2) lacc s
   | Thm_OF e1 e2  of_semi__thm_attribute_aux ((‹OF›, of_semi__thm_attribute_aux [] e2) # lacc) e1) e"

definition "of_semi__thm_attribute = of_semi__thm_attribute_aux []"

definition "of_semi__thm = (λ Thms_single thy  of_semi__thm_attribute thy
                         | Thms_mult thy  of_semi__thm_attribute thy)"

definition "of_semi__thm_attribute_l l = String_concat ‹
                            › (L.map of_semi__thm_attribute l)"
definition "of_semi__thm_attribute_l1 l = String_concat ‹ › (L.map of_semi__thm_attribute l)"

definition "of_semi__thm_l l = String_concat ‹ › (L.map of_semi__thm l)"

definition "of_lemmas _ = (λ Lemmas_simp_thm simp s l 
  ‹lemmas%s%s = %s›
    (if String.is_empty s then ‹› else ‹ %s› (To_string s))
    (if simp then ‹[simp,code_unfold]› else ‹›)
    (of_semi__thm_attribute_l l)
                           | Lemmas_simp_thms s l 
  ‹lemmas%s [simp,code_unfold] = %s›
    (if String.is_empty s then ‹› else ‹ %s› (To_string s))
    (String_concat ‹
                            › (L.map To_string l)))"

definition "(of_semi__attrib_genA :: (semi__thm list  String.literal)
    String.literal  semi__thm list  String.literal) f attr l = ― ‹error reflection: to be merged›
 (if l = [] then
    ‹›
  else
    ‹ %s: %s› attr (f l))"

definition "(of_semi__attrib_genB :: (string list  String.literal)
    String.literal  string list  String.literal) f attr l = ― ‹error reflection: to be merged›
 (if l = [] then
    ‹›
  else
    ‹ %s: %s› attr (f l))"

definition "of_semi__attrib = of_semi__attrib_genA of_semi__thm_l"
definition "of_semi__attrib1 = of_semi__attrib_genB (λl. String_concat ‹ › (L.map To_string l))"

definition "of_semi__method_simp (s :: ― ‹polymorphism weakening needed by code_reflect
                                       String.literal) =
 (λ Method_simp_only l  ‹%s only: %s› s (of_semi__thm_l l)
  | Method_simp_add_del_split l1 l2 []  ‹%s%s%s›
      s
      (of_semi__attrib ‹add› l1)
      (of_semi__attrib ‹del› l2)
  | Method_simp_add_del_split l1 l2 l3  ‹%s%s%s%s›
      s
      (of_semi__attrib ‹add› l1)
      (of_semi__attrib ‹del› l2)
      (of_semi__attrib ‹split› l3))"

fun of_semi__method where "of_semi__method expr = (λ
    Method_rule o_s  ‹rule%s› (case o_s of None  ‹›
                                           | Some s  ‹ %s› (of_semi__thm_attribute s))
  | Method_drule s  ‹drule %s› (of_semi__thm_attribute s)
  | Method_erule s  ‹erule %s› (of_semi__thm_attribute s)
  | Method_intro l  ‹intro %s› (of_semi__thm_attribute_l1 l)
  | Method_elim s  ‹elim %s› (of_semi__thm_attribute s)
  | Method_subst asm l s =>
      let s_asm = if asm then ‹(asm) › else ‹› in
      if L.map String.meta_of_logic l = [STR ''0''] then
        ‹subst %s%s› s_asm (of_semi__thm_attribute s)
      else
        ‹subst %s(%s) %s› s_asm (String_concat ‹ › (L.map To_string l)) (of_semi__thm_attribute s)
  | Method_insert l => ‹insert %s› (of_semi__thm_l l)
  | Method_plus t  ‹(%s)+› (String_concat ‹, › (List.map of_semi__method t))
  | Method_option t  ‹(%s)?› (String_concat ‹, › (List.map of_semi__method t))
  | Method_or t  ‹(%s)› (String_concat ‹ | › (List.map of_semi__method t))
  | Method_one s  of_semi__method_simp ‹simp› s
  | Method_all s  of_semi__method_simp ‹simp_all› s
  | Method_auto_simp_add_split l_simp l_split  ‹auto%s%s›
      (of_semi__attrib ‹simp› l_simp)
      (of_semi__attrib1 ‹split› l_split)
  | Method_rename_tac l  ‹rename_tac %s› (String_concat ‹ › (L.map To_string l))
  | Method_case_tac e  ‹case_tac \"%s\"› (of_semi__term e)
  | Method_blast None  ‹blast›
  | Method_blast (Some n)  ‹blast %d› (To_nat n)
  | Method_clarify  ‹clarify›
  | Method_metis l_opt l  ‹metis %s%s› (if l_opt = [] then ‹›
                                          else
                                            ‹(%s) › (String_concat ‹, › (L.map To_string l_opt))) (of_semi__thm_attribute_l1 l)) expr"

definition "of_semi__command_final = (λ Command_done  ‹done›
                                      | Command_by l_apply  ‹by(%s)› (String_concat ‹, › (L.map of_semi__method l_apply))
                                      | Command_sorry  ‹sorry›)"

definition "of_semi__command_state = (
  λ Command_apply_end []  ‹›
  | Command_apply_end l_apply  ‹  apply_end(%s)
› (String_concat ‹, › (L.map of_semi__method l_apply)))"

definition of_semi__command_proof = (
  let thesis = ‹?thesis›
    ; scope_thesis_gen = λproof show when. ‹  proof - %s show %s%s
› proof
  show
  (if when = [] then
     ‹›
   else
     ‹ when %s› (String_concat ‹ › (L.map (λt. ‹"%s"› (of_semi__term t)) when)))
    ; scope_thesis = λs. scope_thesis_gen s thesis [] in
  λ Command_apply []  ‹›
  | Command_apply l_apply  ‹  apply(%s)
› (String_concat ‹, › (L.map of_semi__method l_apply))
  | Command_using l  ‹  using %s
› (of_semi__thm_l l)
  | Command_unfolding l  ‹  unfolding %s
› (of_semi__thm_l l)
  | Command_let e_name e_body  scope_thesis (‹let %s = "%s"› (of_semi__term e_name) (of_semi__term e_body))
  | Command_have n b e e_last  scope_thesis (‹have %s%s: "%s" %s› (To_string n) (if b then ‹[simp]› else ‹›) (of_semi__term e) (of_semi__command_final e_last))
  | Command_fix_let l l_let o_show _ 
      scope_thesis_gen
        (‹fix %s%s› (String_concat ‹ › (L.map To_string l))
                    (String_concat ‹
›                                  (L.map
                                     (λ(e_name, e_body).
                                       ‹          let %s = "%s"› (of_semi__term e_name) (of_semi__term e_body))
                                     l_let)))
        (case o_show of None  thesis
                      | Some (l_show, _)  ‹"%s"› (String_concat ‹ ⟹ › (L.map of_semi__term l_show)))
        (case o_show of None  [] | Some (_, l_when)  l_when))

definition "of_lemma _ =
 (λ Lemma n l_spec l_apply tactic_last 
    ‹lemma %s : \"%s\"
%s%s›
      (To_string n)
      (String_concat ‹ ⟹ › (L.map of_semi__term l_spec))
      (String_concat ‹› (L.map (λ []  ‹› | l_apply  ‹  apply(%s)
›
                                                          (String_concat ‹, › (L.map of_semi__method l_apply)))
                               l_apply))
      (of_semi__command_final tactic_last)
  | Lemma_assumes n l_spec concl l_apply tactic_last 
    ‹lemma %s : %s
%s%s %s›
      (To_string n)
      (String_concat ‹› (L.map (λ(n, b, e).
          ‹
assumes %s\"%s\"›
            (let (n, b) = if b then (‹%s[simp]› (To_string n), False) else (To_string n, String.is_empty n) in
             if b then ‹› else ‹%s: › n)
            (of_semi__term e)) l_spec
       @@@@
       [‹
shows \"%s\"› (of_semi__term concl)]))
      (String_concat ‹› (L.map of_semi__command_proof l_apply))
      (of_semi__command_final tactic_last)
      (String_concat ‹ ›
        (L.map
          (λl_apply_e.
            ‹%sqed›
              (if l_apply_e = [] then
                 ‹›
               else
                 ‹
%s ›
                   (String_concat ‹› (L.map of_semi__command_state l_apply_e))))
          (List.map_filter
            (λ Command_let _ _  Some [] | Command_have _ _ _ _  Some [] | Command_fix_let _ _ _ l  Some l | _  None)
            (rev l_apply)))))"


definition "of_axiomatization _ = (λ Axiomatization n e  ‹axiomatization where %s:
\"%s\"› (To_string n) (of_semi__term e))"

definition "of_section _ = (λ Section n section_title 
    ‹%s ‹%s››
      (‹%ssection› (if n = 0 then ‹›
                    else if n = 1 then ‹sub›
                    else ‹subsub›))
      (To_string section_title))"

definition "of_text _ = (λ Text s  ‹text ‹%s›› (To_string s))"

definition "of_ML _ = (λ SML e  ‹ML ‹%s›› (of_semi__term' e))"

definition "of_setup _ = (λ Setup e  ‹setup ‹%s›› (of_semi__term' e))"

definition "of_thm _ = (λ Thm thm  ‹thm %s› (of_semi__thm_attribute_l1 thm))"

definition of_interpretation _ = (λ Interpretation n loc_n loc_param tac 
  ‹interpretation %s: %s%s
%s› (To_string n)
    (To_string loc_n)
    (String_concat ‹› (L.map (λs. ‹ "%s"› (of_semi__term s)) loc_param))
    (of_semi__command_final tac))

definition "of_semi__theory env =
 (λ Theory_datatype dataty  of_datatype env dataty
  | Theory_type_synonym ty_synonym  of_type_synonym env ty_synonym
  | Theory_type_notation ty_notation  of_type_notation env ty_notation
  | Theory_instantiation instantiation_class  of_instantiation env instantiation_class
  | Theory_overloading overloading  of_overloading env overloading
  | Theory_consts consts_class  of_consts env consts_class
  | Theory_definition definition_hol  of_definition env definition_hol
  | Theory_lemmas lemmas_simp  of_lemmas env lemmas_simp
  | Theory_lemma lemma_by  of_lemma env lemma_by
  | Theory_axiomatization axiom  of_axiomatization env axiom
  | Theory_section section_title  of_section env section_title
  | Theory_text text  of_text env text
  | Theory_ML ml  of_ML env ml
  | Theory_setup setup  of_setup env setup
  | Theory_thm thm  of_thm env thm
  | Theory_interpretation thm  of_interpretation env thm)"

definition "String_concat_map s f l = String_concat s (L.map f l)"

definition of_semi__theories env =
 (λ Theories_one t  of_semi__theory env t
  | Theories_locale data l  
      ‹locale %s =
%s
begin
%s
end›   (To_string (HolThyLocale_name data))
        (String_concat_map
           ‹
›
           (λ (l_fix, o_assum).
                ‹%s%s› (String_concat_map ‹
› (λ(e, ty). ‹fixes "%s" :: "%s"› (of_semi__term e) (of_semi__typ ty)) l_fix)
                                (case o_assum of None  ‹›
                                               | Some (name, e)  ‹
assumes %s: "%s"› (To_string name) (of_semi__term e)))
           (HolThyLocale_header data))
        (String_concat_map ‹

› (String_concat_map ‹

› (of_semi__theory env)) l))

end

lemmas [code] =
  ― ‹def›
  Print.of_datatype_def
  Print.of_type_synonym_def
  Print.of_type_notation_def
  Print.of_instantiation_def
  Print.of_overloading_def
  Print.of_consts_def
  Print.of_definition_def
  Print.of_semi__thm_attribute_aux_gen_def
  Print.of_semi__thm_attribute_aux_gen_where_def
  Print.of_semi__thm_attribute_aux_gen_of_def
  Print.of_semi__thm_attribute_def
  Print.of_semi__thm_def
  Print.of_semi__thm_attribute_l_def
  Print.of_semi__thm_attribute_l1_def
  Print.of_semi__thm_l_def
  Print.of_lemmas_def
  Print.of_semi__attrib_genA_def
  Print.of_semi__attrib_genB_def
  Print.of_semi__attrib_def
  Print.of_semi__attrib1_def
  Print.of_semi__method_simp_def
  Print.of_semi__command_final_def
  Print.of_semi__command_state_def
  Print.of_semi__command_proof_def
  Print.of_lemma_def
  Print.of_axiomatization_def
  Print.of_section_def
  Print.of_text_def
  Print.of_ML_def
  Print.of_setup_def
  Print.of_thm_def
  Print.of_interpretation_def
  Print.of_semi__theory_def
  Print.String_concat_map_def
  Print.of_semi__theories_def

  ― ‹fun›
  Print.of_semi__typ.simps
  Print.of_semi__term.simps
  Print.of_semi__thm_attribute_aux.simps
  Print.of_semi__method.simps

end