62 lines
1.7 KiB
Text
62 lines
1.7 KiB
Text
/-
|
||
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Author: Leonardo de Moura
|
||
-/
|
||
prelude
|
||
import init.data.list.basic
|
||
universes u
|
||
/--
|
||
A difference List is a Function that, given a List, returns the original
|
||
contents of the difference List prepended to the given List.
|
||
This structure supports `O(1)` `append` and `concat` operations on lists, making it
|
||
useful for append-heavy uses such as logging and pretty printing.
|
||
-/
|
||
structure DList (α : Type u) :=
|
||
(apply : List α → List α)
|
||
(invariant : ∀ l, apply l = apply [] ++ l)
|
||
|
||
namespace DList
|
||
variables {α : Type u}
|
||
open List
|
||
|
||
def ofList (l : List α) : DList α :=
|
||
⟨append l, fun t => (appendNil l).symm ▸ rfl⟩
|
||
|
||
def empty : DList α :=
|
||
⟨id, fun t => rfl⟩
|
||
|
||
instance : HasEmptyc (DList α) :=
|
||
⟨DList.empty⟩
|
||
|
||
def toList : DList α → List α
|
||
| ⟨f, h⟩ := f []
|
||
|
||
def singleton (a : α) : DList α :=
|
||
⟨fun t => a :: t,
|
||
fun t => rfl⟩
|
||
|
||
def cons : α → DList α → DList α
|
||
| a ⟨f, h⟩ :=
|
||
⟨fun t => a :: f t,
|
||
fun t =>
|
||
show a :: f t = a :: f [] ++ t from
|
||
have h₁ : a :: f t = a :: (f nil ++ t) := h t ▸ rfl;
|
||
have h₂ : a :: (f nil ++ t) = a :: f nil ++ t := (consAppend _ _ _).symm;
|
||
Eq.trans h₁ h₂⟩
|
||
|
||
def append : DList α → DList α → DList α
|
||
| ⟨f, h₁⟩ ⟨g, h₂⟩ :=
|
||
⟨f ∘ g, fun t =>
|
||
show f (g t) = (f (g [])) ++ t from
|
||
(h₁ (g [])).symm ▸ (appendAssoc (f []) (g []) t).symm ▸ h₂ t ▸ h₁ (g t) ▸ rfl⟩
|
||
|
||
def push : DList α → α → DList α
|
||
| ⟨f, h⟩ a :=
|
||
⟨fun t => f (a :: t),
|
||
fun t => (h (a::t)).symm ▸ (h [a]).symm ▸ (appendAssoc (f []) [a] t).symm ▸ rfl⟩
|
||
|
||
instance : HasAppend (DList α) :=
|
||
⟨DList.append⟩
|
||
|
||
end DList
|