list.bend checks
raw source on the hub · import bend-mathlib@0.6.0.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 412 · 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 514 · 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 566 · 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 608 · 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 cons is a member of it.
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)
Membership is preserved when a new head is prepended.
law not_mem_nil provedsource · line 702 · raw
@-x:Nat -> @_:mem(Nat, Nat.is_eq, x, []) -> Empty
Nothing 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))
Membership on the left of an append.
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))
Membership on the right of an append.
law sorted_nil provedsource · line 732 · raw
sorted_by(Nat, Nat.is_le, [])
The empty list is sorted by any comparator.
law sorted_single provedsource · line 739 · raw
@-x:Nat -> sorted_by(Nat, Nat.is_le, [x])
A singleton list is sorted by any comparator.
law sorted_cons_cons_intro provedsource · line 747 · raw
@-x:Nat -> @-y:Nat -> @-t:List<&2, Nat> -> @hxy:0x0eaaf505a355d14d67066b86c801e960/nat.le(x, y) -> @hyt:sorted_by(Nat, Nat.is_le, y <> t) -> sorted_by(Nat, Nat.is_le, x <> y <> t)
A sorted tail with an in-order head is sorted.
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) -> 0x0eaaf505a355d14d67066b86c801e960/nat.le(x, y)
The head pair of a sorted cons-cons list is 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 sorted cons-cons list 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)
A sorted list has a sorted tail.
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:0x0eaaf505a355d14d67066b86c801e960/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:0x0eaaf505a355d14d67066b86c801e960/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 -> 0x0eaaf505a355d14d67066b86c801e960/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 append_nil_sym provedsource · line 1315 · 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 1325 · 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 1335 · 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 1347 · 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 1358 · 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 1369 · 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 1380 · 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 1390 · 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 1400 · 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 1414 · 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 1425 · 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 1436 · 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 1448 · 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 1461 · 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 1471 · 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 1481 · 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 1491 · 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 1501 · 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 1512 · 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 1523 · 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 1532 · 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 1541 · 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 1553 · 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 1565 · 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 1574 · 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 1584 · 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 1594 · 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 1602 · 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 1613 · 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 1625 · 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 1634 · 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 1645 · 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 1656 · 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 1670 · 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 1681 · 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 1693 · 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 1705 · 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 1716 · 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 1728 · 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 1738 · 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 1749 · 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 1760 · 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 1772 · 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 1784 · raw
@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x0eaaf505a355d14d67066b86c801e960/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 1797 · raw
@-a:Quant -> @-A:Kind(a) -> @xs:List<a, A> -> @ys:List<a, A> -> @n:Nat -> @h:0x0eaaf505a355d14d67066b86c801e960/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 1810 · 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 1822 · 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 1834 · 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 1845 · 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 1856 · 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 1866 · 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 1875 · 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 1889 · 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 1903 · 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 1914 · 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 1924 · 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 1933 · 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 1942 · 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 1953 · 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 1964 · 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 1975 · 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 1987 · 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 1999 · 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 2010 · 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 2021 · 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.
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 416 · 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 573 · 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 614 · 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>}
Templates
template internal_map_reverse_go source · line 521 · 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}