Infix

Posted on 2017-05-24 by nbloomf
Tags: arithmetic-made-difficult, literate-haskell

This page is part of a series on Arithmetic Made Difficult.

This post is literate Haskell; you can load the source into GHCi and play along.


{-# LANGUAGE NoImplicitPrelude #-}
module Infix
  ( isInfix, _test_isInfix, main_isInfix
  ) where

import Testing
import Booleans
import And
import Or
import NaturalNumbers
import Lists
import HeadAndTail
import BailoutFold
import Snoc
import Reverse
import Cat
import PrefixAndSuffix
import AllAndAny
import TailsAndInits
import Sublist

Today we’ll nail down \(\infix\), a variant on \(\sublist\).

Let \(A\) be a set. Define \(\beta : A \times \lists{A} \times \lists{A} \rightarrow \bool\) by \[\beta(a,x,y) = \prefix(y,\cons(a,x)),\] \(\psi : A \times \lists{A} \times \lists{A} \rightarrow \bool\) by \[\beta(a,x,y) = \btrue,\] and \(\omega : A \times \lists{A} \times \lists{A} \rightarrow \lists{A}\) by \[\omega(a,x,y) = y.\] Then define \(\infix : \lists{A} \times \lists{A} \rightarrow \bool\) by \[\infix(x,y) = \bfoldr(\isnil)(\beta)(\psi)(\omega)(y,x).\]

In Haskell:

(infix is a reserved word in Haskell, so we’ll call this function isInfix.)

Since \(\infix\) is defined in terms of bailout fold, it can be characterized as the unique solution to a system of functional equations.

Let \(A\) be a set. \(\infix\) is the unique map \(f : \lists{A} \times \lists{A} \rightarrow \bool\) satisfying the following equations for all \(b \in A\) and \(x,y \in \lists{A}\). \[\left\{\begin{array}{l} f(x,\nil) = \isnil(x) \\ f(x,\cons(b,y)) = \bif{\prefix(x,\cons(b,y))}{\btrue}{f(x,y)} \end{array}\right.\]

\(\infix\) is an \(\bor\).

Let \(A\) be a set. For all \(x,y \in \lists{A}\), we have \[\infix(x,y) = \bor(\prefix(x,y),\infix(x,\tail(y))).\]

We consider two possibilities for \(y\). If \(y = \nil\), we have \[\begin{eqnarray*} & & \infix(x,\nil) \\ & = & \isnil(x) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-idempotent} = & \bor(\isnil(x),\isnil(x)) \\ & = & \bor(\prefix(x,\nil),\infix(x,\nil)) \\ & \href{/posts/arithmetic-made-difficult/HeadAndTail.html#thm-tail-nil} = & \bor(\prefix(x,\nil),\infix(x,\tail(\nil))) \end{eqnarray*}\] as needed. If \(y = \cons(b,u)\), we have \[\begin{eqnarray*} & & \infix(x,\cons(b,u)) \\ & = & \bif{\prefix(x,\cons(b,u))}{\btrue}{\infix(x,u)} \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-is-if} = & \bor(\prefix(x,\cons(b,u)),\infix(x,u)) \\ & = & \bor(\prefix(x,y),\infix(x,\tail(y))) \end{eqnarray*}\] as needed.

\(\infix\) is reflexive.

Let \(A\) be a set. If \(x \in \lists{A}\), then \(\infix(x,x) = \btrue\).

We consider two cases for \(x\). If \(x = \nil\), we have \[\infix(x,x) = \infix(\nil,\nil) = \btrue\] as claimed. If \(x = \cons(a,u)\), we have \[\begin{eqnarray*} & & \infix(x,x) \\ & = & \infix(x,\cons(a,u)) \\ & = & \bif{\prefix(x,\cons(a,u))}{\btrue}{\infix(x,u)} \\ & = & \bif{\prefix(x,x)}{\btrue}{\infix(x,u)} \\ & = & \btrue \end{eqnarray*}\] as claimed.

\(\infix\) interacts with \(\cat\):

Let \(A\) be a set and \(x,y \in \lists{A}\).

  1. \(\infix(x,\cat(y,x)) = \btrue\).
  2. \(\infix(x,\cat(x,y)) = \btrue\).
  1. We proceed by list induction on \(y\). For the base case, note that \[\begin{eqnarray*} & & \infix(x,\cat(y,x)) \\ & = & \infix(x,\cat(\nil,x)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-nil} = & \infix(x,x) \\ & = & \btrue \end{eqnarray*}\] as needed. For the inductive step, suppose the equality holds for some \(y\) and let \(b \in A\). Now \[\begin{eqnarray*} & & \infix(x,\cat(\cons(b,y),x)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-cons} = & \infix(x,\cons(b,\cat(y,x))) \\ & = & \bor(\prefix(x,\cons(b,\cat(y,x))),\infix(x,\cat(y,x))) \\ & = & \bor(\prefix(x,\cons(b,\cat(y,x))),\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-right} = & \btrue \end{eqnarray*}\] as needed.
  2. We consider two possibilities for \(x\). If \(x = \nil\), we have \[\infix(x,\cat(x,y)) = \infix(\nil,\cat(x,y)) = \btrue\] as claimed. Suppose then that \(x = \cons(a,u)\). Then we have \[\begin{eqnarray*} & & \infix(x,\cat(x,y)) \\ & = & \infix(x,\cat(\cons(a,u),y)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-cons} = & \infix(x,\cons(a,\cat(u,y))) \\ & = & \bor(\prefix(x,\cons(a,\cat(u,y))),\infix(x,\cat(u,y))) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-cons} = & \bor(\prefix(x,\cat(\cons(a,u),y)),\infix(x,\cat(u,y))) \\ & = & \bor(\prefix(x,\cat(x,y)),\infix(x,\cat(u,y))) \\ & \href{/posts/arithmetic-made-difficult/PrefixAndSuffix.html#thm-prefix-cat-self} = & \bor(\btrue,\infix(x,\cat(u,y))) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-left} = & \btrue \end{eqnarray*}\] as needed.

Prefixes and suffixes are also infixes.

Let \(A\) be a set. The following hold for all \(x,y \in \lists{A}\).

  1. If \(\prefix(x,y) = \btrue\), then \(\infix(x,y) = \btrue\).
  2. If \(\suffix(x,y) = \btrue\), then \(\infix(x,y) = \btrue\).
  1. Recall that \(\prefix(x,y) = \btrue\) if and only if \(y = \cat(x,z)\) for some \(z\). Then \[\infix(x,y) = \infix(x,\cat(x,z)) = \btrue\] as claimed.
  2. Recall that \(\suffix(x,y) = \btrue\) if and only if \(y = \cat(z,x)\) for some \(z\). Then \[\infix(x,y) = \infix(x,\cat(z,x)) = \btrue\] as claimed.

\(\infix\) interacts conditionally with \(\cons\).

Let \(A\) be a set with \(a \in A\) and \(x,y \in \lists{A}\). If \(\infix(x,y) = \btrue\), then \(\infix(x,\cons(a,y)) = \btrue\).

Note that \[\begin{eqnarray*} & & \infix(x,\cons(a,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\infix(x,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\btrue) \\ & \href{/posts/arithmetic-made-difficult/Or.html#thm-or-true-right} = & \btrue \end{eqnarray*}\] as claimed.

\(\infix\) interacts conditionally with \(\snoc\).

Let \(A\) be a set with \(a \in A\) and \(x,y \in \lists{A}\). If \(\infix(x,y) = \btrue\), then \(\infix(x,\snoc(a,y)) = \btrue\).

We proceed by list induction on \(y\). For the base case \(y = \nil\), note that we must have \(x = \nil\). Now \[\infix(x,\snoc(a,y)) = \infix(\nil,\snoc(a,y)) = \btrue\] as needed. For the inductive step, suppose the implication holds for some \(y\) and let \(b \in A\). Suppose further that \(\infix(x,\cons(b,y)) = \btrue\). Now \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,\cons(a,y)) \\ & = & \bor(\prefix(x,\cons(b,y)),\infix(x,y)). \end{eqnarray*}\] We have two possibilities. First suppose \(\prefix(x,\cons(b,y)) = \btrue\). Then \(\prefix(x,\snoc(a,\cons(a,y))) = \btrue\), and so \(\infix(x,\snoc(a,\cons(b,y)))\) as needed. Suppose instead that \(\infix(x,y) = \btrue\). By the inductive hypothesis we have \[\infix(x,\snoc(a,y)) = \btrue,\] and by the previous result we have \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,\cons(b,\snoc(a,y))) \\ & \href{/posts/arithmetic-made-difficult/Snoc.html#cor-snoc-cons} = & \infix(x,\snoc(a,\cons(b,y))) \end{eqnarray*}\] as needed.

\(\infix\) is right-compatible with \(\cat\) (from both sides).

Let \(A\) be a set and \(x,y \in \lists{A}\).

  1. If \(\infix(x,y) = \btrue\), then \(\infix(x,\cat(y,z)) = \btrue\).
  2. If \(\infix(x,y) = \btrue\), then \(\infix(x,\cat(z,y)) = \btrue\).
  1. We proceed by list induction on \(z\). For the base case \(z = \nil\), we have \[\infix(x,\cat(y,z)) = \infix(x,\cat(y,\nil)) = \infix(x,y) = \btrue.\] For the inductive step, suppose the implication holds for some \(z\) and let \(a \in A\). Now \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,y) \\ & = & \infix(x,\snoc(a,y)) \\ & = & \infix(x,\cat(\snoc(a,y),z)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-cat-snoc-left} = & \infix(x,\cat(y,\cons(a,z))) \end{eqnarray*}\] as needed.
  2. We proceed by list induction on \(z\). For the base case \(z = \nil\) we have \[\infix(x,\cat(z,y)) = \infix(x,\cat(\nil,y)) = \infix(x,y) = \btrue\] as needed. For the inductive step, suppose the implication holds for some \(z\) and let \(a \in A\). Now \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,y) \\ & = & \infix(x,\cat(z,y)) \\ & = & \infix(x,\cons(a,\cat(z,y))) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-cons} = & \infix(x,\cat(\cons(a,z),y)) \end{eqnarray*}\] as needed.

\(\infix\) perfectly detects two-sided \(\cat\)-factorizations.

Let \(A\) be a set. Then the following hold for all \(x,y \in \lists{A}\).

  1. \(\infix(x,\cat(u,\cat(x,v))) = \btrue\) for all \(u,v \in \lists{A}\).
  2. If \(\infix(x,y) = \btrue\), then \(y = \cat(u,\cat(x,v))\) for some \(u,v \in \lists{A}\).
  1. We have \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,x) \\ & = & \infix(x,\cat(x,v)) \\ & = & \infix(x,\cat(u,\cat(x,v))) \end{eqnarray*}\] as claimed.
  2. We proceed by list induction on \(y\). For the base case \(y = \nil\), if \(\infix(x,y) = \btrue\), we have \(x = \nil\). Now \(x = y\), so that \(y = \cat(\nil,\cat(x,\nil))\) as needed. For the inductive step, suppose the implication holds for some \(y\) and let \(a \in A\). Suppose further that \(\infix(x,\cons(a,y)) = \btrue\). Now \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,\cons(a,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\infix(x,y)). \end{eqnarray*}\] We have two possibilities. If \(\prefix(x,\cons(a,y)) = \btrue\), then \(\cons(a,y) = \cat(x,z)\) for some \(z\); now \[\cons(a,y) = \cat(\nil,\cat(x,z))\] as needed. Suppose instead that \(\infix(x,y) = \btrue\). By the inductive hypothesis we have \(y = \cat(u,\cat(x,v))\) for some \(u\) and \(v\), so that \[\begin{eqnarray*} & & \cons(a,y) \\ & = & \cons(a,\cat(u,\cat(x,v))) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-cons} = & \cat(\cons(a,u),\cat(x,v)) \end{eqnarray*}\] as needed.

