-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpan.v
101 lines (80 loc) · 2.59 KB
/
Span.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(** * Span *)
(** similar to span from Haskell's <a
href="https://hackage.haskell.org/package/base-4.16.1.0/docs/Data-List.html">Data.List</a>,
but written as an [Alg]. *)
(* Coq *)
Require Import Coq.Lists.List.
Import ListNotations.
(* Ours *)
Require Import Dc.
Require Import Kinds.
Require Import Functors.
Require Import List.List.
Section Span.
Variable A : Set.
Variable eqb : A -> A -> bool.
Definition SpanF(X : Set) : Set := list A * X.
Definition spanFmap{Y Z : Set} : FmapT Y Z SpanF :=
fun f c =>
let (x , y) := c in
(x, f y).
Lemma SpanFunctorId : FmapId SpanF (@spanFmap).
intros B d.
destruct d; trivial.
Qed.
Global Instance SpanFunctor : Functor SpanF :=
{
fmap := (@spanFmap);
fmapId := SpanFunctorId
}.
Definition SpanSAlg(p : A -> bool)
: ListSAlg A SpanF :=
rollSAlg
(fun P R up sfo abstIn span xs =>
match xs with
Nil => ([], abstIn xs)
| Cons x xs' =>
if p x
then let (r,s) := span xs' in (x :: r, up s)
else ([], abstIn xs)
end).
Definition spanr{R : Set}(sfo:ListSFoldT A R)
(p : A -> bool)(xs : R) : SpanF R :=
sfo SpanF SpanFunctor (SpanSAlg p) xs.
Definition span(p : A -> bool)(xs : List A) : SpanF (List A) :=
spanr (sfold (ListF A)) p xs.
(** intended just for testing below *)
Definition spanl(p : A -> bool)(xs : list A) : list A * list A :=
let (l,r) := span p (toList xs) in
(l,fromList r).
Definition dropWhiler{R : Set}(sfo:ListSFoldT A R)
(p : A -> bool)(xs : R) : R :=
snd (spanr sfo p xs).
Definition dropWhile(p : A -> bool)(xs : List A) : List A :=
dropWhiler (sfold (ListF A)) p xs.
Definition breakr{R : Set}(sfo : ListSFoldT A R)
(p : A -> bool)(xs : R) : list A * R :=
(spanr sfo (fun x => negb (p x)) xs).
Definition break(p : A -> bool)(xs : List A) : list A * List A :=
breakr (sfold (ListF A)) p xs.
End Span.
Arguments spanr{A}{R}.
Arguments span{A}.
Arguments dropWhiler{A}{R}.
Arguments dropWhile{A}.
Arguments breakr{A}{R}.
Arguments break{A}.
(** Common tactics *)
Ltac foldSpan :=
repeat (match goal with
| |- context[sfold ?F ?SF ?SFun (SpanSAlg ?A ?p) ?t] =>
change (sfold F SF SFun (SpanSAlg A p) t) with (span p t)
end).
(* testcases
Definition test := spanl nat (eqb 1) (1 :: 1 :: 2 :: 2 :: 1 :: 3 :: 5 :: []).
Definition test2 := spanl nat (eqb 0) (1 :: 1 :: 2 :: 2 :: 1 :: 3 :: 5 :: []).
Definition test3 := spanl nat (eqb 0) (0 :: 0 :: 0 :: []).
Eval compute in test.
Eval compute in test2.
Eval compute in test3.
*)