Theory Synth_Definition
theory Synth_Definition
imports "Automatic_Refinement.Refine_Lib" "HOL-Library.Rewrite"
  "Refine_Imperative_HOL.Sepref_Misc" 
keywords "synth_definition" :: thy_goal
begin
ML ‹
  
  structure Synth_Definition = struct
    
      
    local 
      open Refine_Util
      
    in       
      val sd_parser =  Parse.binding -- Parse.opt_attribs --| @{keyword "is"} 
        -- Scan.optional (Parse.attribs --| Parse.$$$ ":") [] -- Parse.term 
    end  
    fun prep_term t = let
      val nidx = maxidx_of_term t + 1
    
      val t = map_aterms (fn 
            @{mpat (typs) "⌑::?'v_T"} => Var (("HOLE",nidx),T)
          | v as Var ((name,_),T) => if String.isPrefix "_" name then v else Var (("_"^name,nidx),T)
          | t => t
        ) t
      |> Term_Subst.zero_var_indexes
    
    in
      t
    end
    fun sd_cmd (((name,attribs_raw),attribs2_raw),t_raw) lthy = let
      local
        
      in
        
      end
      val read = Syntax.read_prop (Proof_Context.set_mode Proof_Context.mode_pattern lthy)
      
      val t = t_raw |> read |> prep_term
      val ctxt = Variable.declare_term t lthy
      val pat= Thm.cterm_of ctxt t
      val goal=t
      val attribs2 = map (Attrib.check_src lthy) attribs2_raw;
      
      
      fun 
        after_qed [[thm]] ctxt = let
            val thm = singleton (Variable.export ctxt lthy) thm
            val (_,lthy) 
              = Local_Theory.note 
                 ((Refine_Automation.mk_qualified (Binding.name_of name) "refine_raw",[]),[thm]) 
                 lthy;
            val ((dthm,rthm),lthy) = Refine_Automation.define_concrete_fun NONE name attribs_raw [] thm [pat] lthy
            val (_,lthy) = Local_Theory.note ((Binding.empty,attribs2),[rthm]) lthy
            
            
            val _ = Thm.pretty_thm lthy dthm |> Pretty.string_of |> writeln
            val _ = Thm.pretty_thm lthy rthm |> Pretty.string_of |> writeln
          in
            lthy
          end
        | after_qed thmss _ = raise THM ("After-qed: Wrong thmss structure",~1,flat thmss)
    in
      Proof.theorem NONE after_qed [[ (goal,[]) ]] ctxt
    end
    val _ = Outer_Syntax.local_theory_to_proof @{command_keyword "synth_definition"}
      "Synthesis of constant"
      (sd_parser >> sd_cmd)
      
  end
›
end