Theory Pattern_Completeness_List
section ‹A List-Based Implementation to Decide Pattern Completeness›
theory Pattern_Completeness_List
  imports 
    Pattern_Completeness_Multiset
    Compute_Nonempty_Infinite_Sorts
    Finite_IDL_Solver_Interface
    "HOL-Library.AList" 
    "HOL-Library.Mapping" 
    Singleton_List
begin
subsection ‹Definition of Algorithm›
text ‹We refine the non-deterministic multiset based implementation
  to a deterministic one which uses lists as underlying data-structure.
  For matching problems we distinguish several different shapes.›
type_synonym ('a,'b)alist = "('a × 'b)list"
type_synonym ('f,'v,'s)match_problem_list = "(('f,nat × 's)term × ('f,'v)term) list" 
type_synonym ('f,'v,'s)match_problem_lx = "((nat × 's) × ('f,'v)term) list"  
type_synonym ('f,'v,'s)match_problem_rx = "('v,('f,nat × 's)term list) alist × bool" 
type_synonym ('f,'v,'s)match_problem_fvf = "('v,(nat × 's) list) alist" 
type_synonym ('f,'v,'s)match_problem_lr = "('f,'v,'s)match_problem_lx × ('f,'v,'s)match_problem_rx" 
type_synonym ('f,'v,'s)pat_problem_list = "('f,'v,'s)match_problem_list list" 
type_synonym ('f,'v,'s)pat_problem_lr = "('f,'v,'s)match_problem_lr list" 
type_synonym ('f,'v,'s)pat_problem_lx = "('f,'v,'s)match_problem_lx list" 
type_synonym ('f,'v,'s)pat_problem_fvf = "('f,'v,'s)match_problem_fvf list" 
type_synonym ('f,'v,'s)pats_problem_list = "('f,'v,'s)pat_problem_list list" 
type_synonym ('f,'v,'s)pat_problem_set_impl = "(('f,nat × 's)term × ('f,'v)term) list list" 
definition lvars_mp :: "('f,'v,'s)match_problem_mset ⇒ 'v set" where
  "lvars_mp mp = (⋃ (vars ` snd ` mp_mset mp))" 
definition vars_mp_mset :: "('f,'v,'s)match_problem_mset ⇒ 'v multiset" where
  "vars_mp_mset mp = sum_mset (image_mset (vars_term_ms o snd) mp)" 
definition ll_mp :: "('f,'v,'s)match_problem_mset ⇒ bool" where
  "ll_mp mp = (∀ x. count (vars_mp_mset mp) x ≤ 1)"  
definition ll_pp :: "('f,'v,'s)pat_problem_list ⇒ bool" where
  "ll_pp p = (∀ mp ∈ set p. ll_mp (mset mp))"  
definition lvars_pp :: "('f,'v,'s)pat_problem_mset ⇒ 'v set" where
  "lvars_pp pp = (⋃ (lvars_mp ` set_mset pp))" 
abbreviation mp_list :: "('f,'v,'s)match_problem_list ⇒ ('f,'v,'s)match_problem_mset" 
  where "mp_list ≡ mset" 
abbreviation mp_lx :: "('f,'v,'s)match_problem_lx ⇒ ('f,'v,'s)match_problem_list" 
  where "mp_lx ≡ map (map_prod Var id)" 
definition mp_rx :: "('f,'v,'s)match_problem_rx ⇒ ('f,'v,'s)match_problem_mset"
  where "mp_rx mp = mset (List.maps (λ (x,ts). map (λ t. (t,Var x)) ts) (fst mp))" 
definition mp_rx_list :: "('f,'v,'s)match_problem_rx ⇒ ('f,'v,'s)match_problem_list"
  where "mp_rx_list mp = List.maps (λ (x,ts). map (λ t. (t,Var x)) ts) (fst mp)" 
definition mp_lr :: "('f,'v,'s)match_problem_lr ⇒ ('f,'v,'s)match_problem_mset"
  where "mp_lr pair = (case pair of (lx,rx) ⇒ mp_list (mp_lx lx) + mp_rx rx)" 
definition mp_lr_list :: "('f,'v,'s)match_problem_lr ⇒ ('f,'v,'s)match_problem_list"
  where "mp_lr_list pair = (case pair of (lx,rx) ⇒ mp_lx lx @ mp_rx_list rx)" 
definition pat_lr :: "('f,'v,'s)pat_problem_lr ⇒ ('f,'v,'s)pat_problem_mset"
  where "pat_lr ps = mset (map mp_lr ps)" 
definition pat_lx :: "('f,'v,'s)pat_problem_lx ⇒ ('f,'v,'s)pat_problem_mset"
  where "pat_lx ps = mset (map (mp_list o mp_lx) ps)" 
definition pat_mset_list :: "('f,'v,'s)pat_problem_list ⇒ ('f,'v,'s)pat_problem_mset"
  where "pat_mset_list ps = mset (map mp_list ps)" 
definition pat_list :: "('f,'v,'s)pat_problem_list ⇒ ('f,'v,'s)pat_problem_set"
  where "pat_list ps = set ` set ps" 
abbreviation pats_mset_list :: "('f,'v,'s)pats_problem_list ⇒ ('f,'v,'s)pats_problem_mset" 
  where "pats_mset_list ≡ mset o map pat_mset_list" 
 
definition subst_match_problem_list :: "('f,nat × 's)subst ⇒ ('f,'v,'s)match_problem_list ⇒ ('f,'v,'s)match_problem_list" where
  "subst_match_problem_list τ = map (subst_left τ)" 
definition subst_pat_problem_list :: "('f,nat × 's)subst ⇒ ('f,'v,'s)pat_problem_list ⇒ ('f,'v,'s)pat_problem_list" where
  "subst_pat_problem_list τ = map (subst_match_problem_list τ)" 
definition match_var_impl :: "('f,'v,'s)match_problem_lr ⇒ 'v list × ('f,'v,'s)match_problem_lr" where
  "match_var_impl mp = (case mp of (xl,(rx,b)) ⇒
     let xs = remdups (List.maps (vars_term_list o snd) xl)
     in (xs,(xl,(filter (λ (x,ts). tl ts ≠ [] ∨ x ∈ set xs) rx),b)))" 
definition find_var :: "bool ⇒ ('f,'v,'s)match_problem_lr list ⇒ _" where 
  "find_var improved p = (case List.maps (λ (lx,_). lx) p of
      (x,t) # _ ⇒ Some x
    | [] ⇒ if improved then (let flat_mps = List.maps (fst o snd) p in 
       (map_option (λ (x,ts). case find is_Var ts of Some (Var x) ⇒ x)
       (find (λ rx. ∃ t ∈ set (snd rx). is_Fun t) flat_mps)))
       else Some (let (_,rx,b) = hd p
         in case hd rx of (x, s # t # _) ⇒ hd (the (conflicts s t))))" 
definition empty_lr :: "('f,'v,'s)match_problem_lr ⇒ bool" where
  "empty_lr mp = (case mp of (lx,rx,_) ⇒ lx = [] ∧ rx  = [])" 
fun zipAll :: "'a list ⇒ 'b list list ⇒ ('a × 'b list) list" where
  "zipAll [] _ = []" 
| "zipAll (x # xs) yss = (x, map hd yss) # zipAll xs (map tl yss)"