Advertisement
Guest User

Untitled

a guest
Aug 21st, 2019
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.23 KB | None | 0 0
  1. /-
  2. Copyright (c) 2016 Microsoft Corporation. All rights reserved.
  3. Released under Apache 2.0 license as described in the file LICENSE.
  4. Author: Leonardo de Moura
  5. -/
  6. prelude
  7. import init.core init.data.nat.basic
  8. open Decidable List
  9.  
  10. universes u v w
  11.  
  12. instance (α : Type u) : Inhabited (List α) :=
  13. ⟨List.nil⟩
  14.  
  15. variables {α : Type u} {β : Type v} {γ : Type w}
  16.  
  17. namespace List
  18.  
  19. protected def hasDecEq [DecidableEq α] : ∀ (a b : List α), Decidable (a = b)
  20. | [], [] => isTrue rfl
  21. | a::as, [] => isFalse (fun h => List.noConfusion h)
  22. | [], b::bs => isFalse (fun h => List.noConfusion h)
  23. | a::as, b::bs =>
  24. match decEq a b with
  25. | isTrue hab =>
  26. match hasDecEq as bs with
  27. | isTrue habs => isTrue (Eq.subst hab (Eq.subst habs rfl))
  28. | isFalse nabs => isFalse (fun h => List.noConfusion h (fun _ habs => absurd habs nabs))
  29. | isFalse nab => isFalse (fun h => List.noConfusion h (fun hab _ => absurd hab nab))
  30.  
  31. instance [DecidableEq α] : DecidableEq (List α) :=
  32. {decEq := List.hasDecEq}
  33.  
  34. def reverseAux : List α → List α → List α
  35. | [], r => r
  36. | a::l, r => reverseAux l (a::r)
  37.  
  38. def reverse : List α → List α :=
  39. fun l => reverseAux l []
  40.  
  41. protected def append (as bs : List α) : List α :=
  42. reverseAux as.reverse bs
  43.  
  44. instance : HasAppend (List α) :=
  45. ⟨List.append⟩
  46.  
  47. theorem reverseAuxReverseAuxNil : ∀ (as bs : List α), reverseAux (reverseAux as bs) [] = reverseAux bs as
  48. | [], bs => rfl
  49. | a::as, bs =>
  50. show reverseAux (reverseAux as (a::bs)) [] = reverseAux bs (a::as) from
  51. reverseAuxReverseAuxNil as (a::bs)
  52.  
  53. theorem nilAppend (as : List α) : [] ++ as = as :=
  54. rfl
  55.  
  56. theorem appendNil (as : List α) : as ++ [] = as :=
  57. show reverseAux (reverseAux as []) [] = as from
  58. reverseAuxReverseAuxNil as []
  59.  
  60. theorem reverseAuxReverseAux : ∀ (as bs cs : List α), reverseAux (reverseAux as bs) cs = reverseAux bs (reverseAux (reverseAux as []) cs)
  61. | [], bs, cs => rfl
  62. | a::as, bs, cs =>
  63. Eq.trans
  64. (reverseAuxReverseAux as (a::bs) cs)
  65. (congrArg (fun b => reverseAux bs b) (reverseAuxReverseAux as [a] cs).symm)
  66.  
  67. theorem consAppend (a : α) (as bs : List α) : (a::as) ++ bs = a::(as ++ bs) :=
  68. reverseAuxReverseAux as [a] bs
  69.  
  70. theorem appendAssoc : ∀ (as bs cs : List α), (as ++ bs) ++ cs = as ++ (bs ++ cs)
  71. | [], bs, cs => rfl
  72. | a::as, bs, cs =>
  73. show ((a::as) ++ bs) ++ cs = (a::as) ++ (bs ++ cs) from
  74. have h₁ : ((a::as) ++ bs) ++ cs = a::(as++bs) ++ cs from congrArg (fun ds => ds ++ cs) (consAppend a as bs);
  75. have h₂ : a::(as++bs) ++ cs = a::((as++bs) ++ cs) from consAppend a (as++bs) cs;
  76. have h₃ : a::((as++bs) ++ cs) = a::(as ++ (bs ++ cs)) from congrArg (fun as => a::as) (appendAssoc as bs cs);
  77. have h₄ : a::(as ++ (bs ++ cs)) = (a::as ++ (bs ++ cs)) from (consAppend a as (bs++cs)).symm;
  78. Eq.trans (Eq.trans (Eq.trans h₁ h₂) h₃) h₄
  79.  
  80. instance : HasEmptyc (List α) :=
  81. ⟨List.nil⟩
  82.  
  83. protected def erase {α} [HasBeq α] : List α → α → List α
  84. | [], b => []
  85. | a::as, b => match a == b with
  86. | true => as
  87. | false => a :: erase as b
  88.  
  89. def eraseIdx : List α → Nat → List α
  90. | [], _ => []
  91. | a::as, 0 => as
  92. | a::as, n+1 => a :: eraseIdx as n
  93.  
  94. def lengthAux : List α → Nat → Nat
  95. | [], n => n
  96. | a::as, n => lengthAux as (n+1)
  97.  
  98. def length (as : List α) : Nat :=
  99. lengthAux as 0
  100.  
  101. def isEmpty : List α → Bool
  102. | [] => true
  103. | _ :: _ => false
  104.  
  105. def get [Inhabited α] : Nat → List α → α
  106. | 0, a::as => a
  107. | n+1, a::as => get n as
  108. | _, _ => default α
  109.  
  110. def getOpt : Nat → List α → Option α
  111. | 0, a::as => some a
  112. | n+1, a::as => getOpt n as
  113. | _, _ => none
  114.  
  115. def set : List α → Nat → α → List α
  116. | a::as, 0, b => b::as
  117. | a::as, n+1, b => a::(set as n b)
  118. | [], _, _ => []
  119.  
  120. def head [Inhabited α] : List α → α
  121. | [] => default α
  122. | a::_ => a
  123.  
  124. def tail : List α → List α
  125. | [] => []
  126. | a::as => as
  127.  
  128. @[specialize] def map (f : α → β) : List α → List β
  129. | [] => []
  130. | a::as => f a :: map as
  131.  
  132. @[specialize] def map₂ (f : α → β → γ) : List α → List β → List γ
  133. | [], _ => []
  134. | _, [] => []
  135. | a::as, b::bs => f a b :: map₂ as bs
  136.  
  137. def join : List (List α) → List α
  138. | [] => []
  139. | a :: as => a ++ join as
  140.  
  141. @[specialize] def filterMap (f : α → Option β) : List α → List β
  142. | [] => []
  143. | a::as =>
  144. match f a with
  145. | none => filterMap as
  146. | some b => b :: filterMap as
  147.  
  148. @[specialize] def filterAux (p : α → Bool) : List α → List α → List α
  149. | [], rs => rs.reverse
  150. | a::as, rs => match p a with
  151. | true => filterAux as (a::rs)
  152. | false => filterAux as rs
  153.  
  154. @[inline] def filter (p : α → Bool) (as : List α) : List α :=
  155. filterAux p as []
  156.  
  157. @[specialize] def partitionAux (p : α → Bool) : List α → List α × List α → List α × List α
  158. | [], (bs, cs) => (bs.reverse, cs.reverse)
  159. | a::as, (bs, cs) =>
  160. match p a with
  161. | true => partitionAux as (a::bs, cs)
  162. | false => partitionAux as (bs, a::cs)
  163.  
  164. @[inline] def partition (p : α → Bool) (as : List α) : List α × List α :=
  165. partitionAux p as ([], [])
  166.  
  167. def dropWhile (p : α → Bool) : List α → List α
  168. | [] => []
  169. | a::l => match p a with
  170. | true => dropWhile l
  171. | false => a::l
  172.  
  173. def find (p : α → Bool) : List α → Option α
  174. | [] => none
  175. | a::as => match p a with
  176. | true => some a
  177. | false => find as
  178.  
  179. def elem [HasBeq α] (a : α) : List α → Bool
  180. | [] => false
  181. | b::bs => match a == b with
  182. | true => true
  183. | false => elem bs
  184.  
  185. def notElem [HasBeq α] (a : α) (as : List α) : Bool :=
  186. !(as.elem a)
  187.  
  188. def eraseDupsAux {α} [HasBeq α] : List α → List α → List α
  189. | [], bs => bs.reverse
  190. | a::as, bs => match bs.elem a with
  191. | true => eraseDupsAux as bs
  192. | false => eraseDupsAux as (a::bs)
  193.  
  194. def eraseDups {α} [HasBeq α] (as : List α) : List α :=
  195. eraseDupsAux as []
  196.  
  197. @[specialize] def spanAux (p : α → Bool) : List α → List α → List α × List α
  198. | [], rs => (rs.reverse, [])
  199. | a::as, rs => match p a with
  200. | true => spanAux as (a::rs)
  201. | false => (rs.reverse, a::as)
  202.  
  203. @[inline] def span (p : α → Bool) (as : List α) : List α × List α :=
  204. spanAux p as []
  205.  
  206. def lookup [HasBeq α] : α → List (α × β) → Option β
  207. | _, [] => none
  208. | a, (k,b)::es => match a == k with
  209. | true => some b
  210. | false => lookup a es
  211.  
  212. def removeAll [HasBeq α] (xs ys : List α) : List α :=
  213. xs.filter (fun x => ys.notElem x)
  214.  
  215. def drop : Nat → List α → List α
  216. | 0, a => a
  217. | n+1, [] => []
  218. | n+1, a::as => drop n as
  219.  
  220. def take : Nat → List α → List α
  221. | 0, a => []
  222. | n+1, [] => []
  223. | n+1, a::as => a :: take n as
  224.  
  225. @[specialize] def foldl (f : α → β → α) : α → List β → α
  226. | a, [] => a
  227. | a, b :: l => foldl (f a b) l
  228.  
  229. @[specialize] def foldr (f : α → β → β) (b : β) : List α → β
  230. | [] => b
  231. | a :: l => f a (foldr l)
  232.  
  233. @[specialize] def foldr1 (f : α → α → α) : ∀ (xs : List α), xs ≠ [] → α
  234. | [], h => absurd rfl h
  235. | [a], _ => a
  236. | a :: as@(_::_), _ => f a (foldr1 as (fun h => List.noConfusion h))
  237.  
  238. @[specialize] def foldr1Opt (f : α → α → α) : List α → Option α
  239. | [] => none
  240. | a :: as => some $ foldr1 f (a :: as) (fun h => List.noConfusion h)
  241.  
  242. @[inline] def any (l : List α) (p : α → Bool) : Bool :=
  243. foldr (fun a r => p a || r) false l
  244.  
  245. @[inline] def all (l : List α) (p : α → Bool) : Bool :=
  246. foldr (fun a r => p a && r) true l
  247.  
  248. def or (bs : List Bool) : Bool := bs.any id
  249.  
  250. def and (bs : List Bool) : Bool := bs.all id
  251.  
  252. def zipWith (f : α → β → γ) : List α → List β → List γ
  253. | x::xs, y::ys => f x y :: zipWith xs ys
  254. | _, _ => []
  255.  
  256. def zip : List α → List β → List (Prod α β) :=
  257. zipWith Prod.mk
  258.  
  259. def unzip : List (α × β) → List α × List β
  260. | [] => ([], [])
  261. | (a, b) :: t => match unzip t with | (al, bl) => (a::al, b::bl)
  262.  
  263. def replicate (n : Nat) (a : α) : List α :=
  264. n.repeat (fun xs => a :: xs) []
  265.  
  266. def rangeAux : Nat → List Nat → List Nat
  267. | 0, ns => ns
  268. | n+1, ns => rangeAux n (n::ns)
  269.  
  270. def range (n : Nat) : List Nat :=
  271. rangeAux n []
  272.  
  273. def iota : Nat → List Nat
  274. | 0 => []
  275. | m@(n+1) => m :: iota n
  276.  
  277. def enumFrom : Nat → List α → List (Nat × α)
  278. | n, [] => nil
  279. | n, x :: xs => (n, x) :: enumFrom (n + 1) xs
  280.  
  281. def enum : List α → List (Nat × α) := enumFrom 0
  282.  
  283. def getLastOfNonNil : ∀ (as : List α), as ≠ [] → α
  284. | [], h => absurd rfl h
  285. | [a], h => a
  286. | a::b::as, h => getLastOfNonNil (b::as) (fun h => List.noConfusion h)
  287.  
  288. def getLast [Inhabited α] : List α → α
  289. | [] => arbitrary α
  290. | a::as => getLastOfNonNil (a::as) (fun h => List.noConfusion h)
  291.  
  292. def init : List α → List α
  293. | [] => []
  294. | [a] => []
  295. | a::l => a::init l
  296.  
  297. def intersperse (sep : α) : List α → List α
  298. | [] => []
  299. | [x] => [x]
  300. | x::xs => x::sep::intersperse xs
  301.  
  302. def intercalate (sep : List α) (xs : List (List α)) : List α :=
  303. join (intersperse sep xs)
  304.  
  305. @[inline] protected def bind {α : Type u} {β : Type v} (a : List α) (b : α → List β) : List β :=
  306. join (map b a)
  307.  
  308. @[inline] protected def pure {α : Type u} (a : α) : List α :=
  309. [a]
  310.  
  311. inductive Less [HasLess α] : List α → List α → Prop
  312. | nil (b : α) (bs : List α) : Less [] (b::bs)
  313. | head {a : α} (as : List α) {b : α} (bs : List α) : a < b → Less (a::as) (b::bs)
  314. | tail {a : α} {as : List α} {b : α} {bs : List α} : ¬ a < b → ¬ b < a → Less as bs → Less (a::as) (b::bs)
  315.  
  316. instance [HasLess α] : HasLess (List α) :=
  317. ⟨List.Less⟩
  318.  
  319. instance hasDecidableLt [HasLess α] [h : DecidableRel HasLess.Less] : ∀ (l₁ l₂ : List α), Decidable (l₁ < l₂)
  320. | [], [] => isFalse (fun h => nomatch h)
  321. | [], b::bs => isTrue (Less.nil _ _)
  322. | a::as, [] => isFalse (fun h => nomatch h)
  323. | a::as, b::bs =>
  324. match h a b with
  325. | isTrue h₁ => isTrue (Less.head _ _ h₁)
  326. | isFalse h₁ =>
  327. match h b a with
  328. | isTrue h₂ => isFalse (fun h => match h with
  329. | Less.head _ _ h₁' => absurd h₁' h₁
  330. | Less.tail _ h₂' _ => absurd h₂ h₂')
  331. | isFalse h₂ =>
  332. match hasDecidableLt as bs with
  333. | isTrue h₃ => isTrue (Less.tail h₁ h₂ h₃)
  334. | isFalse h₃ => isFalse (fun h => match h with
  335. | Less.head _ _ h₁' => absurd h₁' h₁
  336. | Less.tail _ _ h₃' => absurd h₃' h₃)
  337.  
  338. @[reducible] protected def LessEq [HasLess α] (a b : List α) : Prop :=
  339. ¬ b < a
  340.  
  341. instance [HasLess α] : HasLessEq (List α) :=
  342. ⟨List.LessEq⟩
  343.  
  344. instance hasDecidableLe [HasLess α] [h : DecidableRel (HasLess.Less : α → α → Prop)] : ∀ (l₁ l₂ : List α), Decidable (l₁ ≤ l₂) :=
  345. fun a b => Not.Decidable
  346.  
  347. /-- `isPrefixOf l₁ l₂` returns `true` Iff `l₁` is a prefix of `l₂`. -/
  348. def isPrefixOf [HasBeq α] : List α → List α → Bool
  349. | [], _ => true
  350. | _, [] => false
  351. | a::as, b::bs => a == b && isPrefixOf as bs
  352.  
  353. /-- `isSuffixOf l₁ l₂` returns `true` Iff `l₁` is a suffix of `l₂`. -/
  354. def isSuffixOf [HasBeq α] (l₁ l₂ : List α) : Bool :=
  355. isPrefixOf l₁.reverse l₂.reverse
  356.  
  357. @[specialize] def isEqv : List α → List α → (α → α → Bool) → Bool
  358. | [], [], _ => true
  359. | a::as, b::bs, eqv => eqv a b && isEqv as bs eqv
  360. | _, _, eqv => false
  361. end List
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement