Skip to content

Instantly share code, notes, and snippets.

@jake-87
Last active November 27, 2025 10:18
Show Gist options
  • Select an option

  • Save jake-87/b1ecaaa2062e6a24a5fad15241ade518 to your computer and use it in GitHub Desktop.

Select an option

Save jake-87/b1ecaaa2062e6a24a5fad15241ade518 to your computer and use it in GitHub Desktop.

V2:

theory Isabelle_little_compiler
  imports Main
begin

datatype lang = 
  Lit nat
  | Plus lang lang

datatype op =
  Push nat
  | Add

fun compile :: "lang ⇒ op list" where
"compile (Lit n) = [Push n]" |
"compile (Plus a b) = compile a @ compile b @ [Add]"

fun decompile :: "op list ⇒ lang list ⇒ lang list" where
"decompile [] stack = stack" |
"decompile (Push n # xs) stack = decompile xs (Lit n # stack)" |
"decompile (Add # xs) stack = decompile xs (case stack of
b # a # rest ⇒ Plus a b # rest |
_ ⇒ stack)"

lemma decompile_right_gen: "decompile (compile e @ k) stack = decompile k (e # stack)"
  by (induct e arbitrary: k stack; simp)  

lemma decompile_right: "decompile (compile a) [] = [a]"
  using decompile_right_gen[where k="[]"] by auto

lemma equiv: "compile a = compile b ⟹ a = b"
  using decompile_right
  by (metis list.inject)

end

V1 (horrible termination proof):

(* Should really be in a .thy file, but syntax highlighting ;) *)
theory Isabelle_little_compiler
  imports Main
begin

datatype lang = 
  Lit nat
  | Plus lang lang

datatype op =
  Push nat
  | Add

fun compile :: "lang ⇒ op list" where
"compile (Lit n) = [Push n]" |
"compile (Plus a b) = Add # compile a @ compile b"

(* 
   Writing the function mbones's way would fix the "Isabelle is being a pain around termination" problem,
   but this is how I originally pictured it, so this way it'll stay.
*)

function decompile :: "op list ⇒ lang option × op list" where
"decompile [] = (None, [])" |
"decompile (Push n # xs) = (Some (Lit n), xs)" |
"decompile (Add # a) = (case decompile a of
                          (Some a', xs) ⇒ (case decompile xs of
                              (Some b', ys) ⇒ (Some (Plus a' b'), ys) |
                              _ ⇒ (None, [])) |
                          _ ⇒ (None, []))"
  by pat_completeness auto
termination sorry
 

lemma decompile_right_gen: "decompile ((compile a) @ k) = (Some a, k)"
  by (induct a arbitrary: k; clarsimp)

lemma decompile_right: "decompile (compile a) = (Some a, [])"
  using decompile_right_gen[where k="[]"] by auto

lemma equiv: "compile a = compile b ⟹ a = b"
  using decompile_right
  by (metis option.inject prod.inject)
  
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment