Theory Context_Free_Grammar_Example

theory Context_Free_Grammar_Example
imports "HOL-Library.Code_Prolog"
begin
(*
declare mem_def[code_pred_inline]
*)

subsection ‹Alternative rules for length›

definition size_list :: "'a list => nat"
where "size_list = size"

lemma size_list_simps:
  "size_list [] = 0"
  "size_list (x # xs) = Suc (size_list xs)"
by (auto simp add: size_list_def)

declare size_list_simps[code_pred_def]
declare size_list_def[symmetric, code_pred_inline]


setup ‹
  Context.theory_map
    (Quickcheck.add_tester ("prolog", (Code_Prolog.active, Code_Prolog.test_goals)))
›

datatype alphabet = a | b

inductive_set S1 and A1 and B1 where
  "[] ∈ S1"
| "w ∈ A1 ⟹ b # w ∈ S1"
| "w ∈ B1 ⟹ a # w ∈ S1"
| "w ∈ S1 ⟹ a # w ∈ A1"
| "w ∈ S1 ⟹ b # w ∈ S1"
| "⟦v ∈ B1; v ∈ B1⟧ ⟹ a # v @ w ∈ B1"

lemma
  "S1p w ⟹ w = []"
quickcheck[tester = prolog, iterations=1, expect = counterexample]
oops

definition "filter_a = filter (λx. x = a)"

lemma [code_pred_def]: "filter_a [] = []"
unfolding filter_a_def by simp

lemma [code_pred_def]: "filter_a (x#xs) = (if x = a then x # filter_a xs else filter_a xs)"
unfolding filter_a_def by simp

declare filter_a_def[symmetric, code_pred_inline]

definition "filter_b = filter (λx. x = b)"

lemma [code_pred_def]: "filter_b [] = []"
unfolding filter_b_def by simp

lemma [code_pred_def]: "filter_b (x#xs) = (if x = b then x # filter_b xs else filter_b xs)"
unfolding filter_b_def by simp

declare filter_b_def[symmetric, code_pred_inline]

setup ‹Code_Prolog.map_code_options (K
  {ensure_groundness = true,
  limit_globally = NONE,
  limited_types = [],
  limited_predicates = [(["s1p", "a1p", "b1p"], 2)],
  replacing = [(("s1p", "limited_s1p"), "quickcheck")],
  manual_reorder = [(("quickcheck", 1), [0,2,1,4,3,5])]})›


theorem S1_sound:
"S1p w ⟹ length [x ← w. x = a] = length [x ← w. x = b]"
quickcheck[tester = prolog, iterations=1, expect = counterexample]
oops


inductive_set S2 and A2 and B2 where
  "[] ∈ S2"
| "w ∈ A2 ⟹ b # w ∈ S2"
| "w ∈ B2 ⟹ a # w ∈ S2"
| "w ∈ S2 ⟹ a # w ∈ A2"
| "w ∈ S2 ⟹ b # w ∈ B2"
| "⟦v ∈ B2; v ∈ B2⟧ ⟹ a # v @ w ∈ B2"


setup ‹Code_Prolog.map_code_options (K
  {ensure_groundness = true,
  limit_globally = NONE,
  limited_types = [],
  limited_predicates = [(["s2p", "a2p", "b2p"], 3)],
  replacing = [(("s2p", "limited_s2p"), "quickcheck")],
  manual_reorder = [(("quickcheck", 1), [0,2,1,4,3,5])]})›


theorem S2_sound:
  "S2p w ⟶ length [x ← w. x = a] = length [x ← w. x = b]"
quickcheck[tester = prolog, iterations=1, expect = counterexample]
oops

inductive_set S3 and A3 and B3 where
  "[] ∈ S3"
| "w ∈ A3 ⟹ b # w ∈ S3"
| "w ∈ B3 ⟹ a # w ∈ S3"
| "w ∈ S3 ⟹ a # w ∈ A3"
| "w ∈ S3 ⟹ b # w ∈ B3"
| "⟦v ∈ B3; w ∈ B3⟧ ⟹ a # v @ w ∈ B3"


setup ‹Code_Prolog.map_code_options (K
  {ensure_groundness = true,
  limit_globally = NONE,
  limited_types = [],
  limited_predicates = [(["s3p", "a3p", "b3p"], 6)],
  replacing = [(("s3p", "limited_s3p"), "quickcheck")],
  manual_reorder = [(("quickcheck", 1), [0,2,1,4,3,5])]})›

lemma S3_sound:
  "S3p w ⟶ length [x ← w. x = a] = length [x ← w. x = b]"
quickcheck[tester = prolog, iterations=1, size=1, expect = no_counterexample]
oops


(*
setup {* Code_Prolog.map_code_options (K
  {ensure_groundness = true,
  limit_globally = NONE,
  limited_types = [],
  limited_predicates = [],
  replacing = [],
  manual_reorder = [],
  timeout = seconds 10.0,
  prolog_system = Code_Prolog.SWI_PROLOG}) *}


theorem S3_complete:
"length [x ← w. x = a] = length [x ← w. x = b] ⟶ w ∈ S3"
quickcheck[tester = prolog, size=1, iterations=1]
oops
*)

inductive_set S4 and A4 and B4 where
  "[] ∈ S4"
| "w ∈ A4 ⟹ b # w ∈ S4"
| "w ∈ B4 ⟹ a # w ∈ S4"
| "w ∈ S4 ⟹ a # w ∈ A4"
| "⟦v ∈ A4; w ∈ A4⟧ ⟹ b # v @ w ∈ A4"
| "w ∈ S4 ⟹ b # w ∈ B4"
| "⟦v ∈ B4; w ∈ B4⟧ ⟹ a # v @ w ∈ B4"


setup ‹Code_Prolog.map_code_options (K
  {ensure_groundness = true,
  limit_globally = NONE,
  limited_types = [],
  limited_predicates = [(["s4p", "a4p", "b4p"], 6)],
  replacing = [(("s4p", "limited_s4p"), "quickcheck")],
  manual_reorder = [(("quickcheck", 1), [0,2,1,4,3,5])]})›


theorem S4_sound:
  "S4p w ⟶ length [x ← w. x = a] = length [x ← w. x = b]"
quickcheck[tester = prolog, size=1, iterations=1, expect = no_counterexample]
oops

(*
theorem S4_complete:
"length [x ← w. x = a] = length [x ← w. x = b] ⟶ w ∈ S4"
oops
*)

hide_const a b


end