Library EVMOpSem.Lem.lem_list
Require Import Arith.
Require Import Bool.
Require Import List.
Require Import String.
Require Import Program.Wf.
Require Import coqharness.
Open Scope nat_scope.
Open Scope string_scope.
Require Import lem_bool.
Require Export lem_bool.
Require Import lem_maybe.
Require Export lem_maybe.
Require Import lem_basic_classes.
Require Export lem_basic_classes.
Require Import lem_function.
Require Export lem_function.
Require Import lem_tuple.
Require Export lem_tuple.
Require Import lem_num.
Require Export lem_num.
Require Import Coq.Lists.List.
Require Export Coq.Lists.List.
Definition null {a : Type} (l : list a) : bool := match ( l) with [] => true | _ => false end.
Instance x145_Eq{a: Type} `{Eq a}: Eq (list a):= {
isEqual := (list_equal_by (fun x y => x = y));
isInequal l1 l2 := negb ((list_equal_by (fun x y => x = y) l1 l2))
}.
Program Fixpoint lexicographicCompareBy {a : Type} (cmp : a -> a -> ordering ) (l1 : list a) (l2 : list a) : ordering := match ( (l1,l2)) with
| ([], []) => EQ
| ([], _::_) => LT
| (_::_, []) => GT
| (x::xs, y::ys) =>
match ( cmp x y) with
| LT => LT
| GT => GT
| EQ => lexicographicCompareBy cmp xs ys
end
end.
Program Fixpoint lexicographicLessBy {a : Type} (less : a -> a -> bool ) (less_eq : a -> a -> bool ) (l1 : list a) (l2 : list a) : bool := match ( (l1,l2)) with
| ([], []) => false
| ([], _::_) => true
| (_::_, []) => false
| (x::xs, y::ys) => ((less x y) || ((less_eq x y) && (lexicographicLessBy less less_eq xs ys)))
end.
Program Fixpoint lexicographicLessEqBy {a : Type} (less : a -> a -> bool ) (less_eq : a -> a -> bool ) (l1 : list a) (l2 : list a) : bool := match ( (l1,l2)) with
| ([], []) => true
| ([], _::_) => true
| (_::_, []) => false
| (x::xs, y::ys) => (less x y || (less_eq x y && lexicographicLessEqBy less less_eq xs ys))
end.
Instance x144_Ord{a: Type} `{Ord a}: Ord (list a):= {
compare := (lexicographicCompareBy compare);
isLess := (lexicographicLessBy isLess isLessEqual);
isLessEqual := (lexicographicLessEqBy isLess isLessEqual);
isGreater x y := (lexicographicLessBy isLess isLessEqual y x);
isGreaterEqual x y := (lexicographicLessEqBy isLess isLessEqual y x)
}.
Program Fixpoint reverseAppend {a : Type} (l1 : list a) (l2 : list a) : list a:= match ( l1) with
| [] => l2
| x :: xs => reverseAppend xs (x :: l2)
end.
Program Fixpoint map_tr {a b : Type} (rev_acc : list b) (f : a -> b) (l : list a) : list b:= match ( l) with
| [] => List.rev rev_acc
| x :: xs => map_tr ((f x) :: rev_acc) f xs
end.
Program Fixpoint count_map {a b : Type} (f : a -> b) (l : list a) (ctr : nat ) : list b:=
match ( l) with
| [] => []
| hd :: tl => f hd ::
(if nat_ltb ctr( 5000%nat) then count_map f tl ( Coq.Init.Peano.plus ctr( 1%nat))
else map_tr [] f tl)
end.
Definition concat {a : Type} : list (list a) -> list a:= List.fold_right (@ List.app _) [].
Program Fixpoint dest_init_aux {a : Type} (rev_init : list a) (last_elem_seen : a) (to_process : list a) : (list a*a) % type:=
match ( to_process) with
| [] => (List.rev rev_init, last_elem_seen)
| x::xs => dest_init_aux (last_elem_seen::rev_init) x xs
end.
Definition dest_init {a : Type} (l : list a) : option ((list a*a) % type) := match ( l) with
| [] => None
| x::xs => Some (dest_init_aux [] x xs)
end.
Program Fixpoint index {a : Type} (l : list a) (n : nat ) : option a := match ( l) with
| [] => None
| x :: xs => if beq_nat n( 0%nat) then Some x else index xs (Coq.Init.Peano.minus n( 1%nat))
end.
Program Fixpoint findIndices_aux {a : Type} (i:nat ) (P : a -> bool ) (l : list a) : list (nat ):=
match ( l) with
| [] => []
| x :: xs => if P x then i :: findIndices_aux ( Coq.Init.Peano.plus i( 1%nat)) P xs else findIndices_aux ( Coq.Init.Peano.plus i( 1%nat)) P xs
end.
Definition findIndices {a : Type} (P : a -> bool ) (l : list a) : list (nat ):= findIndices_aux( 0%nat) P l.
Definition findIndex {a : Type} (P : a -> bool ) (l : list a) : option (nat ) := match ( findIndices P l) with
| [] => None
| x :: _ => Some x
end.
Program Fixpoint genlist {a : Type} (f : nat -> a) (n : nat ) : list a:=
match ( (n : nat )) with
| 0%nat => []
| S (n') => (@ List.app _)(genlist f n') [(f n')]
end.
Program Fixpoint replicate {a : Type} (n : nat ) (x : a) : list a:=
match ( n) with
| 0%nat => []
| S (n') => x :: replicate n' x
end.
Program Fixpoint splitAtAcc {a : Type} (revAcc : list a) (n : nat ) (l : list a) : (list a*list a) % type:=
match ( l) with
| [] => (List.rev revAcc, [])
| x::xs => if nat_lteb n( 0%nat) then (List.rev revAcc, l) else splitAtAcc (x::revAcc) (Coq.Init.Peano.minus n( 1%nat)) xs
end.
Definition splitAt {a : Type} (n : nat ) (l : list a) : (list a*list a) % type:=
splitAtAcc [] n l.
Definition take {a : Type} (n : nat ) (l : list a) : list a:= (@ fst _ _) (splitAt n l).
Definition drop {a : Type} (n : nat ) (l : list a) : list a:= (@ snd _ _) (splitAt n l).
Program Fixpoint splitWhile_tr {a : Type} (p : a -> bool ) (xs : list a) (acc : list a) : (list a*list a) % type:= match ( xs) with
| [] =>
(List.rev acc, [])
| x::xs =>
if p x then
splitWhile_tr p xs (x::acc)
else
(List.rev acc, (x::xs))
end.
Definition splitWhile {a : Type} (p : a -> bool ) (xs : list a) : (list a*list a) % type:= splitWhile_tr p xs [].
Definition takeWhile {a : Type} (p : a -> bool ) (l : list a) : list a:= (@ fst _ _) (splitWhile p l).
Definition dropWhile {a : Type} (p : a -> bool ) (l : list a) : list a:= (@ snd _ _) (splitWhile p l).
Program Fixpoint isPrefixOf {a : Type} `{Eq a} (l1 : list a) (l2 : list a) : bool := match ( (l1, l2)) with
| ([], _) => true
| (_::_, []) => false
| (x::xs, y::ys) => (x = y) && isPrefixOf xs ys
end.
Program Fixpoint update {a : Type} (l : list a) (n : nat ) (e : a) : list a:=
match ( l) with
| [] => []
| x :: xs => if beq_nat n( 0%nat) then e :: xs else x :: (update xs ( Coq.Init.Peano.minus n( 1%nat)) e)
end.
Definition elemBy {a : Type} (eq : a -> a -> bool ) (e : a) (l : list a) : bool := List.existsb (eq e) l.
Definition elem {a : Type} `{Eq a} : a -> list a -> bool := elemBy (fun x y => x = y).
Program Fixpoint find {a : Type} (P : a -> bool ) (l : list a) : option a := match ( l) with
| [] => None
| x :: xs => if P x then Some x else find P xs
end.
Definition lookupBy {a b : Type} (eq : a -> a -> bool ) (k : a) (m : list ((a*b) % type)) : option b := option_map (fun (x : (a*b) % type) => (@ snd _ _) x) (find (
fun (p : (a*b) % type) => match ( (p) ) with ( (k', _)) => eq k k' end) m).
Definition partition {a : Type} (P : a -> bool ) (l : list a) : (list a*list a) % type:= (List.filter P l, List.filter (fun (x : a) => negb (P x)) l).
Definition reversePartition {a : Type} (P : a -> bool ) (l : list a) : (list a*list a) % type:= partition P (List.rev l).
Program Fixpoint deleteFirst {a : Type} (P : a -> bool ) (l : list a) : option (list a) := match ( l) with
| [] => None
| x :: xs => if (P x) then Some xs else option_map (fun (xs' : list a) => x :: xs') (deleteFirst P xs)
end.
Definition deleteBy {a : Type} (eq : a -> a -> bool ) (x : a) (l : list a) : list a:= fromMaybe l (deleteFirst (eq x) l).
Program Fixpoint zip {a b : Type} (l1 : list a) (l2 : list b) : list ((a*b) % type):= match ( (l1, l2)) with
| (x :: xs, y :: ys) => (x, y) :: zip xs ys
| _ => []
end.
Program Fixpoint unzip {a b : Type} (l : list ((a*b) % type)) : (list a*list b) % type:= match ( l) with
| [] => ([], [])
| (x, y) :: xys =>
match ( unzip xys) with (xs, ys) => ((x :: xs), (y :: ys)) end
end.
Instance x143_SetType{a: Type} `{SetType a}: SetType (list a):= {
setElemCompare := lexicographicCompareBy setElemCompare
}.
Program Fixpoint allDistinct {a : Type} `{Eq a} (l : list a) : bool :=
match ( l) with
| [] => true
|( x::l') => negb (elem x l') && allDistinct l'
end.
Program Fixpoint mapMaybe {a b : Type} (f : a -> option b ) (xs : list a) : list b:=
match ( xs) with
| [] => []
| x::xs =>
match ( f x) with
| None => mapMaybe f xs
| Some y => y :: (mapMaybe f xs)
end
end.
Program Fixpoint mapiAux {a b : Type} (f : nat -> b -> a) (n : nat ) (l : list b) : list a:= match ( l) with
| [] => []
| x :: xs => (f n x) :: mapiAux f ( Coq.Init.Peano.plus n( 1%nat)) xs
end.
Definition mapi {a b : Type} (f : nat -> a -> b) (l : list a) : list b:= mapiAux f( 0%nat) l.
Definition deletes {a : Type} `{Eq a} (xs : list a) (ys : list a) : list a:=
List.fold_left (flip (deleteBy (fun x y => x = y))) ys xs.
Program Fixpoint catMaybes {a : Type} (xs : list (option a )) : list a:=
match ( xs) with
| [] =>
[]
|( None :: xs') =>
catMaybes xs'
|( Some x :: xs') =>
x :: catMaybes xs'
end.