\(\infix\) interacts with \(\rev\).

Let \(A\) be a set. If \(x \in \lists{A}\), we have \(\infix(\rev(x),\rev(y)) = \infix(x,y)\).

Note that, for all \(x,u,v \in \lists{A}\), we have \[\begin{eqnarray*} & & \rev(\cat(u,\cat(x,v))) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-rev-cat-antidistribute} = & \cat(\rev(\cat(x,v)),\rev(u)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-rev-cat-antidistribute} = & \cat(\cat(\rev(v),\rev(x)),\rev(u)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-cat-associative} = & \cat(\rev(v),\cat(\rev(x),\rev(u))) \end{eqnarray*}\] In particular, \[y = \cat(u,\cat(x,v))\] for some \(u\) and \(v\) if and only if \[\rev(y) = \cat(h,\cat(\rev(x),k))\] for some \(h\) and \(k\). So \(\infix(x,y) = \btrue\) if and only if \(\infix(\rev(x),\rev(y)) = \btrue\).

\(\snoc(a,x)\) is not an infix of \(\nil\).

Let \(A\) be a set. For all \(a \in A\) and \(x \in \lists{A}\), we have \[\infix(\snoc(a,x),\nil) = \bfalse.\]

\[\begin{eqnarray*} & & \infix(\snoc(a,x),\nil) \\ & = & \isnil(\snoc(a,x)) \\ & \href{/posts/arithmetic-made-difficult/Snoc.html#thm-isnil-snoc} = & \bfalse \end{eqnarray*}\] as claimed.

\(\infix\) interacts with \(\snoc\).

Let \(A\) be a set. For all \(x,y \in \lists{A}\) and \(b \in A\), we have \[\infix(x,\snoc(b,y)) = \bor(\suffix(x,\snoc(b,y)),\infix(x,y)).\]

Note that \[\begin{eqnarray*} & & \infix(x,\snoc(b,y)) \\ & = & \infix(\rev(x),\rev(\snoc(b,y))) \\ & \href{/posts/arithmetic-made-difficult/Reverse.html#thm-rev-snoc} = & \infix(\rev(x),\cons(b,\rev(y))) \\ & = & \bor(\prefix(\rev(x),\cons(b,\rev(y))),\infix(\rev(x),\rev(y))) \\ & = & \bor(\prefix(\rev(x),\rev(\snoc(b,y))),\infix(x,y)) \\ & = & \bor(\suffix(x,\snoc(b,y)),\infix(x,y)) \end{eqnarray*}\] as claimed.

\(\infix\) is antisymmetric.

Let \(A\) be a set with \(x,y \in \lists{A}\). If \(\infix(x,y) = \btrue\) and \(\infix(y,x) = \btrue\), then \(x = y\).

Suppose \(\infix(x,y) = \btrue\); then we have \(u\) and \(v\) such that \[y = \cat(u,\cat(x,v)).\] Similarly, if \(\infix(y,x) = \btrue\) we have \(h\) and \(k\) such that \[x = \cat(h,\cat(y,k)).\] Now \[\begin{eqnarray*} & & x \\ & = & \cat(h,\cat(y,k)) \\ & = & \cat(h,\cat(\cat(u,\cat(x,v)),k)) \\ & = & \cat(\cat(h,u),\cat(\cat(x,v),k)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-cat-associative} = & \cat(\cat(h,u),\cat(x,\cat(v,k))) \end{eqnarray*}\] so that \(\cat(h,u) = \nil\) and \(\cat(v,k) = \nil\). Thus \(h = k = \nil\), and we have \[\begin{eqnarray*} & & x \\ & = & \cat(h,\cat(y,k)) \\ & = & \cat(\nil,\cat(y,\nil)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-cat-nil-right} = & \cat(\nil,y) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#cor-cat-nil} = & y \end{eqnarray*}\] as claimed.

\(\infix\) is transitive.

Let \(A\) be a set with \(x,y,z \in \lists{A}\). If \(\infix(x,y) = \btrue\) and \(\infix(y,z) = \btrue\), then \(\infix(x,z) = \btrue\).

If \(\infix(x,y) = \btrue\), we have \[y = \cat(u,\cat(x,v))$ for some $u$ and $v$, and if $\infix(y,z) = \btrue$ we have \]z = (h,cat(y,k))$ for some \(h\) and \(k\). Now \[\begin{eqnarray*} & & z \\ & = & \cat(h,\cat(y,k)) \\ & = & \cat(h,\cat(\cat(u,\cat(x,v)),k)) \\ & = & \cat(\cat(h,u),\cat(\cat(x,v),k)) \\ & \href{/posts/arithmetic-made-difficult/Cat.html#thm-cat-associative} = & \cat(\cat(h,u),\cat(x,\cat(v,k))) \end{eqnarray*}\] so that \(\infix(x,z) = \btrue\) as claimed.

Infixes are also sublists:

Let \(A\) be a set and \(x,y \in \lists{A}\).

  1. If \(\infix(x,y) = \btrue\), then \(\sublist(x,y) = \btrue\).
  2. If \(\prefix(x,y) = \btrue\), then \(\sublist(x,y) = \btrue\).
  3. If \(\suffix(x,y) = \btrue\), then \(\sublist(x,y) = \btrue\).
  1. We proceed by list induction on \(y\). For the base case \(y = \nil\), note that if \[\btrue = \infix(x,y) = \infix(x,\nil),\] we have \(x = \nil\). Then \[\sublist(x,y) = \sublist(\nil,y) = \btrue\] as needed. For the inductive step, suppose the implication holds for all \(x\) for some \(y\), and let \(a \in A\). Suppose further that \(\infix(x,\cons(a,y)) = \btrue\). Now \[\begin{eqnarray*} & & \btrue \\ & = & \infix(x,\cons(a,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\infix(x,y)). \end{eqnarray*}\] We consider two possibilities. If \(\prefix(x,\cons(a,y)) = \btrue\), we consider two possibilities for \(x\). If \(x = \nil\), we have \[\sublist(x,\cons(a,y)) = \sublist(\nil,\cons(a,y)) = \btrue\] as needed. Suppose then that \(x = \cons(b,u)\); since \(\prefix(x,\cons(a,y)) = \btrue\), we have \(b = a\) and \(\prefix(u,y) = \btrue\). Now \(\infix(u,y)\), and by the induction hypothesis \(\sublist(u,y) = \btrue\), so that \[\begin{eqnarray*} & & \btrue \\ & = & \sublist(u,y) \\ & = & \sublist(\cons(a,u),\cons(a,y)) \\ & = & \sublist(\cons(b,u),\cons(a,y)) \\ & = & \sublist(x,\cons(a,y)) \end{eqnarray*}\] as needed. Now suppose \(\infix(x,y) = \btrue\). By the induction hypothesis, we have \(\sublist(x,y) = \btrue\), so that \(\sublist(x,\cons(b,y)) = \btrue\) as needed.
  2. If \(\prefix(x,y) = \btrue\), then \(\infix(x,y) = \btrue\).
  3. If \(\suffix(x,y) = \btrue\), then \(\infix(x,y) = \btrue\).

\(\infix\) is an \(\any\).

Let \(A\) be a set. For all \(x \in \lists{A}\), we have \[\infix(x,y) = \any(\prefix(x,-))(\tails(y)).\]

We proceed by list induction on \(y\). For the base case \(y = \nil\), we have \[\begin{eqnarray*} & & \any(\prefix(x,-))(\tails(\nil)) \\ & = & \any(\prefix(x,-))(\cons(\nil,\nil)) \\ & = & \bor(\prefix(x,\nil),\any(\prefix(x,-))(\nil)) \\ & = & \bor(\prefix(x,\nil),\btrue) \\ & = & \prefix(x,\nil) \\ & = & \isnil(x) \\ & = & \infix(x,y) \end{eqnarray*}\] as needed. For the inductive step, suppose the equality holds for all \(x\) for some \(y\), and let \(a \in A\). Now \[\begin{eqnarray*} & & \infix(x,\cons(a,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\infix(x,y)) \\ & = & \bor(\prefix(x,\cons(a,y)),\any(\prefix(x,))(\tails(y))) \\ & = & \any(\prefix(x,-))(\cons(\cons(a,y),\tails(y))) \\ & = & \any(\prefix(x,-))(\tails(\cons(a,y))) \end{eqnarray*}\] as needed.

Testing

Suite:

_test_isInfix ::
  ( TypeName a, Equal a, Show a, Arbitrary a, CoArbitrary a
  , TypeName (t a), List t
  , Equal (t a), Show (t a), Arbitrary (t a)
  ) => Int -> Int -> t a -> IO ()
_test_isInfix size cases t = do
  testLabel1 "infix" t

  let args = testArgs size cases

  runTest args (_test_infix_list_nil t)
  runTest args (_test_infix_list_cons t)
  runTest args (_test_infix_prefix_or t)
  runTest args (_test_infix_reflexive t)
  runTest args (_test_infix_cat_right t)
  runTest args (_test_infix_cat_left t)
  runTest args (_test_infix_prefix t)
  runTest args (_test_infix_suffix t)
  runTest args (_test_infix_cond_cons t)
  runTest args (_test_infix_cond_snoc t)
  runTest args (_test_infix_cat_right_compatible_right t)
  runTest args (_test_infix_cat_right_compatible_left t)
  runTest args (_test_infix_cat_factor t)
  runTest args (_test_infix_rev t)
  runTest args (_test_infix_snoc_nil t)
  runTest args (_test_infix_snoc t)
  runTest args (_test_infix_antisymmetric t)
  runTest args (_test_infix_transitive t)
  runTest args (_test_infix_sublist t)
  runTest args (_test_prefix_sublist t)
  runTest args (_test_suffix_sublist t)
  runTest args (_test_infix_any t)

Main:

main_isInfix :: IO ()
main_isInfix = do
  _test_isInfix 30 1000 (nil :: ConsList Bool)
  _test_isInfix 30 1000 (nil :: ConsList Unary)