~/bend-docscommunity

list.bend checks

raw source on the hub · import bend-mathlib@0.7.2.0/list.bend as MList

bend-mathlib/list.bend: List lemmas (append, reverse, length, take, drop, map, fold, filter).

3 imports
import Base
import ./nat.bend as MNat
import ./bool.bend as MBool

Laws

law append_nil provedsource · line 7 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.append(a, A, xs, []) == xs : List<a, A>}

The empty list is a right identity for append: xs ++ [] = xs.

law nil_append provedsource · line 22 · raw

@-a:Quant -> @-A:Kind(a) -> @-xs:List<a, A> -> {List.append(a, A, [], xs) == xs : List<a, A>}

The empty list is a left identity for append: [] ++ xs = xs.

law append_assoc provedsource · line 32 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-zs:List<a, A> -> {List.append(a, A, List.append(a, A, xs, ys), zs) == List.append(a, A, xs, List.append(a, A, ys, zs)) : List<a, A>}

Append is associative: (xs ++ ys) ++ zs = xs ++ (ys ++ zs).

law length_append provedsource · line 49 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {List.length(a, A, List.append(a, A, xs, ys)) == Nat.add(List.length(a, A, xs), List.length(a, A, ys)) : Nat}

The length of an append is the sum of the lengths.

law reverse_go_spec provedsource · line 72 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-acc:List<a, A> -> {List.reverse.go(a, A, xs, acc) == List.append(a, A, List.reverse(a, A, xs), acc) : List<a, A>}

The reverse accumulator loop appends the reversed list to the accumulator.

law reverse_append provedsource · line 94 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {List.reverse(a, A, List.append(a, A, xs, ys)) == List.append(a, A, List.reverse(a, A, ys), List.reverse(a, A, xs)) : List<a, A>}

Reversing an append reverses and swaps the parts: reverse (xs ++ ys) = reverse ys ++ reverse xs.

law reverse_reverse provedsource · line 112 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.reverse(a, A, List.reverse(a, A, xs)) == xs : List<a, A>}

Reversing twice gives the list back.

law length_reverse provedsource · line 131 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.length(a, A, List.reverse(a, A, xs)) == List.length(a, A, xs) : Nat}

Reversing preserves the length.

law foldr_append provedsource · line 141 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:A -> @_:B -> B) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-z:B -> {List.foldr(a, A, B, f, List.append(a, A, xs, ys), z) == List.foldr(a, A, B, f, xs, List.foldr(a, A, B, f, ys, z)) : B}

A right fold over an append folds the first part onto the fold of the second.

law take_append_drop provedsource · line 160 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {List.append(a, A, List.take(a, A, xs, n), List.drop(a, A, xs, n)) == xs : List<a, A>}

Taking n elements and appending the rest after dropping n gives the list back.

law length_map provedsource · line 178 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.length(&1, B, List.map(A, B, f, xs)) == List.length(&1, A, xs) : Nat}

Mapping preserves the length.

law map_append provedsource · line 194 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @-ys:List<&1, A> -> {List.map(A, B, f, List.append(&1, A, xs, ys)) == List.append(&1, B, List.map(A, B, f, xs), List.map(A, B, f, ys)) : List<&1, B>}

Mapping over an append maps each part: map f (xs ++ ys) = map f xs ++ map f ys.

law map_map provedsource · line 211 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:B -> C) -> @xs:List<&1, A> -> {List.map(B, C, g, List.map(A, B, f, xs)) == List.map(A, C, x => g(f(x)), xs) : List<&1, C>}

Mapping twice is mapping the composition: map g (map f xs) = map (g . f) xs.

law take_zero provedsource · line 229 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.take(a, A, xs, 0n) == [] : List<a, A>}

Taking zero elements gives the empty list.

law drop_zero provedsource · line 243 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.drop(a, A, xs, 0n) == xs : List<a, A>}

Dropping zero elements gives the list back.

law take_nil provedsource · line 257 · raw

@-a:Quant -> @-A:Kind(a) -> @-n:Nat -> {List.take(a, A, [], n) == [] : List<a, A>}

Taking from the empty list gives the empty list.

law drop_nil provedsource · line 267 · raw

@-a:Quant -> @-A:Kind(a) -> @-n:Nat -> {List.drop(a, A, [], n) == [] : List<a, A>}

Dropping from the empty list gives the empty list.

law length_take provedsource · line 277 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {List.length(a, A, List.take(a, A, xs, n)) == Nat.min(n, List.length(a, A, xs)) : Nat}

Taking n elements leaves min(n, length) of them.

law length_drop provedsource · line 295 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {List.length(a, A, List.drop(a, A, xs, n)) == Nat.sub(List.length(a, A, xs), n) : Nat}

Dropping n elements leaves length - n of them.

law take_length provedsource · line 312 · raw

@-A:Data -> @+xs:List<&2, A> -> {List.take(&2, A, xs, List.length(&2, A, xs)) == xs : List<&2, A>}

Taking as many elements as the list has gives the list back.

law drop_length provedsource · line 326 · raw

@-A:Data -> @+xs:List<&2, A> -> {List.drop(&2, A, xs, List.length(&2, A, xs)) == [] : List<&2, A>}

Dropping as many elements as the list has gives the empty list.

law take_take provedsource · line 339 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @m:Nat -> {List.take(a, A, List.take(a, A, xs, n), m) == List.take(a, A, xs, Nat.min(n, m)) : List<a, A>}

Taking m from the first n is taking min(n, m).

law drop_drop provedsource · line 360 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-m:Nat -> {List.drop(a, A, List.drop(a, A, xs, n), m) == List.drop(a, A, xs, Nat.add(n, m)) : List<a, A>}

Dropping m after dropping n is dropping n + m.

law reverse_nil provedsource · line 378 · raw

@-a:Quant -> @-A:Kind(a) -> {List.reverse(a, A, []) == [] : List<a, A>}

Reversing the empty list gives the empty list.

law reverse_singleton provedsource · line 387 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> {List.reverse(a, A, [x]) == [x] : List<a, A>}

Reversing a one-element list gives it back.

law length_replicate provedsource · line 397 · raw

@-A:Data -> @n:Nat -> @-x:A -> {List.length(&2, A, List.replicate(A, n, x)) == n : Nat}

Replicating x n times gives a list of length n.

law length_range provedsource · line 420 · raw

@n:Nat -> {List.length(&2, Nat, List.range(n)) == n : Nat}

Range(n) has length n.

law length_zip provedsource · line 430 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {List.length(&1, Pair(A, A), List.zip(a, A, a, A, xs, ys)) == Nat.min(List.length(a, A, xs), List.length(a, A, ys)) : Nat}

Zipping two lists gives the length of the shorter one.

law append_cons provedsource · line 448 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-ys:List<a, A> -> {List.append(a, A, x <> xs, ys) == x <> List.append(a, A, xs, ys) : List<a, A>}

Appending after a cons: (x :: xs) ++ ys = x :: (xs ++ ys).

law length_nil provedsource · line 460 · raw

@-a:Quant -> @-A:Kind(a) -> {List.length(a, A, []) == 0n : Nat}

The empty list has length zero.

law length_cons provedsource · line 469 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {List.length(a, A, x <> xs) == 1n+List.length(a, A, xs) : Nat}

A cons is one longer than its tail.

law concat_append provedsource · line 480 · raw

@-a:Quant -> @-A:Kind(a) -> @xss:List<a, List<a, A>> -> @-yss:List<a, List<a, A>> -> {List.concat(a, A, List.append(a, List<a, A>, xss, yss)) == List.append(a, A, List.concat(a, A, xss), List.concat(a, A, yss)) : List<a, A>}

Concatenating an append concatenates each part: concat (xss ++ yss) = concat xss ++ concat yss.

law foldl_append provedsource · line 496 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:B -> @_:A -> B) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-z:B -> {List.foldl(a, A, B, f, List.append(a, A, xs, ys), z) == List.foldl(a, A, B, f, ys, List.foldl(a, A, B, f, xs, z)) : B}

A left fold over an append folds the second part from the fold of the first.

law map_reverse provedsource · line 521 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.map(A, B, f, List.reverse(&1, A, xs)) == List.reverse(&1, B, List.map(A, B, f, xs)) : List<&1, B>}

Mapping commutes with reversing: map f (reverse xs) = reverse (map f xs).

law all_append provedsource · line 532 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-ys:List<a, A> -> {List.all(a, A, f, List.append(a, A, xs, ys)) == Bool.and(List.all(a, A, f, xs), List.all(a, A, f, ys)) : Bool}

All over an append is all over each part, joined by and.

law any_append provedsource · line 549 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-ys:List<a, A> -> {List.any(a, A, f, List.append(a, A, xs, ys)) == Bool.or(List.any(a, A, f, xs), List.any(a, A, f, ys)) : Bool}

Any over an append is any over each part, joined by or.

law filter_append provedsource · line 573 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> @ys:List<&2, A> -> {List.filter(A, f, List.append(&2, A, xs, ys)) == List.append(&2, A, List.filter(A, f, xs), List.filter(A, f, ys)) : List<&2, A>}

Filtering an append filters each part.

law contains_append provedsource · line 591 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @xs:List<&2, A> -> @-ys:List<&2, A> -> @+x:A -> {List.contains(A, eq, List.append(&2, A, xs, ys), x) == Bool.or(List.contains(A, eq, xs, x), List.contains(A, eq, ys, x)) : Bool}

An append contains x iff either part does.

law length_filter_le provedsource · line 615 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> {Nat.is_le(List.length(&2, A, List.filter(A, f, xs)), List.length(&2, A, xs)) == True{} : Bool}

Filtering never makes a list longer.

law mem_cons_self provedsource · line 680 · raw

@x:Nat -> @-xs:List<&2, Nat> -> mem(Nat, Nat.is_eq, x, x <> xs)

The head of a Nat list is a member of it (membership by Nat.is_eq).

law mem_cons_of_mem provedsource · line 690 · raw

@x:Nat -> @y:Nat -> @-xs:List<&2, Nat> -> @h:mem(Nat, Nat.is_eq, x, xs) -> mem(Nat, Nat.is_eq, x, y <> xs)

A member of a Nat list stays a member when a head is prepended.

law not_mem_nil provedsource · line 702 · raw

@-x:Nat -> @_:mem(Nat, Nat.is_eq, x, []) -> Empty

No Nat is a member of the empty list.

law mem_append_left provedsource · line 710 · raw

@xs:List<&2, Nat> -> @ys:List<&2, Nat> -> @x:Nat -> @h:mem(Nat, Nat.is_eq, x, xs) -> mem(Nat, Nat.is_eq, x, List.append(&2, Nat, xs, ys))

A member of xs is a member of xs ++ ys (Nat lists).

law mem_append_right provedsource · line 721 · raw

@xs:List<&2, Nat> -> @ys:List<&2, Nat> -> @x:Nat -> @h:mem(Nat, Nat.is_eq, x, ys) -> mem(Nat, Nat.is_eq, x, List.append(&2, Nat, xs, ys))

A member of ys is a member of xs ++ ys (Nat lists).

law sorted_nil provedsource · line 732 · raw

sorted_by(Nat, Nat.is_le, [])

The empty Nat list is sorted by Nat.is_le.

law sorted_single provedsource · line 739 · raw

@-x:Nat -> sorted_by(Nat, Nat.is_le, [x])

A one-element Nat list is sorted by Nat.is_le.

law sorted_cons_cons_intro provedsource · line 747 · raw

@-x:Nat -> @-y:Nat -> @-t:List<&2, Nat> -> @hxy:0x449abff091641d732d7b9f0780df40ae/nat.le(x, y) -> @hyt:sorted_by(Nat, Nat.is_le, y <> t) -> sorted_by(Nat, Nat.is_le, x <> y <> t)

A Nat list sorted by Nat.is_le stays sorted under a head that is <= the next element.

law sorted_cons_cons_elim_le provedsource · line 760 · raw

@x:Nat -> @y:Nat -> @-t:List<&2, Nat> -> @h:sorted_by(Nat, Nat.is_le, x <> y <> t) -> 0x449abff091641d732d7b9f0780df40ae/nat.le(x, y)

The first two elements of a Nat list sorted by Nat.is_le are in order.

law sorted_cons_cons_elim_tail provedsource · line 771 · raw

@x:Nat -> @y:Nat -> @-t:List<&2, Nat> -> @h:sorted_by(Nat, Nat.is_le, x <> y <> t) -> sorted_by(Nat, Nat.is_le, y <> t)

The tail of a Nat list of two or more elements sorted by Nat.is_le is sorted.

law sorted_tail provedsource · line 782 · raw

@x:Nat -> @xs:List<&2, Nat> -> @h:sorted_by(Nat, Nat.is_le, x <> xs) -> sorted_by(Nat, Nat.is_le, xs)

The tail of a nonempty Nat list sorted by Nat.is_le is sorted.

law take_left provedsource · line 796 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {List.take(a, A, List.append(a, A, xs, ys), List.length(a, A, xs)) == xs : List<a, A>}

Taking the length of the first part of an append gives the first part back.

law drop_left provedsource · line 812 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {List.drop(a, A, List.append(a, A, xs, ys), List.length(a, A, xs)) == ys : List<a, A>}

Dropping the length of the first part of an append gives the second part.

law take_append provedsource · line 827 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-n:Nat -> {List.take(a, A, List.append(a, A, xs, ys), Nat.add(List.length(a, A, xs), n)) == List.append(a, A, xs, List.take(a, A, ys, n)) : List<a, A>}

Taking past the first part of an append keeps it and takes the rest from the second part.

law drop_append provedsource · line 844 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-n:Nat -> {List.drop(a, A, List.append(a, A, xs, ys), Nat.add(List.length(a, A, xs), n)) == List.drop(a, A, ys, n) : List<a, A>}

Dropping past the first part of an append drops the rest from the second part.

law take_append_of_le_length provedsource · line 860 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x449abff091641d732d7b9f0780df40ae/nat.le(n, List.length(a, A, xs)) -> {List.take(a, A, List.append(a, A, xs, ys), n) == List.take(a, A, xs, n) : List<a, A>}

Taking at most the length of the first part of an append only sees the first part.

law drop_append_of_le_length provedsource · line 882 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x449abff091641d732d7b9f0780df40ae/nat.le(n, List.length(a, A, xs)) -> {List.drop(a, A, List.append(a, A, xs, ys), n) == List.append(a, A, List.drop(a, A, xs, n), ys) : List<a, A>}

Dropping at most the length of the first part of an append drops only from the first part.

law map_take provedsource · line 903 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {List.map(A, B, f, List.take(&1, A, xs, n)) == List.take(&1, B, List.map(A, B, f, xs), n) : List<&1, B>}

Mapping commutes with taking: map f (take n xs) = take n (map f xs).

law map_drop provedsource · line 922 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {List.map(A, B, f, List.drop(&1, A, xs, n)) == List.drop(&1, B, List.map(A, B, f, xs), n) : List<&1, B>}

Mapping commutes with dropping: map f (drop n xs) = drop n (map f xs).

law take_replicate provedsource · line 940 · raw

@-A:Data -> @n:Nat -> @m:Nat -> @-x:A -> {List.take(&2, A, List.replicate(A, n, x), m) == List.replicate(A, Nat.min(m, n), x) : List<&2, A>}

Taking m from n copies of x gives min(m, n) copies of x.

law drop_replicate provedsource · line 959 · raw

@-A:Data -> @n:Nat -> @m:Nat -> @-x:A -> {List.drop(&2, A, List.replicate(A, n, x), m) == List.replicate(A, Nat.sub(n, m), x) : List<&2, A>}

Dropping m from n copies of x gives n - m copies of x.

law length_take_le provedsource · line 976 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> 0x449abff091641d732d7b9f0780df40ae/nat.le(List.length(a, A, List.take(a, A, xs, n)), n)

Taking n elements gives at most n of them.

law length_tail provedsource · line 993 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.length(a, A, List.tail(a, A, xs)) == Nat.sub(List.length(a, A, xs), 1n) : Nat}

The tail is one shorter than the list, or empty: length (tail xs) = length xs - 1.

law map_id provedsource · line 1007 · raw

@-A:Type -> @xs:List<&1, A> -> {List.map(A, A, x => x, xs) == xs : List<&1, A>}

Mapping the identity gives the list back.

law foldr_map provedsource · line 1021 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:B -> @_:C -> C) -> @xs:List<&1, A> -> @-z:C -> {List.foldr(&1, B, C, g, List.map(A, B, f, xs), z) == List.foldr(&1, A, C, x => y => g(f(x), y), xs, z) : C}

A right fold over a map folds with the mapped function: foldr g z (map f xs) = foldr (g . f) z xs.

law foldl_map provedsource · line 1040 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:C -> @_:B -> C) -> @xs:List<&1, A> -> @-z:C -> {List.foldl(&1, B, C, g, List.map(A, B, f, xs), z) == List.foldl(&1, A, C, x => y => g(x, f(y)), xs, z) : C}

A left fold over a map folds with the mapped function: foldl g z (map f xs) = foldl (fun acc x => g acc (f x)) z xs.

law replicate_add provedsource · line 1058 · raw

@-A:Data -> @m:Nat -> @-n:Nat -> @-x:A -> {List.replicate(A, Nat.add(m, n), x) == List.append(&2, A, List.replicate(A, m, x), List.replicate(A, n, x)) : List<&2, A>}

Replicating m + n times appends m copies to n copies.

law reverse_replicate provedsource · line 1098 · raw

@-A:Data -> @n:Nat -> @-x:A -> {List.reverse(&2, A, List.replicate(A, n, x)) == List.replicate(A, n, x) : List<&2, A>}

Reversing n copies of x gives them back.

law filter_true provedsource · line 1109 · raw

@-A:Data -> @xs:List<&2, A> -> {List.filter(A, x => True{}, xs) == xs : List<&2, A>}

Filtering with an always-true predicate gives the list back.

law filter_false provedsource · line 1123 · raw

@-A:Data -> @xs:List<&2, A> -> {List.filter(A, x => False{}, xs) == [] : List<&2, A>}

Filtering with an always-false predicate gives the empty list.

law filter_filter provedsource · line 1145 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.filter(A, p, List.filter(A, q, xs)) == List.filter(A, +x => Bool.and(p(x), q(x)), xs) : List<&2, A>}

Filtering twice is filtering by both predicates: filter p (filter q xs) = filter (p and q) xs.

law all_filter provedsource · line 1169 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.all(&2, A, q, List.filter(A, p, xs)) == List.all(&2, A, +x => Bool.or(Bool.not(p(x)), q(x)), xs) : Bool}

All over a filter checks q only where p holds: all q (filter p xs) = all (not p or q) xs.

law any_filter provedsource · line 1193 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.any(&2, A, q, List.filter(A, p, xs)) == List.any(&2, A, +x => Bool.and(p(x), q(x)), xs) : Bool}

Any over a filter looks for q only where p holds: any q (filter p xs) = any (p and q) xs.

law all_map provedsource · line 1210 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @-p:(@_:B -> Bool) -> @xs:List<&1, A> -> {List.all(&1, B, p, List.map(A, B, f, xs)) == List.all(&1, A, x => p(f(x)), xs) : Bool}

All over a map checks the composed predicate: all p (map f xs) = all (p . f) xs.

law any_map provedsource · line 1227 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @-p:(@_:B -> Bool) -> @xs:List<&1, A> -> {List.any(&1, B, p, List.map(A, B, f, xs)) == List.any(&1, A, x => p(f(x)), xs) : Bool}

Any over a map checks the composed predicate: any p (map f xs) = any (p . f) xs.

law all_reverse provedsource · line 1256 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.all(a, A, f, List.reverse(a, A, xs)) == List.all(a, A, f, xs) : Bool}

Reversing does not change whether all elements satisfy a predicate.

law any_reverse provedsource · line 1279 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.any(a, A, f, List.reverse(a, A, xs)) == List.any(a, A, f, xs) : Bool}

Reversing does not change whether some element satisfies a predicate.

law contains_reverse provedsource · line 1302 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @xs:List<&2, A> -> @+x:A -> {List.contains(A, eq, List.reverse(&2, A, xs), x) == List.contains(A, eq, xs, x) : Bool}

Reversing does not change whether a list contains x.

law zip_nil_left provedsource · line 1313 · raw

@-a:Quant -> @-A:Kind(a) -> @-b:Quant -> @-B:Kind(b) -> @-ys:List<b, B> -> {List.zip(a, A, b, B, [], ys) == [] : List<&1, Pair(A, B)>}

Zipping the empty list with anything gives the empty list.

law zip_nil_right provedsource · line 1325 · raw

@-a:Quant -> @-A:Kind(a) -> @-b:Quant -> @-B:Kind(b) -> @xs:List<a, A> -> {List.zip(a, A, b, B, xs, []) == [] : List<&1, Pair(A, B)>}

Zipping anything with the empty list gives the empty list.

law head_cons provedsource · line 1341 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {List.head(a, A, x <> xs) == Some{x} : Maybe<a, A>}

The head of a cons is its first element.

law head_append provedsource · line 1352 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {List.head(a, A, List.append(a, A, xs, ys)) == Maybe.or(a, A, List.head(a, A, xs), List.head(a, A, ys)) : Maybe<a, A>}

The head of an append is the head of the first part, or else of the second.

law head_map provedsource · line 1367 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.head(&1, B, List.map(A, B, f, xs)) == Maybe.map(&1, A, B, f, List.head(&1, A, xs)) : Maybe<&1, B>}

The head of a map is the mapped head.

law tail_map provedsource · line 1382 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.tail(&1, B, List.map(A, B, f, xs)) == List.map(A, B, f, List.tail(&1, A, xs)) : List<&1, B>}

The tail of a map is the map of the tail.

law get_cons_zero provedsource · line 1397 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {List.get(a, A, x <> xs, 0n) == Some{x} : Maybe<a, A>}

The element at index zero of a cons is its head.

law get_cons_succ provedsource · line 1408 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {List.get(a, A, x <> xs, 1n+n) == List.get(a, A, xs, n) : Maybe<a, A>}

The element at index n + 1 of a cons is the element at index n of its tail.

law get_map provedsource · line 1420 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {List.get(&1, B, List.map(A, B, f, xs), n) == Maybe.map(&1, A, B, f, List.get(&1, A, xs, n)) : Maybe<&1, B>}

Indexing a map is mapping the indexed element.

law length_set provedsource · line 1438 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-x:A -> {List.length(a, A, List.set(a, A, xs, n, x)) == List.length(a, A, xs) : Nat}

Setting an element does not change the length.

law get_set_self provedsource · line 1457 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-x:A -> {List.get(a, A, List.set(a, A, xs, n, x), n) == Maybe.map(a, A, A, y => x, List.get(a, A, xs, n)) : Maybe<a, A>}

Reading the index just set gives the new value wherever the index is in range.

law last_append_singleton provedsource · line 1482 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-x:A -> {List.last(a, A, List.append(a, A, xs, [x])) == Some{x} : Maybe<a, A>}

The last element of xs ++ [x] is x.

law head_reverse provedsource · line 1505 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.head(a, A, List.reverse(a, A, xs)) == List.last(a, A, xs) : Maybe<a, A>}

The head of the reverse is the last element.

law last_reverse provedsource · line 1526 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.last(a, A, List.reverse(a, A, xs)) == List.head(a, A, xs) : Maybe<a, A>}

The last element of the reverse is the head.

law is_empty_iff_length_eq_zero provedsource · line 1540 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.is_empty(a, A, xs) == Nat.is_eq(List.length(a, A, xs), 0n) : Bool}

A list is empty exactly when its length is zero.

law is_empty_append provedsource · line 1554 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {List.is_empty(a, A, List.append(a, A, xs, ys)) == Bool.and(List.is_empty(a, A, xs), List.is_empty(a, A, ys)) : Bool}

An append is empty exactly when both parts are.

law is_empty_reverse provedsource · line 1576 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.is_empty(a, A, List.reverse(a, A, xs)) == List.is_empty(a, A, xs) : Bool}

The reverse is empty exactly when the list is.

law is_empty_map provedsource · line 1590 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.is_empty(&1, B, List.map(A, B, f, xs)) == List.is_empty(&1, A, xs) : Bool}

A map is empty exactly when the list is.

law filter_reverse provedsource · line 1612 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.filter(A, f, List.reverse(&2, A, xs)) == List.reverse(&2, A, List.filter(A, f, xs)) : List<&2, A>}

Filtering commutes with reversing: filter p (reverse xs) = reverse (filter p xs).

law foldr_cons_nil provedsource · line 1630 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.foldr(a, A, List<a, A>, x => acc => x <> acc, xs, []) == xs : List<a, A>}

Folding cons from the right, starting from the empty list, rebuilds the list.

law foldl_reverse provedsource · line 1652 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:B -> @_:A -> B) -> @xs:List<a, A> -> @-z:B -> {List.foldl(a, A, B, f, List.reverse(a, A, xs), z) == List.foldr(a, A, B, x => y => f(y, x), xs, z) : B}

A left fold over the reverse is a right fold with the arguments flipped.

law foldr_reverse provedsource · line 1672 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:A -> @_:B -> B) -> @xs:List<a, A> -> @-z:B -> {List.foldr(a, A, B, f, List.reverse(a, A, xs), z) == List.foldl(a, A, B, x => y => f(y, x), xs, z) : B}

A right fold over the reverse is a left fold with the arguments flipped.

law range_succ provedsource · line 1692 · raw

@n:Nat -> {List.range(1n+n) == List.append(&2, Nat, List.range(n), [n]) : List<&2, Nat>}

Range(n + 1) is range(n) followed by n.

law find_append provedsource · line 1708 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> @ys:List<&2, A> -> {List.find(A, f, List.append(&2, A, xs, ys)) == Maybe.or(&2, A, List.find(A, f, xs), List.find(A, f, ys)) : Maybe<&2, A>}

Finding in an append finds in the first part, or else in the second.

law all_eq_not_any_not provedsource · line 1733 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.all(a, A, f, xs) == Bool.not(List.any(a, A, x => Bool.not(f(x)), xs)) : Bool}

All elements satisfy f exactly when no element fails it.

law any_eq_not_all_not provedsource · line 1756 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.any(a, A, f, xs) == Bool.not(List.all(a, A, x => Bool.not(f(x)), xs)) : Bool}

Some element satisfies f exactly when not all elements fail it.

law length_singleton provedsource · line 1772 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> {List.length(a, A, [x]) == 1n : Nat}

A one-element list has length one.

law reverse_cons provedsource · line 1782 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @xs:List<a, A> -> {List.reverse(a, A, x <> xs) == List.append(a, A, List.reverse(a, A, xs), [x]) : List<a, A>}

Reversing a cons puts its head last: reverse (x :: xs) = reverse xs ++ [x].

law take_succ provedsource · line 1793 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {List.take(a, A, x <> xs, 1n+n) == x <> List.take(a, A, xs, n) : List<a, A>}

Taking n + 1 elements of a cons keeps its head and takes n from its tail.

law drop_succ provedsource · line 1805 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {List.drop(a, A, x <> xs, 1n+n) == List.drop(a, A, xs, n) : List<a, A>}

Dropping n + 1 elements of a cons drops its head and n from its tail.

law append_nil_sym provedsource · line 1819 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {xs == List.append(a, A, xs, []) : List<a, A>}

The empty list is a right identity for append: xs ++ [] = xs, reversed to rewrite toward the simple side.

law nil_append_sym provedsource · line 1829 · raw

@-a:Quant -> @-A:Kind(a) -> @-xs:List<a, A> -> {xs == List.append(a, A, [], xs) : List<a, A>}

The empty list is a left identity for append: [] ++ xs = xs, reversed to rewrite toward the simple side.

law append_assoc_sym provedsource · line 1839 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-zs:List<a, A> -> {List.append(a, A, xs, List.append(a, A, ys, zs)) == List.append(a, A, List.append(a, A, xs, ys), zs) : List<a, A>}

Append is associative: (xs ++ ys) ++ zs = xs ++ (ys ++ zs), reversed to rewrite toward the simple side.

law length_append_sym provedsource · line 1851 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {Nat.add(List.length(a, A, xs), List.length(a, A, ys)) == List.length(a, A, List.append(a, A, xs, ys)) : Nat}

The length of an append is the sum of the lengths, reversed to rewrite toward the simple side.

law reverse_go_spec_sym provedsource · line 1862 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-acc:List<a, A> -> {List.append(a, A, List.reverse(a, A, xs), acc) == List.reverse.go(a, A, xs, acc) : List<a, A>}

The reverse accumulator loop appends the reversed list to the accumulator, reversed to rewrite toward the simple side.

law reverse_append_sym provedsource · line 1873 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {List.append(a, A, List.reverse(a, A, ys), List.reverse(a, A, xs)) == List.reverse(a, A, List.append(a, A, xs, ys)) : List<a, A>}

Reversing an append reverses and swaps the parts: reverse (xs ++ ys) = reverse ys ++ reverse xs, reversed to rewrite toward the simple side.

law reverse_reverse_sym provedsource · line 1884 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {xs == List.reverse(a, A, List.reverse(a, A, xs)) : List<a, A>}

Reversing twice gives the list back, reversed to rewrite toward the simple side.

law length_reverse_sym provedsource · line 1894 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.length(a, A, xs) == List.length(a, A, List.reverse(a, A, xs)) : Nat}

Reversing preserves the length, reversed to rewrite toward the simple side.

law foldr_append_sym provedsource · line 1904 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:A -> @_:B -> B) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-z:B -> {List.foldr(a, A, B, f, xs, List.foldr(a, A, B, f, ys, z)) == List.foldr(a, A, B, f, List.append(a, A, xs, ys), z) : B}

A right fold over an append folds the first part onto the fold of the second, reversed to rewrite toward the simple side.

law take_append_drop_sym provedsource · line 1918 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {xs == List.append(a, A, List.take(a, A, xs, n), List.drop(a, A, xs, n)) : List<a, A>}

Taking n elements and appending the rest after dropping n gives the list back, reversed to rewrite toward the simple side.

law length_map_sym provedsource · line 1929 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.length(&1, A, xs) == List.length(&1, B, List.map(A, B, f, xs)) : Nat}

Mapping preserves the length, reversed to rewrite toward the simple side.

law map_append_sym provedsource · line 1940 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @-ys:List<&1, A> -> {List.append(&1, B, List.map(A, B, f, xs), List.map(A, B, f, ys)) == List.map(A, B, f, List.append(&1, A, xs, ys)) : List<&1, B>}

Mapping over an append maps each part: map f (xs ++ ys) = map f xs ++ map f ys, reversed to rewrite toward the simple side.

law map_map_sym provedsource · line 1952 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:B -> C) -> @xs:List<&1, A> -> {List.map(A, C, x => g(f(x)), xs) == List.map(B, C, g, List.map(A, B, f, xs)) : List<&1, C>}

Mapping twice is mapping the composition: map g (map f xs) = map (g . f) xs, reversed to rewrite toward the simple side.

law take_zero_sym provedsource · line 1965 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {[] == List.take(a, A, xs, 0n) : List<a, A>}

Taking zero elements gives the empty list, reversed to rewrite toward the simple side.

law drop_zero_sym provedsource · line 1975 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {xs == List.drop(a, A, xs, 0n) : List<a, A>}

Dropping zero elements gives the list back, reversed to rewrite toward the simple side.

law take_nil_sym provedsource · line 1985 · raw

@-a:Quant -> @-A:Kind(a) -> @-n:Nat -> {[] == List.take(a, A, [], n) : List<a, A>}

Taking from the empty list gives the empty list, reversed to rewrite toward the simple side.

law drop_nil_sym provedsource · line 1995 · raw

@-a:Quant -> @-A:Kind(a) -> @-n:Nat -> {[] == List.drop(a, A, [], n) : List<a, A>}

Dropping from the empty list gives the empty list, reversed to rewrite toward the simple side.

law length_take_sym provedsource · line 2005 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {Nat.min(n, List.length(a, A, xs)) == List.length(a, A, List.take(a, A, xs, n)) : Nat}

Taking n elements leaves min(n, length) of them, reversed to rewrite toward the simple side.

law length_drop_sym provedsource · line 2016 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> {Nat.sub(List.length(a, A, xs), n) == List.length(a, A, List.drop(a, A, xs, n)) : Nat}

Dropping n elements leaves length - n of them, reversed to rewrite toward the simple side.

law take_length_sym provedsource · line 2027 · raw

@-A:Data -> @+xs:List<&2, A> -> {xs == List.take(&2, A, xs, List.length(&2, A, xs)) : List<&2, A>}

Taking as many elements as the list has gives the list back, reversed to rewrite toward the simple side.

law drop_length_sym provedsource · line 2036 · raw

@-A:Data -> @+xs:List<&2, A> -> {[] == List.drop(&2, A, xs, List.length(&2, A, xs)) : List<&2, A>}

Dropping as many elements as the list has gives the empty list, reversed to rewrite toward the simple side.

law take_take_sym provedsource · line 2045 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @m:Nat -> {List.take(a, A, xs, Nat.min(n, m)) == List.take(a, A, List.take(a, A, xs, n), m) : List<a, A>}

Taking m from the first n is taking min(n, m), reversed to rewrite toward the simple side.

law drop_drop_sym provedsource · line 2057 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-m:Nat -> {List.drop(a, A, xs, Nat.add(n, m)) == List.drop(a, A, List.drop(a, A, xs, n), m) : List<a, A>}

Dropping m after dropping n is dropping n + m, reversed to rewrite toward the simple side.

law reverse_nil_sym provedsource · line 2069 · raw

@-a:Quant -> @-A:Kind(a) -> {[] == List.reverse(a, A, []) : List<a, A>}

Reversing the empty list gives the empty list, reversed to rewrite toward the simple side.

law reverse_singleton_sym provedsource · line 2078 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> {[x] == List.reverse(a, A, [x]) : List<a, A>}

Reversing a one-element list gives it back, reversed to rewrite toward the simple side.

law length_replicate_sym provedsource · line 2088 · raw

@-A:Data -> @n:Nat -> @-x:A -> {n == List.length(&2, A, List.replicate(A, n, x)) : Nat}

Replicating x n times gives a list of length n, reversed to rewrite toward the simple side.

law length_range_sym provedsource · line 2098 · raw

@n:Nat -> {n == List.length(&2, Nat, List.range(n)) : Nat}

Range(n) has length n, reversed to rewrite toward the simple side.

law length_zip_sym provedsource · line 2106 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {Nat.min(List.length(a, A, xs), List.length(a, A, ys)) == List.length(&1, Pair(A, A), List.zip(a, A, a, A, xs, ys)) : Nat}

Zipping two lists gives the length of the shorter one, reversed to rewrite toward the simple side.

law append_cons_sym provedsource · line 2117 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-ys:List<a, A> -> {x <> List.append(a, A, xs, ys) == List.append(a, A, x <> xs, ys) : List<a, A>}

Appending after a cons: (x :: xs) ++ ys = x :: (xs ++ ys), reversed to rewrite toward the simple side.

law length_nil_sym provedsource · line 2129 · raw

@-a:Quant -> @-A:Kind(a) -> {0n == List.length(a, A, []) : Nat}

The empty list has length zero, reversed to rewrite toward the simple side.

law length_cons_sym provedsource · line 2138 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {1n+List.length(a, A, xs) == List.length(a, A, x <> xs) : Nat}

A cons is one longer than its tail, reversed to rewrite toward the simple side.

law concat_append_sym provedsource · line 2149 · raw

@-a:Quant -> @-A:Kind(a) -> @xss:List<a, List<a, A>> -> @-yss:List<a, List<a, A>> -> {List.append(a, A, List.concat(a, A, xss), List.concat(a, A, yss)) == List.concat(a, A, List.append(a, List<a, A>, xss, yss)) : List<a, A>}

Concatenating an append concatenates each part: concat (xss ++ yss) = concat xss ++ concat yss, reversed to rewrite toward the simple side.

law foldl_append_sym provedsource · line 2160 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:B -> @_:A -> B) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-z:B -> {List.foldl(a, A, B, f, ys, List.foldl(a, A, B, f, xs, z)) == List.foldl(a, A, B, f, List.append(a, A, xs, ys), z) : B}

A left fold over an append folds the second part from the fold of the first, reversed to rewrite toward the simple side.

law map_reverse_sym provedsource · line 2174 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.reverse(&1, B, List.map(A, B, f, xs)) == List.map(A, B, f, List.reverse(&1, A, xs)) : List<&1, B>}

Mapping commutes with reversing: map f (reverse xs) = reverse (map f xs), reversed to rewrite toward the simple side.

law all_append_sym provedsource · line 2185 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-ys:List<a, A> -> {Bool.and(List.all(a, A, f, xs), List.all(a, A, f, ys)) == List.all(a, A, f, List.append(a, A, xs, ys)) : Bool}

All over an append is all over each part, joined by and, reversed to rewrite toward the simple side.

law any_append_sym provedsource · line 2197 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-ys:List<a, A> -> {Bool.or(List.any(a, A, f, xs), List.any(a, A, f, ys)) == List.any(a, A, f, List.append(a, A, xs, ys)) : Bool}

Any over an append is any over each part, joined by or, reversed to rewrite toward the simple side.

law filter_append_sym provedsource · line 2209 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> @ys:List<&2, A> -> {List.append(&2, A, List.filter(A, f, xs), List.filter(A, f, ys)) == List.filter(A, f, List.append(&2, A, xs, ys)) : List<&2, A>}

Filtering an append filters each part, reversed to rewrite toward the simple side.

law contains_append_sym provedsource · line 2220 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @xs:List<&2, A> -> @-ys:List<&2, A> -> @+x:A -> {Bool.or(List.contains(A, eq, xs, x), List.contains(A, eq, ys, x)) == List.contains(A, eq, List.append(&2, A, xs, ys), x) : Bool}

An append contains x iff either part does, reversed to rewrite toward the simple side.

law length_filter_le_sym provedsource · line 2232 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> {True{} == Nat.is_le(List.length(&2, A, List.filter(A, f, xs)), List.length(&2, A, xs)) : Bool}

Filtering never makes a list longer, reversed to rewrite toward the simple side.

law take_left_sym provedsource · line 2242 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {xs == List.take(a, A, List.append(a, A, xs, ys), List.length(a, A, xs)) : List<a, A>}

Taking the length of the first part of an append gives the first part back, reversed to rewrite toward the simple side.

law drop_left_sym provedsource · line 2253 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> {ys == List.drop(a, A, List.append(a, A, xs, ys), List.length(a, A, xs)) : List<a, A>}

Dropping the length of the first part of an append gives the second part, reversed to rewrite toward the simple side.

law take_append_sym provedsource · line 2264 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-n:Nat -> {List.append(a, A, xs, List.take(a, A, ys, n)) == List.take(a, A, List.append(a, A, xs, ys), Nat.add(List.length(a, A, xs), n)) : List<a, A>}

Taking past the first part of an append keeps it and takes the rest from the second part, reversed to rewrite toward the simple side.

law drop_append_sym provedsource · line 2276 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-n:Nat -> {List.drop(a, A, ys, n) == List.drop(a, A, List.append(a, A, xs, ys), Nat.add(List.length(a, A, xs), n)) : List<a, A>}

Dropping past the first part of an append drops the rest from the second part, reversed to rewrite toward the simple side.

law take_append_of_le_length_sym provedsource · line 2288 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x449abff091641d732d7b9f0780df40ae/nat.le(n, List.length(a, A, xs)) -> {List.take(a, A, xs, n) == List.take(a, A, List.append(a, A, xs, ys), n) : List<a, A>}

Taking at most the length of the first part of an append only sees the first part, reversed to rewrite toward the simple side.

law drop_append_of_le_length_sym provedsource · line 2301 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x449abff091641d732d7b9f0780df40ae/nat.le(n, List.length(a, A, xs)) -> {List.append(a, A, List.drop(a, A, xs, n), ys) == List.drop(a, A, List.append(a, A, xs, ys), n) : List<a, A>}

Dropping at most the length of the first part of an append drops only from the first part, reversed to rewrite toward the simple side.

law map_take_sym provedsource · line 2314 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {List.take(&1, B, List.map(A, B, f, xs), n) == List.map(A, B, f, List.take(&1, A, xs, n)) : List<&1, B>}

Mapping commutes with taking: map f (take n xs) = take n (map f xs), reversed to rewrite toward the simple side.

law map_drop_sym provedsource · line 2326 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {List.drop(&1, B, List.map(A, B, f, xs), n) == List.map(A, B, f, List.drop(&1, A, xs, n)) : List<&1, B>}

Mapping commutes with dropping: map f (drop n xs) = drop n (map f xs), reversed to rewrite toward the simple side.

law take_replicate_sym provedsource · line 2338 · raw

@-A:Data -> @n:Nat -> @m:Nat -> @-x:A -> {List.replicate(A, Nat.min(m, n), x) == List.take(&2, A, List.replicate(A, n, x), m) : List<&2, A>}

Taking m from n copies of x gives min(m, n) copies of x, reversed to rewrite toward the simple side.

law drop_replicate_sym provedsource · line 2349 · raw

@-A:Data -> @n:Nat -> @m:Nat -> @-x:A -> {List.replicate(A, Nat.sub(n, m), x) == List.drop(&2, A, List.replicate(A, n, x), m) : List<&2, A>}

Dropping m from n copies of x gives n - m copies of x, reversed to rewrite toward the simple side.

law length_tail_sym provedsource · line 2360 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {Nat.sub(List.length(a, A, xs), 1n) == List.length(a, A, List.tail(a, A, xs)) : Nat}

The tail is one shorter than the list, or empty: length (tail xs) = length xs - 1, reversed to rewrite toward the simple side.

law map_id_sym provedsource · line 2370 · raw

@-A:Type -> @xs:List<&1, A> -> {xs == List.map(A, A, x => x, xs) : List<&1, A>}

Mapping the identity gives the list back, reversed to rewrite toward the simple side.

law foldr_map_sym provedsource · line 2379 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:B -> @_:C -> C) -> @xs:List<&1, A> -> @-z:C -> {List.foldr(&1, A, C, x => y => g(f(x), y), xs, z) == List.foldr(&1, B, C, g, List.map(A, B, f, xs), z) : C}

A right fold over a map folds with the mapped function: foldr g z (map f xs) = foldr (g . f) z xs, reversed to rewrite toward the simple side.

law foldl_map_sym provedsource · line 2393 · raw

@-A:Type -> @-B:Type -> @-C:Type -> @-f:(@_:A -> B) -> @-g:(@_:C -> @_:B -> C) -> @xs:List<&1, A> -> @-z:C -> {List.foldl(&1, A, C, x => y => g(x, f(y)), xs, z) == List.foldl(&1, B, C, g, List.map(A, B, f, xs), z) : C}

A left fold over a map folds with the mapped function: foldl g z (map f xs) = foldl (fun acc x => g acc (f x)) z xs, reversed to rewrite toward the simple side.

law replicate_add_sym provedsource · line 2407 · raw

@-A:Data -> @m:Nat -> @-n:Nat -> @-x:A -> {List.append(&2, A, List.replicate(A, m, x), List.replicate(A, n, x)) == List.replicate(A, Nat.add(m, n), x) : List<&2, A>}

Replicating m + n times appends m copies to n copies, reversed to rewrite toward the simple side.

law reverse_replicate_sym provedsource · line 2418 · raw

@-A:Data -> @n:Nat -> @-x:A -> {List.replicate(A, n, x) == List.reverse(&2, A, List.replicate(A, n, x)) : List<&2, A>}

Reversing n copies of x gives them back, reversed to rewrite toward the simple side.

law filter_true_sym provedsource · line 2428 · raw

@-A:Data -> @xs:List<&2, A> -> {xs == List.filter(A, x => True{}, xs) : List<&2, A>}

Filtering with an always-true predicate gives the list back, reversed to rewrite toward the simple side.

law filter_false_sym provedsource · line 2437 · raw

@-A:Data -> @xs:List<&2, A> -> {[] == List.filter(A, x => False{}, xs) : List<&2, A>}

Filtering with an always-false predicate gives the empty list, reversed to rewrite toward the simple side.

law filter_filter_sym provedsource · line 2446 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.filter(A, +x => Bool.and(p(x), q(x)), xs) == List.filter(A, p, List.filter(A, q, xs)) : List<&2, A>}

Filtering twice is filtering by both predicates: filter p (filter q xs) = filter (p and q) xs, reversed to rewrite toward the simple side.

law all_filter_sym provedsource · line 2457 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.all(&2, A, +x => Bool.or(Bool.not(p(x)), q(x)), xs) == List.all(&2, A, q, List.filter(A, p, xs)) : Bool}

All over a filter checks q only where p holds: all q (filter p xs) = all (not p or q) xs, reversed to rewrite toward the simple side.

law any_filter_sym provedsource · line 2468 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @-q:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.any(&2, A, +x => Bool.and(p(x), q(x)), xs) == List.any(&2, A, q, List.filter(A, p, xs)) : Bool}

Any over a filter looks for q only where p holds: any q (filter p xs) = any (p and q) xs, reversed to rewrite toward the simple side.

law all_map_sym provedsource · line 2479 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @-p:(@_:B -> Bool) -> @xs:List<&1, A> -> {List.all(&1, A, x => p(f(x)), xs) == List.all(&1, B, p, List.map(A, B, f, xs)) : Bool}

All over a map checks the composed predicate: all p (map f xs) = all (p . f) xs, reversed to rewrite toward the simple side.

law any_map_sym provedsource · line 2491 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @-p:(@_:B -> Bool) -> @xs:List<&1, A> -> {List.any(&1, A, x => p(f(x)), xs) == List.any(&1, B, p, List.map(A, B, f, xs)) : Bool}

Any over a map checks the composed predicate: any p (map f xs) = any (p . f) xs, reversed to rewrite toward the simple side.

law all_reverse_sym provedsource · line 2503 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.all(a, A, f, xs) == List.all(a, A, f, List.reverse(a, A, xs)) : Bool}

Reversing does not change whether all elements satisfy a predicate, reversed to rewrite toward the simple side.

law any_reverse_sym provedsource · line 2514 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {List.any(a, A, f, xs) == List.any(a, A, f, List.reverse(a, A, xs)) : Bool}

Reversing does not change whether some element satisfies a predicate, reversed to rewrite toward the simple side.

law contains_reverse_sym provedsource · line 2525 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @xs:List<&2, A> -> @+x:A -> {List.contains(A, eq, xs, x) == List.contains(A, eq, List.reverse(&2, A, xs), x) : Bool}

Reversing does not change whether a list contains x, reversed to rewrite toward the simple side.

law zip_nil_left_sym provedsource · line 2536 · raw

@-a:Quant -> @-A:Kind(a) -> @-b:Quant -> @-B:Kind(b) -> @-ys:List<b, B> -> {[] == List.zip(a, A, b, B, [], ys) : List<&1, Pair(A, B)>}

Zipping the empty list with anything gives the empty list, reversed to rewrite toward the simple side.

law zip_nil_right_sym provedsource · line 2548 · raw

@-a:Quant -> @-A:Kind(a) -> @-b:Quant -> @-B:Kind(b) -> @xs:List<a, A> -> {[] == List.zip(a, A, b, B, xs, []) : List<&1, Pair(A, B)>}

Zipping anything with the empty list gives the empty list, reversed to rewrite toward the simple side.

law head_cons_sym provedsource · line 2560 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {Some{x} == List.head(a, A, x <> xs) : Maybe<a, A>}

The head of a cons is its first element, reversed to rewrite toward the simple side.

law head_append_sym provedsource · line 2571 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {Maybe.or(a, A, List.head(a, A, xs), List.head(a, A, ys)) == List.head(a, A, List.append(a, A, xs, ys)) : Maybe<a, A>}

The head of an append is the head of the first part, or else of the second, reversed to rewrite toward the simple side.

law head_map_sym provedsource · line 2582 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {Maybe.map(&1, A, B, f, List.head(&1, A, xs)) == List.head(&1, B, List.map(A, B, f, xs)) : Maybe<&1, B>}

The head of a map is the mapped head, reversed to rewrite toward the simple side.

law tail_map_sym provedsource · line 2593 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.map(A, B, f, List.tail(&1, A, xs)) == List.tail(&1, B, List.map(A, B, f, xs)) : List<&1, B>}

The tail of a map is the map of the tail, reversed to rewrite toward the simple side.

law get_cons_zero_sym provedsource · line 2604 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> {Some{x} == List.get(a, A, x <> xs, 0n) : Maybe<a, A>}

The element at index zero of a cons is its head, reversed to rewrite toward the simple side.

law get_cons_succ_sym provedsource · line 2615 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {List.get(a, A, xs, n) == List.get(a, A, x <> xs, 1n+n) : Maybe<a, A>}

The element at index n + 1 of a cons is the element at index n of its tail, reversed to rewrite toward the simple side.

law get_map_sym provedsource · line 2627 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @n:Nat -> {Maybe.map(&1, A, B, f, List.get(&1, A, xs, n)) == List.get(&1, B, List.map(A, B, f, xs), n) : Maybe<&1, B>}

Indexing a map is mapping the indexed element, reversed to rewrite toward the simple side.

law length_set_sym provedsource · line 2639 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-x:A -> {List.length(a, A, xs) == List.length(a, A, List.set(a, A, xs, n, x)) : Nat}

Setting an element does not change the length, reversed to rewrite toward the simple side.

law get_set_self_sym provedsource · line 2651 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @n:Nat -> @-x:A -> {Maybe.map(a, A, A, y => x, List.get(a, A, xs, n)) == List.get(a, A, List.set(a, A, xs, n, x), n) : Maybe<a, A>}

Reading the index just set gives the new value wherever the index is in range, reversed to rewrite toward the simple side.

law last_append_singleton_sym provedsource · line 2663 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-x:A -> {Some{x} == List.last(a, A, List.append(a, A, xs, [x])) : Maybe<a, A>}

The last element of xs ++ [x] is x, reversed to rewrite toward the simple side.

law head_reverse_sym provedsource · line 2674 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.last(a, A, xs) == List.head(a, A, List.reverse(a, A, xs)) : Maybe<a, A>}

The head of the reverse is the last element, reversed to rewrite toward the simple side.

law last_reverse_sym provedsource · line 2684 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.head(a, A, xs) == List.last(a, A, List.reverse(a, A, xs)) : Maybe<a, A>}

The last element of the reverse is the head, reversed to rewrite toward the simple side.

law is_empty_iff_length_eq_zero_sym provedsource · line 2694 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {Nat.is_eq(List.length(a, A, xs), 0n) == List.is_empty(a, A, xs) : Bool}

A list is empty exactly when its length is zero, reversed to rewrite toward the simple side.

law is_empty_append_sym provedsource · line 2704 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> {Bool.and(List.is_empty(a, A, xs), List.is_empty(a, A, ys)) == List.is_empty(a, A, List.append(a, A, xs, ys)) : Bool}

An append is empty exactly when both parts are, reversed to rewrite toward the simple side.

law is_empty_reverse_sym provedsource · line 2715 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {List.is_empty(a, A, xs) == List.is_empty(a, A, List.reverse(a, A, xs)) : Bool}

The reverse is empty exactly when the list is, reversed to rewrite toward the simple side.

law is_empty_map_sym provedsource · line 2725 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> {List.is_empty(&1, A, xs) == List.is_empty(&1, B, List.map(A, B, f, xs)) : Bool}

A map is empty exactly when the list is, reversed to rewrite toward the simple side.

law filter_reverse_sym provedsource · line 2736 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> {List.reverse(&2, A, List.filter(A, f, xs)) == List.filter(A, f, List.reverse(&2, A, xs)) : List<&2, A>}

Filtering commutes with reversing: filter p (reverse xs) = reverse (filter p xs), reversed to rewrite toward the simple side.

law foldr_cons_nil_sym provedsource · line 2746 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> {xs == List.foldr(a, A, List<a, A>, x => acc => x <> acc, xs, []) : List<a, A>}

Folding cons from the right, starting from the empty list, rebuilds the list, reversed to rewrite toward the simple side.

law foldl_reverse_sym provedsource · line 2756 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:B -> @_:A -> B) -> @xs:List<a, A> -> @-z:B -> {List.foldr(a, A, B, x => y => f(y, x), xs, z) == List.foldl(a, A, B, f, List.reverse(a, A, xs), z) : B}

A left fold over the reverse is a right fold with the arguments flipped, reversed to rewrite toward the simple side.

law foldr_reverse_sym provedsource · line 2769 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:A -> @_:B -> B) -> @xs:List<a, A> -> @-z:B -> {List.foldl(a, A, B, x => y => f(y, x), xs, z) == List.foldr(a, A, B, f, List.reverse(a, A, xs), z) : B}

A right fold over the reverse is a left fold with the arguments flipped, reversed to rewrite toward the simple side.

law range_succ_sym provedsource · line 2782 · raw

@n:Nat -> {List.append(&2, Nat, List.range(n), [n]) == List.range(1n+n) : List<&2, Nat>}

Range(n + 1) is range(n) followed by n, reversed to rewrite toward the simple side.

law find_append_sym provedsource · line 2790 · raw

@-A:Data -> @-f:(@_:A -> Bool) -> @xs:List<&2, A> -> @ys:List<&2, A> -> {Maybe.or(&2, A, List.find(A, f, xs), List.find(A, f, ys)) == List.find(A, f, List.append(&2, A, xs, ys)) : Maybe<&2, A>}

Finding in an append finds in the first part, or else in the second, reversed to rewrite toward the simple side.

law all_eq_not_any_not_sym provedsource · line 2801 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {Bool.not(List.any(a, A, x => Bool.not(f(x)), xs)) == List.all(a, A, f, xs) : Bool}

All elements satisfy f exactly when no element fails it, reversed to rewrite toward the simple side.

law any_eq_not_all_not_sym provedsource · line 2812 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> {Bool.not(List.all(a, A, x => Bool.not(f(x)), xs)) == List.any(a, A, f, xs) : Bool}

Some element satisfies f exactly when not all elements fail it, reversed to rewrite toward the simple side.

law length_singleton_sym provedsource · line 2823 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> {1n == List.length(a, A, [x]) : Nat}

A one-element list has length one, reversed to rewrite toward the simple side.

law reverse_cons_sym provedsource · line 2833 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @xs:List<a, A> -> {List.append(a, A, List.reverse(a, A, xs), [x]) == List.reverse(a, A, x <> xs) : List<a, A>}

Reversing a cons puts its head last: reverse (x :: xs) = reverse xs ++ [x], reversed to rewrite toward the simple side.

law take_succ_sym provedsource · line 2844 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {x <> List.take(a, A, xs, n) == List.take(a, A, x <> xs, 1n+n) : List<a, A>}

Taking n + 1 elements of a cons keeps its head and takes n from its tail, reversed to rewrite toward the simple side.

law drop_succ_sym provedsource · line 2856 · raw

@-a:Quant -> @-A:Kind(a) -> @-x:A -> @-xs:List<a, A> -> @-n:Nat -> {List.drop(a, A, xs, n) == List.drop(a, A, x <> xs, 1n+n) : List<a, A>}

Dropping n + 1 elements of a cons drops its head and n from its tail, reversed to rewrite toward the simple side.

Definitions

def internal_reverse_go_append source · line 64 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-acc:List<a, A> -> {List.reverse.go(a, A, xs, List.append(a, A, ys, acc)) == List.append(a, A, List.reverse.go(a, A, xs, ys), acc) : List<a, A>}

def internal_reverse_append_go source · line 86 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-ys:List<a, A> -> @-acc:List<a, A> -> {List.reverse.go(a, A, List.append(a, A, xs, ys), acc) == List.reverse.go(a, A, ys, List.reverse.go(a, A, xs, acc)) : List<a, A>}

def internal_reverse_go_go source · line 104 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-acc:List<a, A> -> {List.reverse.go(a, A, List.reverse.go(a, A, xs, acc), []) == List.reverse.go(a, A, acc, xs) : List<a, A>}

def internal_length_reverse_go source · line 121 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-acc:List<a, A> -> @+n:Nat -> @e:{List.length(a, A, acc) == n : Nat} -> {List.length(a, A, List.reverse.go(a, A, xs, acc)) == Nat.add(n, List.length(a, A, xs)) : Nat}

def internal_length_range_go source · line 411 · raw

@+n:Nat -> @acc:List<&2, Nat> -> {List.length(&2, Nat, List.range.go(n, acc)) == Nat.add(n, List.length(&2, Nat, acc)) : Nat}

def internal_filter_put_append source · line 565 · raw

@-A:Data -> @h:A -> @r:List<&2, A> -> @s:List<&2, A> -> @b:Bool -> {List.append(&2, A, List.filter.put(A, h, r, b), s) == List.filter.put(A, h, List.append(&2, A, r, s), b) : List<&2, A>}

def internal_length_filter_put_le source · line 607 · raw

@-A:Data -> @h:A -> @r:List<&2, A> -> @b:Bool -> {Nat.is_le(List.length(&2, A, List.filter.put(A, h, r, b)), 1n+List.length(&2, A, r)) == True{} : Bool}

def internal_or_of_right source · line 637 · raw

@a:Bool -> @-b:Bool -> @hb:{b == True{} : Bool} -> {Bool.or(a, b) == True{} : Bool}

def internal_or_of_or source · line 644 · raw

@a:Bool -> @-b:Bool -> @-c:Bool -> @h:{Bool.or(a, b) == True{} : Bool} -> @k:(@_:{b == True{} : Bool} -> {c == True{} : Bool}) -> {Bool.or(a, c) == True{} : Bool}

