@@ -14,10 +14,16 @@ coinductive seq (α : Type u) : Type u
14
14
| cons : α → seq α → seq α
15
15
-/
16
16
17
+ /--
18
+ A stream `s : option α` is a sequence if `s.nth n = none` implies `s.nth (n + 1) = none`.
19
+ -/
20
+ def stream.is_seq {α : Type u} (s : stream (option α)) : Prop :=
21
+ ∀ {n : ℕ}, s n = none → s (n + 1 ) = none
22
+
17
23
/-- `seq α` is the type of possibly infinite lists (referred here as sequences).
18
24
It is encoded as an infinite stream of options such that if `f n = none`, then
19
25
`f m = none` for all `m ≥ n`. -/
20
- def seq (α : Type u) : Type u := { f : stream (option α) // ∀ {n}, f n = none → f (n+ 1 ) = none }
26
+ def seq (α : Type u) : Type u := { f : stream (option α) // f.is_seq }
21
27
22
28
/-- `seq1 α` is the type of nonempty sequences. -/
23
29
def seq1 (α) := α × seq α
@@ -56,6 +62,17 @@ theorem le_stable (s : seq α) {m n} (h : m ≤ n) :
56
62
s.1 m = none → s.1 n = none :=
57
63
by {cases s with f al, induction h with n h IH, exacts [id, λ h2, al (IH h2)]}
58
64
65
+ /--
66
+ If `s.nth n = some aₙ` for some value `aₙ`, then there is also some value `aₘ` such
67
+ that `s.nth = some aₘ` for `m ≤ n`.
68
+ -/
69
+ lemma ge_stable (s : seq α) {aₙ : α} {n m : ℕ} (m_le_n : m ≤ n)
70
+ (s_nth_eq_some : s.nth n = some aₙ) :
71
+ ∃ (aₘ : α), s.nth m = some aₘ :=
72
+ have s.nth n ≠ none, by simp [s_nth_eq_some],
73
+ have s.nth m ≠ none, from mt (s.le_stable m_le_n) this ,
74
+ with_one.ne_one_iff_exists.elim_left this
75
+
59
76
theorem not_mem_nil (a : α) : a ∉ @nil α :=
60
77
λ ⟨n, (h : some a = none)⟩, by injection h
61
78
281
298
run on an infinite sequence. -/
282
299
meta def force_to_list (s : seq α) : list α := (to_lazy_list s).to_list
283
300
301
+ /-- The sequence of natural numbers some 0, some 1, ... -/
302
+ def nats : seq ℕ := stream.nats
303
+
304
+ @[simp]
305
+ lemma nats_nth (n : ℕ) : nats.nth n = some n := rfl
306
+
284
307
/-- Append two sequences. If `s₁` is infinite, then `s₁ ++ s₂ = s₁`,
285
308
otherwise it puts `s₂` at the location of the `nil` in `s₁`. -/
286
309
def append (s₁ s₂ : seq α) : seq α :=
@@ -335,6 +358,8 @@ def split_at : ℕ → seq α → list α × seq α
335
358
| some (x, s') := let (l, r) := split_at n s' in (list.cons x l, r)
336
359
end
337
360
361
+ section zip_with
362
+
338
363
/-- Combine two sequences with a function -/
339
364
def zip_with (f : α → β → γ) : seq α → seq β → seq γ
340
365
| ⟨f₁, a₁⟩ ⟨f₂, a₂⟩ := ⟨λn,
@@ -344,12 +369,47 @@ def zip_with (f : α → β → γ) : seq α → seq β → seq γ
344
369
end ,
345
370
λn, begin
346
371
induction h1 : f₁ n,
347
- { intro H, rw a₁ h1, refl },
372
+ { intro H, simp only [( a₁ h1)] , refl },
348
373
induction h2 : f₂ n; dsimp [seq.zip_with._match_1]; intro H,
349
- { rw a₂ h2, cases f₁ (n + 1 ); refl },
350
- { contradiction }
374
+ { rw ( a₂ h2) , cases f₁ (n + 1 ); refl },
375
+ { rw [h1, h2] at H, contradiction }
351
376
end ⟩
352
377
378
+ variables {s : seq α} {s' : seq β} {n : ℕ}
379
+
380
+ lemma zip_with_nth_some {a : α} {b : β} (s_nth_eq_some : s.nth n = some a)
381
+ (s_nth_eq_some' : s'.nth n = some b) (f : α → β → γ) :
382
+ (zip_with f s s').nth n = some (f a b) :=
383
+ begin
384
+ cases s with st,
385
+ have : st n = some a, from s_nth_eq_some,
386
+ cases s' with st',
387
+ have : st' n = some b, from s_nth_eq_some',
388
+ simp only [zip_with, seq.nth, *]
389
+ end
390
+
391
+ lemma zip_with_nth_none (s_nth_eq_none : s.nth n = none) (f : α → β → γ) :
392
+ (zip_with f s s').nth n = none :=
393
+ begin
394
+ cases s with st,
395
+ have : st n = none, from s_nth_eq_none,
396
+ cases s' with st',
397
+ cases st'_nth_eq : st' n;
398
+ simp only [zip_with, seq.nth, *]
399
+ end
400
+
401
+ lemma zip_with_nth_none' (s'_nth_eq_none : s'.nth n = none) (f : α → β → γ) :
402
+ (zip_with f s s').nth n = none :=
403
+ begin
404
+ cases s' with st',
405
+ have : st' n = none, from s'_nth_eq_none,
406
+ cases s with st,
407
+ cases st_nth_eq : st n;
408
+ simp only [zip_with, seq.nth, *]
409
+ end
410
+
411
+ end zip_with
412
+
353
413
/-- Pair two sequences into a sequence of pairs -/
354
414
def zip : seq α → seq β → seq (α × β) := zip_with prod.mk
355
415
@@ -549,6 +609,24 @@ by rw add_comm; symmetry; apply dropn_add
549
609
theorem nth_tail : ∀ (s : seq α) n, nth (tail s) n = nth s (n + 1 )
550
610
| ⟨f, al⟩ n := rfl
551
611
612
+ @[extensionality]
613
+ protected lemma ext (s s': seq α) (hyp : ∀ (n : ℕ), s.nth n = s'.nth n) : s = s' :=
614
+ begin
615
+ let ext := (λ (s s' : seq α), ∀ n, s.nth n = s'.nth n),
616
+ apply seq.eq_of_bisim ext _ hyp,
617
+ -- we have to show that ext is a bisimulation
618
+ clear hyp s s',
619
+ assume s s' (hyp : ext s s'),
620
+ unfold seq.destruct,
621
+ rw (hyp 0 ),
622
+ cases (s'.nth 0 ),
623
+ { simp [seq.bisim_o] }, -- option.none
624
+ { -- option.some
625
+ suffices : ext s.tail s'.tail, by simpa,
626
+ assume n,
627
+ simp only [seq.nth_tail _ n, (hyp $ n + 1 )] }
628
+ end
629
+
552
630
@[simp] theorem head_dropn (s : seq α) (n) : head (drop s n) = nth s n :=
553
631
begin
554
632
induction n with n IH generalizing s, { refl },
0 commit comments