Theory Test_Pat_Complete
section ‹Setup for Experiments›
theory Test_Pat_Complete
imports
Pattern_Completeness
"HOL-Library.Code_Abstract_Char"
"HOL-Library.Code_Target_Numeral"
begin
text ‹turn error message into runtime error›
definition pat_complete_alg :: "(('f × 's list) × 's)list ⇒ (('f × 's list) × 's)list ⇒ ('f,'v)term list ⇒ bool" where
"pat_complete_alg C D lhss = (
case decide_pat_complete_lhss C D lhss of Inl err ⇒ Code.abort (err (STR '''')) (λ _. True)
| Inr res ⇒ res)"
text ‹turn error message into runtime error›
definition strong_quasi_reducible_alg :: "(('f × 's list) × 's)list ⇒ (('f × 's list) × 's)list ⇒ ('f,'v)term list ⇒ bool" where
"strong_quasi_reducible_alg C D lhss = (
case decide_strong_quasi_reducible C D lhss of Inl err ⇒ Code.abort (err (STR '''')) (λ _. True)
| Inr res ⇒ res)"
text ‹Examples›
definition "nat_bool = [
((''zero'', []), ''nat''),
((''succ'', [''nat'']), ''nat''),
((''true'', []), ''bool''),
((''false'', []), ''bool'')
]"
definition "int_bool = [
((''zero'', []), ''int''),
((''succ'', [''int'']), ''int''),
((''pred'', [''int'']), ''int''),
((''true'', []), ''bool''),
((''false'', []), ''bool'')
]"
definition "even_nat = [
((''even'', [''nat'']), ''bool'')
]"
definition "even_int = [
((''even'', [''int'']), ''bool'')
]"
definition "even_lhss = [
Fun ''even'' [Fun ''zero'' []],
Fun ''even'' [Fun ''succ'' [Fun ''zero'' []]],
Fun ''even'' [Fun ''succ'' [Fun ''succ'' [Var ''x'']]]
]"
definition "even_lhss_int = [
Fun ''even'' [Fun ''zero'' []],
Fun ''even'' [Fun ''succ'' [Fun ''zero'' []]],
Fun ''even'' [Fun ''succ'' [Fun ''succ'' [Var ''x'']]],
Fun ''even'' [Fun ''pred'' [Fun ''zero'' []]],
Fun ''even'' [Fun ''pred'' [Fun ''pred'' [Var ''x'']]],
Fun ''succ'' [Fun ''pred'' [Var ''x'']],
Fun ''pred'' [Fun ''succ'' [Var ''x'']]
]"
lemma decide_pat_complete_wrapper:
assumes "(case decide_pat_complete_lhss C D lhss of Inr b ⇒ Some b | Inl _ ⇒ None) = Some res"
shows "pat_complete_lhss (map_of C) (map_of D) (set lhss) = res"
using decide_pat_complete_lhss[of C D lhss] assms by (auto split: sum.splits)
lemma decide_strong_quasi_reducible_wrapper:
assumes "(case decide_strong_quasi_reducible C D lhss of Inr b ⇒ Some b | Inl _ ⇒ None) = Some res"
shows "strong_quasi_reducible (map_of C) (map_of D) (set lhss) = res"
using decide_strong_quasi_reducible[of C D lhss] assms by (auto split: sum.splits)
lemma "pat_complete_lhss (map_of nat_bool) (map_of even_nat) (set even_lhss)"
apply (subst decide_pat_complete_wrapper[of _ _ _ True])
by eval+
lemma "¬ pat_complete_lhss (map_of int_bool) (map_of even_int) (set even_lhss_int)"
apply (subst decide_pat_complete_wrapper[of _ _ _ False])
by eval+
lemma "strong_quasi_reducible (map_of int_bool) (map_of even_int) (set even_lhss_int)"
apply (subst decide_strong_quasi_reducible_wrapper[of _ _ _ True])
by eval+
definition "non_lin_lhss = [
Fun ''f'' [Var ''x'', Var ''x'', Var ''y''],
Fun ''f'' [Var ''x'', Var ''y'', Var ''x''],
Fun ''f'' [Var ''y'', Var ''x'', Var ''x'']
]"
lemma "pat_complete_lhss (map_of nat_bool) (map_of [((''f'',[''bool'',''bool'',''bool'']),''bool'')]) (set non_lin_lhss)"
apply (subst decide_pat_complete_wrapper[of _ _ _ True])
by eval+
lemma "¬ pat_complete_lhss (map_of nat_bool) (map_of [((''f'',[''nat'',''nat'',''nat'']),''bool'')]) (set non_lin_lhss)"
apply (subst decide_pat_complete_wrapper[of _ _ _ False])
by eval+
definition "testproblem (c :: nat) n = (let s = String.implode; s = id;
c1 = even c;
c2 = even (c div 2);
c3 = even (c div 4);
c4 = even (c div 8);
revo = (if c4 then id else rev);
nn = [0 ..< n];
rnn = (if c4 then id nn else rev nn);
b = s ''b''; t = s ''tt''; f = s ''ff''; g = s ''g'';
gg = (λ ts. Fun g (revo ts));
ff = Fun f [];
tt = Fun t [];
C = [((t, [] :: string list), b), ((f, []), b)];
D = [((g, replicate (2 * n) b), b)];
x = (λ i :: nat. Var (s (''x'' @ show i)));
y = (λ i :: nat. Var (s (''y'' @ show i)));
lhsF = gg (if c1 then List.maps (λ i. [ff, y i] ) rnn else (replicate n ff @ map y rnn));
lhsT = (λ b j. gg (if c1 then List.maps (λ i. if i = j then [tt, b] else [x i, y i] ) rnn else
(map (λ i. if i = j then tt else x i) rnn @ map (λ i. if i = j then b else y i) rnn)));
lhssT = (if c2 then List.maps (λ i. [lhsT tt i, lhsT ff i]) nn else List.maps (λ b. map (lhsT b) nn) [tt,ff]);
lhss = (if c3 then [lhsF] @ lhssT else lhssT @ [lhsF])
in (C, D, lhss))"
definition "test_problem c n perms = (if c < 16 then testproblem c n
else let (C, D, lhss) = testproblem 0 n;
(permRow,permCol) = perms ! (c - 16);
permRows = map (λ i. lhss ! i) permRow;
pCol = (λ t. case t of Fun g ts ⇒ Fun g (map (λ i. ts ! i) permCol))
in (C, D, map pCol permRows))"
definition test_problem_integer where
"test_problem_integer c n perms = test_problem (nat_of_integer c) (nat_of_integer n) (map (map_prod (map nat_of_integer) (map nat_of_integer)) perms)"
fun term_to_haskell where
"term_to_haskell (Var x) = String.implode x"
| "term_to_haskell (Fun f ts) = (if f = ''tt'' then STR ''TT'' else if f = ''ff'' then STR ''FF'' else String.implode f)
+ foldr (λ t r. STR '' '' + term_to_haskell t + r) ts (STR '''')"
definition createHaskellInput :: "integer ⇒ integer ⇒ (integer list × integer list) list ⇒ String.literal" where
"createHaskellInput c n perms = (case test_problem_integer c n perms
of
(_,_,lhss) ⇒ STR ''module Test(g) where⏎⏎data B = TT | FF⏎⏎'' +
foldr (λ l s. (term_to_haskell l + STR '' = TT⏎'' + s)) lhss (STR ''''))"
definition pat_complete_alg_test :: "integer ⇒ integer ⇒ (integer list * integer list)list ⇒ bool" where
"pat_complete_alg_test c n perms = (case test_problem_integer c n perms of
(C,D,lhss) ⇒ pat_complete_alg C D lhss)"
definition show_pat_complete_test :: "integer ⇒ integer ⇒ (integer list * integer list)list ⇒ String.literal" where
"show_pat_complete_test c n perms = (case test_problem_integer c n perms of (_,_,lhss)
⇒ showsl_lines (STR ''empty'') lhss (STR ''''))"
definition create_agcp_input :: "(String.literal ⇒ 't) ⇒ integer ⇒ integer ⇒ (integer list * integer list)list ⇒
't list list * 't list list" where
"create_agcp_input term C N perms = (let
n = nat_of_integer N;
c = nat_of_integer C;
lhss = (snd o snd) (test_problem_integer C N perms);
tt = (λ t. case t of (Var x) ⇒ term (String.implode (''?'' @ x @ '':B''))
| Fun f [] ⇒ term (String.implode f));
pslist = map (λ i. tt (Var (''x'' @ show i))) [0..< 2 * n];
patlist = map (λ t. case t of Fun _ ps ⇒ map tt ps) lhss
in ([pslist], patlist))"
text ‹connection to AGCP, which is written in SML, and
SML-export of verified pattern completeness algorithm›
export_code
pat_complete_alg_test
show_pat_complete_test
create_agcp_input
pat_complete_alg
strong_quasi_reducible_alg
Var
in SML module_name Pat_Complete
text ‹tree automata encoding›
text ‹We assume that there are certain interface-functions from the tree-automata library.›
context
fixes cState :: "String.literal ⇒ 'state"
and cSym :: "String.literal ⇒ integer ⇒ 'sym"
and cRule :: "'sym ⇒ 'state list ⇒ 'state ⇒ 'rule"
and cAut :: "'sym list ⇒ 'state list ⇒ 'state list ⇒ 'rule list ⇒ 'aut"
and checkSubset :: "'aut ⇒ 'aut ⇒ bool"
begin
text ‹we further fix the parameters to generate the example TRSs›
context
fixes c n :: integer
and perms :: "(integer list × integer list) list"
begin
definition "tt = cSym (STR ''tt'') 0"
definition "ff = cSym (STR ''ff'') 0"
definition "g = cSym (STR ''g'') (2 * n)"
definition "qt = cState (STR ''qt'')"
definition "qf = cState (STR ''qf'')"
definition "qb = cState (STR ''qb'')"
definition "qfin = cState (STR ''qFin'')"
definition "tRule = (λ q. cRule tt [] q)"
definition "fRule = (λ q. cRule ff [] q)"
definition "qbRules = [tRule qb, fRule qb]"
definition "stdRules = qbRules @ [tRule qt, fRule qf]"
definition "leftStates = [qb, qfin]"
definition "rightStates = [qt, qf] @ leftStates"
definition "finStates = [qfin]"
definition "signature = [tt, ff, g]"
fun argToState where
"argToState (Var _) = qb"
| "argToState (Fun s []) = (if s = ''tt'' then qt else if s = ''ff'' then qf
else Code.abort (STR ''unknown'') (λ _. qf))"
fun termToRule where
"termToRule (Fun _ ts) = cRule g (map argToState ts) qfin"
definition "automataLeft = cAut signature leftStates finStates (cRule g (replicate (2 * nat_of_integer n) qb) qfin # qbRules)"
definition "automataRight = (case test_problem_integer c n perms of
(_,_,lhss) ⇒ cAut signature rightStates finStates (map termToRule lhss @ stdRules))"
definition "encodeAutomata = (automataLeft, automataRight)"
definition "patCompleteAutomataTest = (checkSubset automataLeft automataRight)"
end
end
definition string_append :: "String.literal ⇒ String.literal ⇒ String.literal" (infixr "+++" 65) where
"string_append s t = String.implode (String.explode s @ String.explode t)"
code_printing constant string_append ⇀
(Haskell) infixr 5 "++"
fun paren where
"paren e l r s [] = e"
| "paren e l r s (x # xs) = l +++ x +++ foldr (λ y r. s +++ y +++ r) xs r"
definition showAutomata where "showAutomata n c perms = (case encodeAutomata id (λ n a. n)
(λ f qs q. paren f (f +++ STR ''('') (STR '')'') (STR '','') qs +++ STR '' -> '' +++ q)
(λ sig Q Qfin rls.
STR ''tree-automata has final states: '' +++ paren (STR ''{}'') (STR ''{'') (STR ''}'') (STR '','') Qfin +++ STR ''⏎''
+++ STR ''and transitions:⏎'' +++ paren (STR '''') (STR '''') (STR '''') (STR ''⏎'') rls +++ STR ''⏎⏎'') n c perms
of (all,pats) ⇒ STR ''decide whether language of first automaton is subset of the second automaton⏎⏎''
+++ STR ''first '' +++ all +++ STR ''⏎and second '' +++ pats)"
value "showAutomata 4 4 []"
value "show_pat_complete_test 4 4 []"
value "createHaskellInput 4 4 []"
text ‹connection to FORT-h, generation of Haskell-examples, and Haskell tests of
verified pattern completeness algorithm›
export_code encodeAutomata
showAutomata
patCompleteAutomataTest
show_pat_complete_test
pat_complete_alg_test
createHaskellInput
in Haskell module_name Pat_Test_Generated
end