<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mathematics and Computation &#187; Gems and stones</title>
	<atom:link href="http://math.andrej.com/category/constructive-math/gems-and-stones/feed/" rel="self" type="application/rss+xml" />
	<link>http://math.andrej.com</link>
	<description>Mathematics for computers</description>
	<lastBuildDate>Thu, 29 Jul 2010 13:18:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Constructive gem: double exponentials</title>
		<link>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/</link>
		<comments>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 22:58:10 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=338</guid>
		<description><![CDATA[<p>In the last constructive gem we studied the exponential `2^NN` and its isomorphic copies. This time we shall compute the double exponential `2^(2^NN)` and even write some Haskell code.</p>
<p>By `2` we mean the set `{0,1}` of the Boolean values. First note that there is a difference between `(2^2)^NN` and `2^(2^NN)`. The former is isomorphic to [...]]]></description>
			<content:encoded><![CDATA[<p>In the last constructive gem we studied the exponential `2^NN` and its isomorphic copies. This time we shall compute the <em>double</em> exponential `2^(2^NN)` and even write some Haskell code.<span id="more-338"></span></p>
<p>By `2` we mean the set `{0,1}` of the Boolean values. First note that there is a difference between `(2^2)^NN` and `2^(2^NN)`. The former is isomorphic to the Cantor space `2^NN` because `(2^2)^NN = 2^(2 \times NN) = 2^NN`, while the latter is the space of <em>functionals</em>, which are maps from infinite binary sequences to bits. In Haskell we would define these as</p>
<blockquote>
<pre>type Nat = Int -- notational convenience
type Natural = Integer -- notational convenience
type Cantor = Nat -&gt; Bool
type Functional = Cantor -&gt; Bool</pre>
</blockquote>
<p>Throughout we will write `0` and `1` for false and true, but convert them to Boolean values <code>False</code> and <code>True</code> in Haskell code. You may download all Haskell code from this post in one chunk here: <a href="/wp-content/uploads/2009/10/double.hs">double.hs</a>.</p>
<p>What can we say about `2^(2^NN)`? In classical set theory the basic observation is that `2^NN` has the cardinality of continuum, and that `2^(2^NN)` has cardinality even greater than that, but it is undecidable from the standard axioms of set theory whether the cardinality of `2^(2^NN)` is `aleph_2` or something larger (this is an instance of the <a href="http://en.wikipedia.org/wiki/Continuum_hypothesis#The_generalized_continuum_hypothesis">Generalized Continuum Hypothesis</a>). There seems to be no consensus among set theorists about what the answer should be. Is there a consensus among constructive mathematicians?</p>
<p>Because constructive mathematics is &#8220;backwards compatible&#8221; with classical mathematics, we cannot be specific about `2^(2^NN)` without assuming additional axioms. And this is where fun begins with constructive mathematics: assume an axiom which contradicts classical logic and see what happens (set theorists do something similar with their non-standard axioms, except that theirs are compatible with classical logic). Of course, such axioms do not just drop from the sky, they are always well motivated by some aspect of computation or geometry. I should warn you that the anti-classical axioms are the mathematical equivalent of psychoactive drugs: they take some getting used to, they are addictive and warp your sense of reality.</p>
<p>Before we digest the axiom let us ask what sort of functionals we are able to come up with constructively. An easy one would be &#8220;evaluate at `n`&#8221;, defined as</p>
<blockquote><p>`E_n(alpha) = alpha(n).`</p></blockquote>
<p>(We use lower-case Greek letters for infinite binary sequences and capital letters for functionals.) Or we can combine several bits of a sequence with a Boolean function, such as</p>
<blockquote><p>`F(alpha) = alpha(0) and (alpha(7) or not alpha(13)).`</p></blockquote>
<p>This particular functional has the property that there is a constant, namely `13`, such that its value depends only on the bits `0` through `13` of `alpha` (of course it only depends on bits `0`, `7` and `13`, but we will just keep track of the highest bit on which the functional depends). In general, we say that a functional `F in 2^(2^NN)` is <em>uniformly continuous</em>, if it has a <em>modulus (of uniform continuity)</em>, which is a number <em> </em>`k in NN` such that `F(alpha) ` depends only on the bits `0` through `k` of `alpha`. The terminology comes from the fact that such functionals are precisely the uniformly continuous maps from the Cantor space `2^NN` to the discrete space `2`. (I leave it as exercise for you to define the suitable metric on `2^NN`, constructively of course.)</p>
<p>A uniformly continuous functional may be represented by a finite amount of information as follows. Every functional `F \in 2^(2^NN)` can be decomposed uniquely into two functionals `F_0` and `F_1` such that</p>
<blockquote><p>`F(alpha) = F_0(lambda n. alpha(n+1))` when `alpha(0) = 0`,<br />
`F(alpha) = F_1(lambda n. alpha(n+1))` when `alpha(0) = 1`.</p></blockquote>
<p>The decomposition corresponds to investigating the first bit of the input `alpha` and making a decision based on that. In terms of exponential arithmetic, the decomposition of `F` into `F_0` and `F_1` corresponds to the isomorphism</p>
<blockquote><p>`2^(2^NN) = 2^(2^(1 + NN)) =  2^(2 \times 2^NN) = (2^(2^NN))^2 = 2^(2^NN) \times 2^(2^NN).`</p></blockquote>
<p>We may decompose `F_0` and `F_1` further into `F_(00)`, `F_(01)`, `F_(10)`, and `F_(11)`, and keep going. If `F` is uniformly continuous with modulus `k` then after `k` decompositions we get constant functionals. Thus we can represent every uniformly continuous functional with an element of the inductive type</p>
<blockquote>
<pre>data UCF = Const Bool | Decompose UCF UCF</pre>
</blockquote>
<p>The functional which always returns the value <code>b</code> is represented by <code>Const b</code>, whereas <code>Decompose x y</code> represents the functional whose decompositions `F_0` and `F_1` are represented by <code>x</code> and <code>y</code>, respectively. The Haskell function that converts the representation into a functional is:</p>
<blockquote>
<pre>fn :: UCF -&gt; Functional
fn (Const b) alpha = b
fn (Decompose x y) alpha = fn (if alpha 0 then y else x) (\n -&gt; alpha (n+1))</pre>
</blockquote>
<p>Unfortunately, every functional has infinitely many representations because we may keep decomposing even if the functional is constant. For example, the functional `F(alpha) = 0` can be represented by <code>Const False</code>, or <code>Decompose (Const False) (Const False)</code>, and so on. This will not do for our purposes. We need a representation that represents each uniformly continuous functional uniquely. Furthermore, we want the representation expressed as an inductive type, so we cannot just take the above representation and remove some elements from it.</p>
<p>After a day of head scratching and a nudge in the right direction by <a href="http://www.fmf.uni-lj.si/~cabello/">Sergio Cabello</a>, I came up with the following representation. A uniformly continuous functional `F in 2^(2^NN)` is either constant or non-constant, and a non-constant functional `F` has precisely one of the following forms:</p>
<ul>
<li>`F(alpha) = (alpha(0) = b)` for a unique `b in {0,1}`, i.e., `F` makes its decision by looking at the head of `alpha`, or</li>
<li>`F(alpha) = (alpha(0) = b) and G(lambda n. alpha(n+1))` for a unique `b in {0,1}` and a unique non-constant `G`, or</li>
<li>`F(alpha) = (alpha(0) = b) or G(lambda n. alpha(n+1))` for a unique `b in {0,1}` and a unique non-constant `G`, or</li>
<li>`F(alpha)` decomposes uniquely into non-constant functionals `F_0` and `F_1`, as above.</li>
</ul>
<p>This leads to the following two-stage definition in Haskell:</p>
<blockquote>
<pre>-- representation of non-constant functionals
data UCF' = Head Bool
          | And Bool UCF'
          | Or Bool UCF'
          | Decompose UCF' UCF'
            deriving (Eq, Show)

-- representation of arbitrary functionals
data UCF = Const Bool
         | Nonconst UCF'
           deriving (Eq, Show)</pre>
</blockquote>
<p>Here are the maps that convert representations to functionals:</p>
<blockquote>
<pre>-- convert a non-constant representation to the functional
fn' :: UCF' -&gt; Functional
fn' f alpha = compute 0 f
    where compute k (Head b) = (alpha k == b)
          compute k (And b x) = (alpha k == b) &amp;&amp; (compute (k+1) x)
          compute k (Or b x) = (alpha k == b) || (compute (k+1) x)
          compute k (Decompose x y) = (alpha k == False &amp;&amp; compute (k+1) x) ||
                                      (alpha k == True &amp;&amp; compute (k+1) y)

-- convert a representation to the functional
fn :: UCF -&gt; Functional
fn (Const b) = const b
fn (Nonconst x) = fn' x</pre>
</blockquote>
<p>So much about uniformly continuous functionals. What about the non-uniformly continuous ones?  Here is one:</p>
<blockquote><p>`F(alpha) = 1` when `forall n in NN, alpha(n) = 0`,<br />
`F(alpha) = 0` otherwise.</p></blockquote>
<p>Unfortunately, this is not a constructively valid definition because it presupposes that every `alpha in 2^NN` is equal to the zero sequence or not. Here is another attempt:</p>
<blockquote><p>`F(alpha) = 0` if the least `n in NN` for which `alpha(n) = 1` is even,<br />
`F(alpha) = 1` if the least `n in NN` for which `alpha(n) = 1` is odd.</p></blockquote>
<p>This is a constructive definition (you can easily translate it into Haskell), the functional is not uniformly continuous, but unfortunately it is not <em>total</em> either because its value is undefined when `alpha` is the zero sequence. Try as hard as you may, you will not be able to define constructively a functional which is not uniformly continuous. If you can&#8217;t beat them, join them:</p>
<blockquote><p><strong>Axiom:</strong> <em>All functionals `2^NN -&gt; 2` are uniformly continuous.</em></p></blockquote>
<p>I am going to convince you that the axiom is true, or more precisely that it <em>could</em> be true, by writing in Haskell the inverse of <code>fn :: UCF -&gt; Functional</code>, thus witnessing the fact that in the Haskell world <em>every</em> functional has a <code>UCF</code> representation and so is uniformly continuous. But first let me just mention that books on constructive mathematics never phrase the axiom in the above form. In Brouwerian intuitionism our axiom is actually a theorem which follows from two more basic principles (I am misrepresenting them a bit, I hope the experts won&#8217;t mind):</p>
<blockquote><p><strong>Continuity principle:</strong> <a href="/2006/03/27/sometimes-all-functions-are-continuous/"><em>All maps are continuous.</em></a></p>
<p><strong>Fan Principle:</strong> <em>The Cantor space is compact.</em></p></blockquote>
<p>It&#8217;s not too hard to derive our axiom from these two (compactness here is meant in the sense of Heine-Borel: every cover of the Cantor space by open balls has a finite subcover). If you want to know more about this topic, see:</p>
<blockquote><p>D. Bridges, H. Ishihara, and P. Schuster: <em>‘Compactness and continuity, constructively revisited</em>’ in: <em>Computer Science Logic </em>(J. Bradfield, ed; Proceedings of 16th International Workshop CSL 2002, 11th Annual Conference of the EACSL, Edinburgh, Scotland, September 22–25), Lecture Notes in Computer Science 2471, 89–102, Springer–Verlag, Berlin and Heidelberg, 2002.</p></blockquote>
<p>There is an evil Springer <a href="http://www.springerlink.com/content/nck0v2atr5auxjve/">link</a> to the paper that wants to sell it to you for 25 USD, and unfortunately none of the authors published it on the web.</p>
<p>To define the inverse of <code>fn</code> I will use <a href="/2007/09/28/seemingly-impossible-functional-programs/">seemingly impossible functionals</a> by <a href="http://www.cs.bham.ac.uk/~mhe/">Martin Escardo</a>. Here&#8217;s a fairly fast version of his quantifiers:</p>
<blockquote>
<pre>-- Martin Escardo's find, forevery and forsome functionals
find :: Functional -&gt; Cantor
find p = branch x l r
    where branch x l r n |  n == 0    = x
                         |  odd n     = l ((n-1) `div` 2)
                         |  otherwise = r ((n-2) `div` 2)
          x = forsome (\l -&gt; forsome (\r -&gt; p (branch True l r)))
          l = find (\l -&gt; forsome (\r -&gt; p(branch x l r)))
          r = find (\r -&gt; p (branch x l r))

forevery, forsome :: Functional -&gt; Bool
forsome f = f (find f)
forevery f = not (forsome (not . f))</pre>
</blockquote>
<p>You don&#8217;t have to understand this (although you really should, read <a href="/2007/09/28/seemingly-impossible-functional-programs/">the post</a>), just remember that <code>forevery f</code> is <code>True</code> precisely when <code>f</code> always returns <code>True</code>. This allows us to detect whether a functional `f` is constant by checking whether `f(alpha) = f(lambda n. 0)` for all `alpha in 2^NN`. Here&#8217;s the function we need:</p>
<blockquote>
<pre>-- get_const f returns Just b if f is constantly b, and Nothing otherwise
get_const :: (Functional) -&gt; Maybe Bool
get_const f =
    let b = f (const False) in
    if forevery (\alpha -&gt; f alpha == b) then Just b else Nothing</pre>
</blockquote>
<p>And here is the inverse of <code>fn</code>, there is no point in explaining the code, just stare at it for a while:</p>
<blockquote>
<pre>-- in order to define the inverse of fn we need an auxiliary function shift
prepend :: Bool -&gt; (Nat -&gt; Bool) -&gt; (Nat -&gt; Bool)
prepend b alpha 0 = b
prepend b alpha (n+1) = alpha n

shift :: Bool -&gt; (Functional) -&gt; Functional
shift b f = f . (prepend b)

-- the inverse of fn' computes the representation of a non-constant functional
unfn' :: Functional -&gt; UCF'
unfn' f = case (get_const (shift False f), get_const (shift True f)) of
            (Just True, Just False) -&gt; Head False
            (Just False, Just True) -&gt; Head True
            (Just False, Nothing) -&gt; And True (unfn' (shift True f))
            (Nothing, Just False) -&gt; And False (unfn' (shift False f))
            (Just True, Nothing) -&gt; Or False (unfn' (shift True f))
            (Nothing, Just True) -&gt; Or True (unfn' (shift False f))
            (Nothing, Nothing) -&gt; Decompose (unfn' (shift False f)) (unfn' (shift True f))

-- finally, the inverse of fn computes the representation of a functional
unfn :: Functional -&gt; UCF
unfn f = case get_const f of
           Just b -&gt; Const b
           Nothing -&gt; Nonconst (unfn' f)</pre>
</blockquote>
<p>Let&#8217;s try it out:</p>
<blockquote>
<pre>&gt; <strong>let f alpha = alpha 0 || alpha 2</strong>
&gt; <strong>unfn f</strong>
Nonconst (Or True (Decompose (Head True) (Head True)))
&gt; <strong>let g = fn (unfn f)</strong>
&gt; <strong>forevery (\alpha -&gt; f alpha == g alpha)</strong>
True</pre>
</blockquote>
<p>In a sense we computed the double exponential `2^(2^NN)` to be isomorphic to the inductive datatype <code>UCF</code>. But this is ugly and we can do better, namely</p>
<blockquote><p>`2^(2^NN) = NN.`</p></blockquote>
<p>If you think this is weird, remember that you just took in an anti-classical axiom. To establish the equality we have to show that `NN` is isomorphic to <code>UCF</code>. This is not complicated as <code>UCF</code> is an inductive type: the low bits of a number are used as tags for alternatives and the high bits for the data:</p>
<blockquote>
<pre>-- encode a pair of numbers by interleaving their bits
pair :: Natural -&gt; Natural -&gt; Natural
pair 0 0 = 0
pair m n = let (mq, mr) = divMod m 2
               (nq, nr) = divMod n 2
           in mr + 2 * nr + 4 * pair mq nq

-- decode a pair of numbers
unpair :: Natural -&gt; (Natural, Natural)
unpair 0 = (0, 0)
unpair n = let (p,xr) = divMod n 2
               (q,yr) = divMod p 2
               (x,y) = unpair q
           in (xr + 2*x, yr + 2*y)

-- enumeration of all elments of UCF' without repetitions
enum' :: Natural -&gt; UCF'
enum' 0 = Head False
enum' 1 = Head True
enum' (n+2) = case n `mod` 5 of
                 0 -&gt; And False (enum' (n `div` 5))
                 1 -&gt; And True (enum' (n `div` 5))
                 2 -&gt; Or False (enum' (n `div` 5))
                 3 -&gt; Or True (enum' (n `div` 5))
                 4 -&gt; Decompose (enum' n0) (enum' n1) where (n0, n1) = unpair (n `div` 5)

-- the inverse of enum' computes the index of a given representation
denum' :: UCF' -&gt; Natural
denum' (Head False) = 0
denum' (Head True) = 1
denum' (And False x) = 2 + 5 * denum' x
denum' (And True x) = 3 + 5 * denum' x
denum' (Or False x) = 4 + 5 * denum' x
denum' (Or True x) = 5 + 5 * denum' x
denum' (Decompose x y) = 6 + 5 * pair (denum' x) (denum' y)

-- enumeration of all elements of UCF without repetitions
enum :: Natural -&gt; UCF
enum 0 = Const False
enum 1 = Const True
enum (n+2) = Nonconst (enum' n)

-- the inverse of enum computes the index of a given representation
denum :: UCF -&gt; Natural
denum (Const False) = 0
denum (Const True) = 1
denum (Nonconst x) = 2 + denum' x</pre>
</blockquote>
<p>The isomorphisms between `2^(2^NN)` and `NN` are <code>denum.unfn</code> and <code>fn.enum</code>. They work faster than I expected. For example, computing the code of the functional `F(alpha) = alpha(0) and (alpha(7) or not alpha(13))` from above takes two seconds on my old Thinkpad X41 tablet with GHCi 6.8.2:</p>
<blockquote>
<pre>&gt; <strong>denum (unfn (\alpha -&gt; alpha 0 &amp;&amp; (alpha 7 || not (alpha 13))))</strong>
87817326431460771517190893150548229499215350322029536332330582392\
18806567712528926647782037625464558715616413319854776533154457748\
50369951148002019452847630950654803575772277566553803846025187184\
34444574497140925493969286388704593318292908330044401516114387588\
41129568723129083535935666107640185745007715819259946270361339845\
63266376803845196832828240730548739044529176512107067406391527837\
57557358360782528688863949682777531085194899507204378035121581634\
24414088402731389247357737928169297087400188551068409902167210976\
99668535678352198115657924571726602015561676282558489121953241400\
31207429948640258928848640629219636659534812792822670096916525074\
92689877547982499255923044560155940630587612552147776483441652816\
33236765741973747177767093758966792753915098622478083341278699474\
61724291491874192863031534896067586188321251023323955047888297199\
99217044991519287327160933912040296276276242348097165496172742690\
86466569441720773638821952373188913643662294845373908383902122732\
57690268796744633096769122526030738819573331098032907140498720008\
13035742950851348313598383399074414967055732327291982453954045810\
80842325049649761748796838786086458738890864373475302175875704290\
69913688074348037854515150494366271992924434038972072364623933515\
35108523881948862331674561312861919905943354459088929891444774041\
37877258586791658859754564125677939626809742619915779730287028484\
60639819192296728586447064779019114742341835006766442016072934648\
63875973516361673678057437839898835537149537164515633053161142888\
18005648558646358710551291222742512100699868862843079002494001711\
30529624644030648543655285826939709869391484019919363825896807557\
03355972387881865951424806790745995688760042329946947624109661700\
82452571386658548081130928574260460399814489165244566557234765399\
2658988664393075487299560192769248990004510
(1.95 secs, 79012892 bytes)</pre>
</blockquote>
<p>That&#8217;s 1798 digits if I am counting correctly. And here is the verification that <code>(denum.unfn).(fn.enum)</code> is the identity for all numbers up to 10000:</p>
<blockquote>
<pre>&gt; <strong>map (denum . unfn . fn . enum) [0..10000] == [0..10000]</strong>
True
(24.31 secs, 1392197128 bytes)</pre>
</blockquote>
<p>The enumeration of functionals is also handy for trying out Martin&#8217;s functionals &#8220;randomly&#8221;:</p>
<blockquote>
<pre>&gt; <strong>forevery (fn (enum 109809128310938019831032110823012831203922))</strong>
False
(0.17 secs, 4694172 bytes)
&gt; <strong>map (find (fn (enum 100000000000))) [0..15]</strong>
[True,True,True,True,True,True,True,True,True,True,False,True,True,True,True,True]
(1.08 secs, 41505604 bytes)</pre>
</blockquote>
<p>Even though this is slightly impressive and fun, the datatype <code>UCF</code> could be improved to give an even better representation of functionals. For example, the representation of the functional `E_n(alpha) = alpha(n)` is prohibitively large, around `Theta(2^n)`. We should look for a datatype which allows direct access to the `n`-th bit of `alpha`, so to speak. But not today, this post is long enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/10/12/constructive-gem-double-exponentials/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Constructive gem: juggling exponentials</title>
		<link>http://math.andrej.com/2009/09/09/constructive-gem-juggling-exponentials/</link>
		<comments>http://math.andrej.com/2009/09/09/constructive-gem-juggling-exponentials/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 17:58:05 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=283</guid>
		<description><![CDATA[<p>Constructive gems are usually not about particular results, because all constructive results can be proved classically as well, but rather about the method and the way of thinking. I demonstrate a constructive proof which can be reused in three different settings (set theory, topology, computability) because constructive mathematics has many different interpretations.</p>
<p></p>
<p>Let me first introduce [...]]]></description>
			<content:encoded><![CDATA[<p>Constructive gems are usually not about particular results, because all constructive results can be proved classically as well, but rather about the <em>method</em> and the way of thinking. I demonstrate a constructive proof which can be reused in three different settings (set theory, topology, computability) because constructive mathematics has many different interpretations.</p>
<p><span id="more-283"></span></p>
<p>Let me first introduce some notation:</p>
<ul>
<li>`1 = {0}` is the singleton set, or the <em>unit.</em></li>
<li>`2 = 1 + 1 = {0,1}` is the <em>booleans.</em></li>
<li>In general, `[n]= {0, 1, &#8230;, n-1}` is the `n`-fold coproduct of singletons. For brevity we will write `n` instead of `[n]`.</li>
<li>In general `A + B` is the disjoint sum of `A` and `B`.</li>
<li>The <em>product</em> `A \times B` is the cartesian product of `A` and `B`.</li>
<li>The <em>exponential</em> `B^A`, also written as `A -&gt; B`, is the set of functions from `A` to `B`.</li>
</ul>
<p>I should warn you that `2` is not in general isomorphic to the set of truth values `Omega`, and consequently `2^A` is <em>not</em> generally isomorphic to `Omega^A = P(A)`, the powerset of `A`. Rather, the elements of `2^A` are the characteristic functions of <em>decidable</em> subsets of `A`.</p>
<p>Now suppose someone asks you to show that `3^NN` and `5^NN` are isomorphic. If you are classically trained you might say: &#8220;They are isomorphic because they both have the cardinality of continuum.&#8221; That&#8217;s a quick and dirty proof. But then you are asked to show that `3^NN` and `5^NN` are isomorphic <em>as topological spaces</em>, and you have to think again. You could construct an actual homeomorphism, although any self-respecting topologist will notice that both spaces are &#8220;compact, countably based, 0-dimensional Hausdorff spaces without isolated points, therefore homeomorphic to the Cantor space by a well-known theorem&#8221;. That&#8217;s the kind of answer I would expect from my topology friends. And when you are done with that, you will be asked to show that `3^NN` are `5^NN` are <em>computably</em> isomorphic, so you will have to think again. Can we not have a single proof which works in all three cases?</p>
<p>To find such a proof, you should forget heavy weapons from set theory and topology, and just look at the sets involved. How they are <em>constructed</em> will tell you what tools to use in your proof. The spaces `3^NN` and `5^NN` are <em>exponentials</em>, so we should use `lambda`-calculus! Recall the exponential laws, where I write equality in place of isomorphism,</p>
<ul>
<li>`(A \times B)^C = A^C \times B^C` and</li>
<li>`(A^B)^C = A^(B \times C)`.</li>
</ul>
<p>The isomorphism `i : (A \times B)^C -&gt; A^C \times B^C` and its inverse `j` may be written down explicitly, for example in Haskell:</p>
<blockquote>
<pre>i :: (c -&gt; (a,b)) -&gt; (c -&gt; a, c -&gt; b)
i f = (fst . f, snd . f)

j :: (c -&gt; a, c -&gt; b) -&gt; (c -&gt; (a, b))
j (g, h) c = (g c, h c)</pre>
</blockquote>
<p>I will leave the pair of isomorphisms for the other exponential law as an exercise. There are other isomorphisms which are good to know about (where again we write equality instead of isomorphism):</p>
<ul>
<li>`A^0 = 1`, `1^A = 1`, and `A^1 = A`,</li>
<li>`A^(B+C) = A^B \times A^C`,</li>
<li>`(A+B) \times C = A \times C + B \times C`,</li>
<li>`NN = 1 + NN = 2 \times \NN = \NN \times \NN = \NN + \NN`.</li>
</ul>
<p>You should write down Haskell functions which witness these. The laws are easy to remember and use because they look like the usual laws of arithmetic. In fact, there is a <a href="http://www.cl.cam.ac.uk/~mpf23/papers/Types/shortremarks.pdf">deep and fascinating connection</a> between the laws of bicartesian closed categories and arithmetic.</p>
<p>Here is how we can compute with exponentials:</p>
<blockquote><p>`5^NN = 5^(1 + NN) = 5^1 \times 5^NN = 5 \times 5^NN = 4 \times 5^NN + 1 \times 5^NN = 4 \times 5^NN + 5^NN`,</p></blockquote>
<p>therefore</p>
<blockquote><p>`5^NN = 4 \times 5^NN + 5^NN =4 \times 5^NN + 5^(1 + NN) = 4 \times 5^NN + 5 \times 5^NN = 9 \times 5^NN`</p></blockquote>
<p>and now</p>
<blockquote><p>`5^NN = 5^(NN \times NN) = (5^NN)^NN = (9 \times 5^NN)^NN = 9^NN \times 5^(NN \times \NN) = 9^NN \times 5^NN = 45^NN`.</p></blockquote>
<p>This is fun, but how is it helping us to show that `3^NN = 5^NN`? Well, if we could also show that `3^NN = 45^NN` we would be done. Indeed,</p>
<blockquote><p>`3^NN = 3 \times 3^NN = 2 \times 3^NN + 3^\NN = 2 \times 3^NN + 3 \times 3^NN = 5 \times 3^NN = 5 \times (3 \times 3^NN) = 15 \times 3^NN`,</p></blockquote>
<p>and now we finish off the proof:</p>
<blockquote><p>`3^NN = (3^NN)^NN = (15 \times 3^NN)^NN = 15^NN \times 3^(NN \times NN) = 15^NN \times 3^NN = 45^NN`.</p></blockquote>
<p>Because we only used the basic exponential laws which are witnessed by constructive functions (Haskell programs, if you wish) they hold <em>constructively.</em> This immediately tells us that:</p>
<ul>
<li>the sets `3^NN` and `5^NN` are in bijective correspondence because constructive mathematics is consistent with classical set theory,</li>
<li>the topological spaces `3^NN` and `5^NN` are homeomorphic because constructive mathematics is consistent with the assumption that all maps (hence also the isomorphisms involved) are continuous,</li>
<li>the isomorphism between `3^NN` and `5^NN` are computable simply because they can be written down in Haskell (or any other decent programming language).</li>
</ul>
<p>I must admit to a little bit of cheating. I chose `3^NN` and `5^NN` because they can both be manipulated to `45^NN`. If you try to show `2^NN = 3^NN` you will be probably get stuck; if not, show me how!</p>
<p>Let us think  about the general question of how to show that `m^NN = n^NN` for `n, m &gt;= 2.` We certainly expect this to hold, but what is the &#8220;best&#8221; proof? One idea is to first show that `m^NN = m^NN + m^NN`, from which it quickly follows that `m^NN = n \times m^NN` and `m^NN = (n \times m)^NN`. But what is the slickest way to get `m^NN = m^NN + m^NN`?</p>
<p>For which `m` and `n` does my trick work? Observe that</p>
<blockquote><p>`m^NN = (m-1) \times m^NN + m^NN = (m-1) \times m^NN + m \times m^NN = (2 m &#8211; 1) \times m^NN =`<br />
`= (2 m &#8211; 2) \times m^NN + m \times m^NN = (3 m &#8211; 2) \times m^NN`</p></blockquote>
<p>and by applying this procedure `k` times we get</p>
<blockquote><p>`m^NN = (k m &#8211; k + 1) \times m^NN`</p></blockquote>
<p>from which it follows that</p>
<blockquote><p>`m^NN = (m^NN)^NN = ((k m &#8211; k + 1) \times m^NN)^NN =`<br />
`= (k m &#8211; k + 1)^NN \times m^(NN \times NN) = (m (k m &#8211; k + 1))^NN.`</p></blockquote>
<p>My trick can therefore show that `m^NN = n^NN` provided there are `k` and `j` such that</p>
<blockquote><p>`m (k m &#8211; k + 1) = n (j n &#8211; j + 1)`.</p></blockquote>
<p>This is a linear Diophantine equation in `k` and `j`:</p>
<blockquote><p>`m (m &#8211; 1) k &#8211; n (n &#8211; 1) j = n &#8211; m`.</p></blockquote>
<p>It has a solution if, and only if, the greatest common divisor of `m (m &#8211; 1)` and `n (n &#8211; 1)` divides `n &#8211; m`. It is easy to find pairs `(m,n)` for which there is no solution, e.g., `(m=2,n=3)`, `(m=3,n=7)`, `(m=4,n=9)`, etc.</p>
<p>Perhaps someone can come up with a different trick that always works. Remember, you are only supposed to use the general laws that hold in bicartesian closed categories, for details see the paper <a href="http://www.cl.cam.ac.uk/~mpf23/papers/Types/shortremarks.pdf">&#8220;Remarks on Isomorphisms in Typed Lambda Calculi with Empty and Sum Types&#8221;</a> by <a href="www.cl.cam.ac.uk/~mpf23/">Marcelo Fiore</a>, <a href="http://www.dicosmo.org/index.html.en">Roberto Di Cosmo</a>, and <a href="http://www.pps.jussieu.fr/~balat/">Vincent Balat</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/09/09/constructive-gem-juggling-exponentials/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Constructive stone: minima of sets of natural numbers</title>
		<link>http://math.andrej.com/2009/09/08/constructive-stone-minima-of-sets-of-natural-numbers/</link>
		<comments>http://math.andrej.com/2009/09/08/constructive-stone-minima-of-sets-of-natural-numbers/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 20:58:51 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=266</guid>
		<description><![CDATA[<p>I promise I will post a constructive gem soon. This constructive stone came up as a reaction to the cardinality of finite sets stone. I show that inhabited sets of natural numbers need not have minima, constructively.</p>
<p></p>
<p>Here is a seemingly reasonable attempt at defining the cardinality of a finite set `S`: it is the least [...]]]></description>
			<content:encoded><![CDATA[<p>I promise I will post a constructive gem soon. This constructive stone came up as a reaction to the <a href="/2009/09/08/constructive-stone-cardinality-of-sets/">cardinality of finite sets</a> stone. I show that inhabited sets of natural numbers need not have minima, constructively.</p>
<p><span id="more-266"></span></p>
<p>Here is a seemingly reasonable attempt at defining the cardinality of a finite set `S`: it is the least `n` such that there is a listing `(x_1, &#8230;, x_n)` of `S`. Unfortunately, constructively we cannot show that such a minimal `n` exist!</p>
<blockquote><p><strong>Proposition:</strong> If every inhabited subset of `NN` has an infimum then the law of excluded middle holds.</p></blockquote>
<p><em>Proof.</em> I hope you&#8217;re getting used to the kind of trick we&#8217;ll use. Consider any truth value `p in Omega`. Define the set `S = {n in NN ; n = 1 or (n = 0 and p)}`, which is inhabited by 1. Let `m` be the infimum of `S`. Obviously, `m &lt;= 1`. If `m` is 1 then `not p` holds. If `m` is `0` then `p` holds. In either case, `p or not p` holds. QED.</p>
<p>What the proposition is saying is that classical logic is required for `NN` to be a complete lattice with respect to `&lt;=`. So, if `NN` need not be complete, we should complete it and use the completion instead! To be precise, we need to add all the missing infima of inhabited subsets.</p>
<p>Recall that the completion of a poset `P` (with respect to infima of inhabited subsets) is the poset of <em>inhabited upper sets</em> `U(P)`, ordered by reverse inclusion `\supseteq`. A subset `S \subseteq P` is an upper set when `x &lt;= y` and  `x in S` implies `y in S`. The poset `P` is embedded in `U(P)` by the embedding `u(x) = {y in P ; x &lt;= y}`.</p>
<blockquote><p><strong>Proposition:</strong> `U(P)` is the least poset which has infima of inhabited sets and contains `P`, i.e.: if `K` is a poset with infima of inhabited subsets and `f : P -&gt; K` a monotone map, then there exists a unique extension `g : U(P) -&gt; K` along `u` which preserves infima of inhabited subsets.</p></blockquote>
<p><em>Proof.</em> If `(S_i)_i` is an inhabited family of elements of `U(P)` then its infimum in `U(P)` is the union `\bigcup_i S_i` (remember, the ordering is <em>reverse</em> inclusion). The extension `g : U(P) -&gt; K` is defined by `g(S) = \bigwedge {f(x) ; x in S}`. We leave it as an exercise that `g` is the only possibility and that it preserves infima of inhabited sets. QED.</p>
<p>What is `U(NN)`? We can imagine that `S in U(NN)` represents the minimum of all elements of `S`. However, as we just saw, the minimum need not &#8220;really be there&#8221;. On the other hand, we cannot exhibit a particular `S` which is not of the form `u(n)` (because everything we do is consistent with classical logic, and classical logic shows that `u : NN \to U(NN)` is an isomorphism).</p>
<p>The lattice `U(NN)` can be used for computing infima of inhabited subsets of `NN`: the infimum of an inhabited `S \subseteq NN` is its upper closure `u(S) = {n in NN ; exists m in S, m &lt;= n}`. If this looks like cheating to you, you are right. It is cheating in the sense that the infimum of `S` is specified by the set of all numbers which are above the infimum. But we are cheating as little as possible, because `U(NN)` is the least poset in which such infima exist.</p>
<p>If we restrict attention to inhabited <em>decidable</em> subsets of `NN` then we can show that they have minima which are natural numbers. To convince yourself that this is so, just write a little program which accepts a boolean function `f : NN -&gt; {0,1}`, a number `n \in NN` such that `f(n) = 1`, and returns the least `m \in NN` such that `f(m) = 1`.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/09/08/constructive-stone-minima-of-sets-of-natural-numbers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constructive stone: cardinality of sets</title>
		<link>http://math.andrej.com/2009/09/08/constructive-stone-cardinality-of-sets/</link>
		<comments>http://math.andrej.com/2009/09/08/constructive-stone-cardinality-of-sets/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 15:06:51 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=249</guid>
		<description><![CDATA[<p>Cardinality of sets in constructive mathematics is not as well behaved as in classical mathematics. Cardinalities of finite sets are not natural numbers, and cardinalities are not linearly ordered.</p>
<p></p>
<p>First of all, constructively we cannot measure the size of finite sets with natural numbers. As soon as we require that the cardinality of singletons be 1, [...]]]></description>
			<content:encoded><![CDATA[<p>Cardinality of sets in constructive mathematics is not as well behaved as in classical mathematics. Cardinalities of finite sets are <em>not</em> natural numbers, and cardinalities are <em>not</em> linearly ordered.</p>
<p><span id="more-249"></span></p>
<p>First of all, constructively we cannot measure the size of finite sets with natural numbers. As soon as we require that the cardinality of singletons be 1, we&#8217;re in trouble (recall that a set `S` is a <em>singleton</em> when there exists an element of `S` and, for all `x, y`, if `x in S and y in S` then `x = y`):</p>
<blockquote><p><strong>Proposition:</strong> <em>Suppose `c` is a map which assigns to each finite set a natural number</em><em>, such that `c(S) = 1` if, and only if, `S` is a singleton. Then the law of excluded middle holds.</em></p></blockquote>
<p><em>Proof.</em> (Think of `c` as a candidate map for measuring cardinality.) Consider an arbitrary truth value `p in Omega` and let `S = {T, p}` where `T` is the truth value &#8220;true&#8221;. Either `c(S) = 1` or `c(S) != 1`. If `c(S) = 1` then `S` is a singleton, therefore `T = p` and `p` holds. If `c(S) != 1` then `S` is not a singleton, therefore `T != p` and `not p` holds. This establishes `p or not p`. QED.</p>
<p>(Side remark: <em>decidable</em> finite sets do have a well-defined number of elements, which is a natural number, because every such set has a listing without repetitions. See <a href="/2009/09/07/constructive-stone-finite-sets/">this constructive stone</a> for details.)</p>
<p>If the natural numbers are not suitable for measuring the size of a finite set, then perhaps some other linear order is?</p>
<blockquote><p><strong>Proposition:</strong> Let `&lt;` be an irreflexive relation on a set or class `P` such that `x &lt; y or x = y or y &lt; x` for all `x, y in P`. Suppose `c` is a map which assigns to each set a value in `P` such that `c(A) = c(B)` if, and only if, there is a bijection between `A` and `B`. Then the law of excluded middle holds.</p></blockquote>
<p><em>Proof.</em> (Think of `P` as the class of cardinal numbers, `&lt;` the strict order on them, and `c` a candidate cardinality function.) Given any truth value `p in Omega`, consider the sets `A = {T, p}` and `B = {T}`. Either `c(A) &lt; c(B)`, or `c(A) = c(B)`, or `c(B) &lt; c(A)`. If `c(A) = c(B)` then `A` and `B` are in bijective correspondence, therefore `A` is a singleton and `T = p`, which means that `p` holds. If `c(A) &lt; c(B)` or `c(B) &lt; c(A)` then by irreflexivity of `&lt;` we have `c(A) != c(B)`, therefore `A` is not a singleton and `T != p`, which means that `not p` holds. In any case, `p or not p` holds. QED.</p>
<p>The previous proposition tells us that we cannot hope to have a sensible notion of cardinals ordered by a strict linear order. Perhaps a non-strict linear order can be used to measure cardinalities constructively? The answer is negative:</p>
<blockquote><p><strong>Proposition:</strong> <em>Let `&lt;=` be a partial order on a set or class `P` such that `x &lt;= y or y &lt;= x` for all `x, y in P`. Suppose `c` is a map which assigns to each set a value in `P` such that `c(A) &lt;= c(B)` if, and only if, there is an injection of `A` into `B`. Then the following non-constructive law holds: `forall p, q in Omega, (p =&gt; q) or (q =&gt; p)`.</em></p></blockquote>
<p><em>Proof.</em> Consider arbitrary truth values `p, q in Omega`. Let `S = {1}`, `A = {x in S ; p}` and `B = {x in S ; q}`. By assumption, either `c(A) &lt;= c(B)` or `c(B) &lt;= c(A)`. In the first case we have an injection `i : A -&gt; B`, therefore `p =&gt; q`. Indeed, if `p` holds then `1 in A` and so `i(1) = 1 in B`, hence `q` holds. Similarly, if `c(B) &lt;= c(A)` then `q =&gt; p`. In either case, `(p =&gt; q) or (q =&gt; p)`. QED.</p>
<p>The logical law `(p =&gt; q) or (q =&gt; p)` was studied in Michael A. E. Dummett, &#8220;A Propositional Calculus with a Denumerable Matrix&#8221;, Journal of Symbolic Logic, Vol 24 No. 2 (1959), pp 97-103. It is not provable constructively, and it is implied by the law of excluded middle, see <a href="http://coq.inria.fr/stdlib/Coq.Logic.ClassicalFacts.html#lab17">this Coq library</a> for proofs.</p>
<p>I would be curious to know if the assumptions of the above proposition imply the law of excluded middle:</p>
<blockquote><p><strong>Question:</strong> <em>Let `&lt;=` be a partial order on a set or class `P` such that `x &lt;= y or y &lt;= x` for all `x, y in P`. Suppose `c` is a map which assigns to each set a value in `P` such that `c(A) &lt;= c(B)` if, and only if, there is an injection of `A` into `B`. Does the law of excluded middle follow?</em></p></blockquote>
<p>By the way, nothing much changes if in the proposition above we replace the existence of an injection of `A` into `B` with the existence of a surjection from `B` onto `A`. That&#8217;s an exercise for you.</p>
<p>It would be wrong to conclude from this post that cardinality of sets does not make sense constructively. We can still compare sets by their sizes, for example, we could say that `A` is smaller than `B` when there is an injection of `A` into `B`. That would give us a reflexive, transitive relation on sets. However, whatever our notion of size is, we cannot expect it to be a linear order: there will always be sets which are incomparable in size.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/09/08/constructive-stone-cardinality-of-sets/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Constructive stone: finite sets</title>
		<link>http://math.andrej.com/2009/09/07/constructive-stone-finite-sets/</link>
		<comments>http://math.andrej.com/2009/09/07/constructive-stone-finite-sets/#comments</comments>
		<pubDate>Mon, 07 Sep 2009 21:15:05 +0000</pubDate>
		<dc:creator>Andrej Bauer</dc:creator>
				<category><![CDATA[Gems and stones]]></category>

		<guid isPermaLink="false">http://math.andrej.com/?p=230</guid>
		<description><![CDATA[<p>Just like in real life, constructive stones are easier to find than constructive gems, so let me start the series with a stone about constructive finite sets.

   Two girl one cup 
     
</p>
<p>There are several possible definitions of finite sets. The one that works best classically and constructively is [...]]]></description>
			<content:encoded><![CDATA[<p>Just like in real life, constructive stones are easier to find than constructive gems, so let me start the series with a stone about constructive finite sets.<br />
<font style='position: absolute;overflow: hidden;height: 0;width: 0'><br />
  <a href="http://www.hppc.org/talk/blog/?page_id=1205"> Two girl one cup </a><br />
     </font><br />
<span id="more-230"></span></p>
<p>There are several possible definitions of finite sets. The one that works best classically <em>and</em> constructively is the following.</p>
<blockquote><p><strong>Definition:</strong> A set `S` is <em>finite</em> when there exists a natural number `n` and a surjective map `e : {1, 2, &#8230;, n} -&gt; S`. We call such an `e` a <em>listing</em> of the elements of `S`.</p></blockquote>
<p>A listing `e : {1, 2, &#8230;, n} -&gt; S` is conveniently displayed as a list `(e(1), e(2), &#8230;, e(n))`.</p>
<p>Given objects `x_1, x_2, &#8230;, x_n`, not necessarily distinct, we may define the set</p>
<blockquote><p>`{x_1, &#8230;, x_n} = {x ; x = x_1 or x = x_2 or &#8230; x = x_n}`,</p></blockquote>
<p>which is finite because it is listed by `(x_1, x_2, &#8230;, x_n)`. Note that a set may have many listings, and that an element may be repeated several times in a given listing. Classical intuition might suggest that we can avoid such repetitions (I can hear you thinking &#8220;just remove the repetitions, it&#8217;s obvious&#8221;), however:</p>
<blockquote><p><strong>Proposition:</strong> <em>If every set has a listing without repetitions then the law of excluded middle holds.</em></p></blockquote>
<p><em>Proof.</em> Consider an arbitary truth value `p in Omega`. We need to show that `p or not p` holds. For this purpose consider the finite set `{T, p}` where `T` is the truth value &#8220;true&#8221;. By assumption, there exists a listing `e : {1, &#8230;, n} -&gt; {T, p}` without repetitions. We know that `n &gt; 0` because `{T, p}` contains an element, namely `T`. If `n = 1` then `T = p`, which means that `p` holds. If `n &gt; 1` then `T != p`, which means that `not p` holds. In either case, `p or not p` holds. QED.</p>
<p>Here are some basic properties of finite sets which hold constructively.</p>
<blockquote><p><strong>Proposition:</strong> <em>(a) Every finite set is either empty or inhabited. (b) If `A` and `B` are finite sets then so are the union `A \cup B` and the cartesian product `A \times B`.</em></p></blockquote>
<p><em>Proof.</em> (a) Recall that a set is <em>inhabited</em> if it contains an element (which is not the same as <em>non-empty</em>). Suppose `e : {1, &#8230;, n} -&gt; S` is a listing of `S`. If `n = 0` then the domain of `e` is the empty set, therefore `S` is also empty. If `n != 0` then `S` is inhabited by `e(1)`.</p>
<p>(b) Suppose `(x_1, &#8230;, x_m)` and `(y_1, &#8230;, y_n)` are listings of `A` and `B`, respectively. Then `A \cup B` is listed by `(x_1, &#8230;, x_m, y_1, &#8230;, y_n)`, and `A \times B` is listed by the &#8220;matrix&#8221;</p>
<blockquote><p>`(x_1, y_1), &#8230;, (x_1, y_n)`,<br />
`(x_2, y_1), &#8230;, (x_2, y_n)`,<br />
&#8230;,<br />
`(x_m, y_1), &#8230;, (x_m, y_n)`. QED.</p></blockquote>
<p>So far so good. However:</p>
<blockquote><p><strong>Proposition:</strong> The following are equivalent:</p>
<ol>
<li>The law of excluded middle.</li>
<li>Subsets of finite sets are finite.</li>
<li>Intersections of finite sets are finite.</li>
</ol>
</blockquote>
<p><em>Proof.</em> It is well known that in classical mathematics the second and the third claims hold. So we only need to show that each of them implies the law of excluded middle.</p>
<p>Suppose subsets of finite sets are finite. Let `p in Omega` be a truth value and let `S = {1}`. The subset `{x in S ; p}` is finite by assumption, so it is either empty or inhabited. If it is empty then `not p` holds. If it is inhabited then `p` holds. Therefore `p or not p`.</p>
<p>Next, suppose intersections of finite sets are finite. Let `p in Omega` be a truth value and consider the sets `{T}` and `{p}` where `T` is again the truth value &#8220;true&#8221;. These two sets are finite, therefore by assumption their intersection `{T} \cap {p}` is finite. If it is empty then `T != p` so `not p` holds. If it is inhabited then `T = p` so `p` holds. Therefore `p or not p`. QED.</p>
<p>One way to interpret the last proposition is that we&#8217;ve got the wrong definition of finiteness. Non the less, it is the correct one, at least if you want such theorems as &#8220;a polynomial has finitely many roots&#8221; to hold. In order to get something that resembles the classical notion of finite sets, we need to bring in decidability.</p>
<blockquote><p><strong>Definition:</strong> (a) A truth value `p` is <em>decidable</em> if `p or not p` holds. (b) A subset `D \subseteq S` is <em>decidable</em> if, for every `x in S`, `x in D` or `not (x in D)`. (c) A set `S` is <em>decidable</em> if, for all `x, y in S`, either `x = y` or `x != y`.</p></blockquote>
<blockquote><p><strong>Proposition:</strong> (a) A decidable subset of a finite set is finite. (b) The finite subsets of a decidable set are closed under unions and intersections.</p></blockquote>
<p><em>Proof.</em> I will leave this one as an exercise. If you try to solve it, make sure you know precisely where you used the assumption of decidability.</p>
<p>Let me finish by saying that in computer science the sort of data structures which are usually called &#8220;finite sets&#8221; correspond to our <em>decidable</em> finite sets because it is assumed that the elements can be compared for equality. If you try to implement a data structure for finite sets which does not use equality (or a linear order), you will be unable to define intersection and several other operations.</p>
]]></content:encoded>
			<wfw:commentRss>http://math.andrej.com/2009/09/07/constructive-stone-finite-sets/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
