list.bend checks
raw source on the hub · import bend-mathlib@0.7.1.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:0x3c446c5bcf57d1eef89775ba0b411fc6/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) -> 0x3c446c5bcf57d1eef89775ba0b411fc6/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:0x3c446c5bcf57d1eef89775ba0b411fc6/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:0x3c446c5bcf57d1eef89775ba0b411fc6/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 -> 0x3c446c5bcf57d1eef89775ba0b411fc6/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 append_nil_sym provedsource · line 1774 · 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 1784 · 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 1794 · 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 1806 · 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 1817 · 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 1828 · 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 1839 · 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 1849 · 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 1859 · 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 1873 · 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 1884 · 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 1895 · 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 1907 · 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 1920 · 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 1930 · 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 1940 · 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 1950 · 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 1960 · 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 1971 · 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 1982 · 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 1991 · 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 2000 · 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 2012 · 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 2024 · 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 2033 · 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 2043 · 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 2053 · 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 2061 · 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 2072 · 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 2084 · 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 2093 · 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 2104 · 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 2115 · 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 2129 · 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 2140 · 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 2152 · 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 2164 · 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 2175 · 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 2187 · 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 2197 · 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 2208 · 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 2219 · 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 2231 · 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 2243 · raw
@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x3c446c5bcf57d1eef89775ba0b411fc6/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 2256 · raw
@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x3c446c5bcf57d1eef89775ba0b411fc6/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 2269 · 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 2281 · 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 2293 · 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 2304 · 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 2315 · 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 2325 · 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 2334 · 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 2348 · 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 2362 · 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 2373 · 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 2383 · 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 2392 · 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 2401 · 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 2412 · 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 2423 · 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 2434 · 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 2446 · 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 2458 · 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 2469 · 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 2480 · 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 2491 · 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 2503 · 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 2515 · 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 2526 · 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 2537 · 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 2548 · 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 2559 · 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 2570 · 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 2582 · 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 2594 · 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 2606 · 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 2618 · 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 2629 · 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 2639 · 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 2649 · 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 2659 · 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 2670 · 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 2680 · 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 2691 · 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 2701 · 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 2711 · 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 2724 · 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 2737 · 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 2745 · 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 2756 · 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 2767 · 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.
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}