def internal_and_left source · line 651 · raw

@a:Bool -> @-b:Bool -> @h:{Bool.and(a, b) == True{} : Bool} -> {a == True{} : Bool}

def internal_and_right source · line 658 · raw

@a:Bool -> @-b:Bool -> @h:{Bool.and(a, b) == True{} : Bool} -> {b == True{} : Bool}

def internal_mem_append_left source · line 665 · raw

@+xs:List<&2, Nat> -> @+ys:List<&2, Nat> -> @+x:Nat -> @h:{List.contains(Nat, Nat.is_eq, xs, x) == True{} : Bool} -> {List.contains(Nat, Nat.is_eq, List.append(&2, Nat, xs, ys), x) == True{} : Bool}

def internal_mem_append_right source · line 672 · raw

@+xs:List<&2, Nat> -> @+ys:List<&2, Nat> -> @+x:Nat -> @h:{List.contains(Nat, Nat.is_eq, ys, x) == True{} : Bool} -> {List.contains(Nat, Nat.is_eq, List.append(&2, Nat, xs, ys), x) == True{} : Bool}

def internal_replicate_append_nil source · line 1073 · raw

@-A:Data -> @n:Nat -> @-x:A -> {List.append(&2, A, List.replicate(A, n, x), []) == List.replicate(A, n, x) : List<&2, A>}

def internal_replicate_append_cons source · line 1081 · raw

@-A:Data -> @n:Nat -> @-x:A -> @-acc:List<&2, A> -> {List.append(&2, A, List.replicate(A, n, x), x <> acc) == x <> List.append(&2, A, List.replicate(A, n, x), acc) : List<&2, A>}

def internal_reverse_go_replicate source · line 1089 · raw

@-A:Data -> @n:Nat -> @-x:A -> @-acc:List<&2, A> -> {List.reverse.go(&2, A, List.replicate(A, n, x), acc) == List.append(&2, A, List.replicate(A, n, x), acc) : List<&2, A>}

def internal_last_go_append_singleton source · line 1474 · raw

@-a:Quant -> @-A:Kind(a) -> @ys:List<a, A> -> @-h:A -> @-x:A -> {List.last.go(a, A, List.append(a, A, ys, [x]), h) == x : A}

def internal_head_reverse_go source · line 1497 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-h:A -> @-acc:List<a, A> -> {List.head(a, A, List.reverse.go(a, A, xs, h <> acc)) == Some{List.last.go(a, A, xs, h)} : Maybe<a, A>}

def internal_last_reverse_go source · line 1518 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-h:A -> @-acc:List<a, A> -> {List.last(a, A, List.reverse.go(a, A, xs, h <> acc)) == Some{List.last.go(a, A, acc, h)} : Maybe<a, A>}

def internal_is_empty_reverse_go source · line 1568 · raw

@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @-h:A -> @-acc:List<a, A> -> {List.is_empty(a, A, List.reverse.go(a, A, xs, h <> acc)) == False{} : Bool}

def internal_reverse_filter_put source · line 1604 · raw

@-A:Data -> @-h:A -> @r:List<&2, A> -> @b:Bool -> {List.append(&2, A, List.reverse(&2, A, r), List.filter.put(A, h, [], b)) == List.reverse(&2, A, List.filter.put(A, h, r, b)) : List<&2, A>}

def internal_range_go_append source · line 1684 · raw

@+n:Nat -> @-ys:List<&2, Nat> -> @-acc:List<&2, Nat> -> {List.range.go(n, List.append(&2, Nat, ys, acc)) == List.append(&2, Nat, List.range.go(n, ys), acc) : List<&2, Nat>}

def internal_find_put_or source · line 1700 · raw

@-A:Data -> @h:A -> @r:Maybe<&2, A> -> @-s:Maybe<&2, A> -> @b:Bool -> {Maybe.or(&2, A, List.find.put(A, h, r, b), s) == List.find.put(A, h, Maybe.or(&2, A, r, s), b) : Maybe<&2, A>}

def internal_and_not_eq_not_or_not source · line 1725 · raw

@b:Bool -> @-s:Bool -> {Bool.and(b, Bool.not(s)) == Bool.not(Bool.or(Bool.not(b), s)) : Bool}

def internal_or_not_eq_not_and_not source · line 1748 · raw

@b:Bool -> @-s:Bool -> {Bool.or(b, Bool.not(s)) == Bool.not(Bool.and(Bool.not(b), s)) : Bool}

Templates

template internal_map_reverse_go source · line 513 · raw

@-A:Type -> @-B:Type -> @-f:(@_:A -> B) -> @xs:List<&1, A> -> @acc:List<&1, A> -> {List.map(A, B, f, List.reverse.go(&1, A, xs, acc)) == List.reverse.go(&1, B, List.map(A, B, f, xs), List.map(A, B, f, acc)) : List<&1, B>}

template mem source · line 630 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @+x:A -> @xs:List<&2, A> -> Data

Membership in a list, as a reusable proposition.

template sorted_by source · line 634 · raw

@-A:Data -> @-le:(@_:A -> @_:A -> Bool) -> @+xs:List<&2, A> -> Data

A list is sorted by a comparator when every adjacent pair is in order.

template internal_filter_put_filter source · line 1135 · raw

@-A:Data -> @-p:(@_:A -> Bool) -> @+h:A -> @r:List<&2, A> -> @b:Bool -> {List.filter(A, p, List.filter.put(A, h, r, b)) == List.filter.put(A, h, List.filter(A, p, r), Bool.and(p(h), b)) : List<&2, A>}

template internal_all_filter_put source · line 1161 · raw

@-A:Data -> @-q:(@_:A -> Bool) -> @-h:A -> @r:List<&2, A> -> @b:Bool -> {List.all(&2, A, q, List.filter.put(A, h, r, b)) == Bool.and(Bool.or(Bool.not(b), q(h)), List.all(&2, A, q, r)) : Bool}

template internal_any_filter_put source · line 1185 · raw

@-A:Data -> @-q:(@_:A -> Bool) -> @-h:A -> @r:List<&2, A> -> @b:Bool -> {List.any(&2, A, q, List.filter.put(A, h, r, b)) == Bool.or(Bool.and(b, q(h)), List.any(&2, A, q, r)) : Bool}

template internal_all_reverse_go source · line 1243 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-acc:List<a, A> -> @c:Bool -> @e:{List.all(a, A, f, acc) == c : Bool} -> {List.all(a, A, f, List.reverse.go(a, A, xs, acc)) == Bool.and(c, List.all(a, A, f, xs)) : Bool}

template internal_any_reverse_go source · line 1266 · raw

@-a:Quant -> @-A:Kind(a) -> @-f:(@_:A -> Bool) -> @xs:List<a, A> -> @-acc:List<a, A> -> @c:Bool -> @e:{List.any(a, A, f, acc) == c : Bool} -> {List.any(a, A, f, List.reverse.go(a, A, xs, acc)) == Bool.or(c, List.any(a, A, f, xs)) : Bool}

template internal_contains_reverse_go source · line 1289 · raw

@-A:Data -> @-eq:(@_:A -> @_:A -> Bool) -> @xs:List<&2, A> -> @-acc:List<&2, A> -> @+x:A -> @c:Bool -> @e:{List.contains(A, eq, acc, x) == c : Bool} -> {List.contains(A, eq, List.reverse.go(&2, A, xs, acc), x) == Bool.or(c, List.contains(A, eq, xs, x)) : Bool}

template internal_foldl_reverse_go source · line 1644 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:B -> @_:A -> B) -> @xs:List<a, A> -> @-acc:List<a, A> -> @-z:B -> {List.foldl(a, A, B, f, List.reverse.go(a, A, xs, acc), z) == List.foldl(a, A, B, f, acc, List.foldr(a, A, B, x => y => f(y, x), xs, z)) : B}

template internal_foldr_reverse_go source · line 1664 · raw

@-a:Quant -> @-A:Kind(a) -> @-B:Type -> @-f:(@_:A -> @_:B -> B) -> @xs:List<a, A> -> @-acc:List<a, A> -> @-z:B -> {List.foldr(a, A, B, f, List.reverse.go(a, A, xs, acc), z) == List.foldl(a, A, B, x => y => f(y, x), xs, List.foldr(a, A, B, f, acc, z)) : B}