Friday, July 23, 2010

Does 1=.999...?

I heard a joke about logic a while back:

One man's modus ponens is another man's modus tollens

Though, I am hesitant to tell such a joke, for fear it will injure someone through uncontrollable side-splitting laughter. I am not responsible for burst spleens! ;)

It basically means any valid chain of reasoning can be run in two directions. For example:

Here's one proof for 1 = .999...


In Axiomatic System 1


(1) Assume: 1/3 = .333...
(2) Then adding this equation to itself three times results in:

1/3 = .333...
+ 1/3 = .333...
+ 1/3 = .333...
-------------------
1 = .999...

(3) Therefore 1 = .999...

However, this result seems a bit counter-intuitive.

There is however an equally valid argument that can be constructed by running this same chain of reasoning in reverse:


In Axiomatic System 2

(1) Assume: 1/3 = .333...
(2) Then adding this equation to itself three times results in:

1/3 = .333...
+ 1/3 = .333...
+ 1/3 = .333...
-------------------
1 = .999...

(3) Therefore, 1 = .999...
(4) However, clearly this conclusion is absurd. There is one point of difference, if we define the set of real numbers by repeatedly dividing a line into ten parts. The coordinate .999... would describe the next-to-last point in the line.
(5) Therefore we can conclude that the assumption (1) was false (by reductio ad absurdum).
(6) And since 1 > .999... by one point,

1/3 > .333...

Just like that we get a completely different conclusion.


Point Schmoint

Generally both axiomatic systems coincide on calculations, literally, 99.9... % of the time. Does a difference of a point or two matter? Who would notice the error in a calculation off by such a small amount?

The practical significance will emerge in a calculation that amplifies the difference, such as:

(1 - .999...) * (the number of points in a line of length 1)

This infinite summation is an indeterminate form, roughly:

0 * oo

In the first axiomatic system we may take this product to be 0. Since if the difference is truly zero, zero times anything must be zero.

In the second axiomatic system we may take this product to be equal to 1. Since if N represents the non-finite number of points in the line, 1/N * N = 1.

Neither 0 or 1 is "the" correct answer, any more than saying Checkers is "more correct" than Othello. Different ground rules will lead to different results in different games. A chain of reasoning only establishes a connection between a set of assumptions and the conclusion. It does not establish a direction the reasoning must travel along that chain. Just as we can accept the conclusion, we may equally reject both the conclusion and at least one assumption which led to it.

We might even imagine a system in which 1=0 (mod 1, for example), and both answers are correct. :)

So overall, we may take these numbers '1/3' and '.333...' to be infinitely close together on the number line, but not exactly equal. Or we may take them to be *exactly* equal -- the exact same point. Both systems can be consistent. But whether or not they are equal really depends on what our definition of "is equal" is.

Wednesday, July 21, 2010

1=0

Based on the definitions and axioms of standard arithmetic,'1=0' is a contradiction. However, there is nothing intrinsically contradictory about stating that '1=0' in isolation of a given set of definitions/axioms.

Math is a lot like a game of checkers. Abstractly, an axiomatic system can be reduced to three things:
  • a set of symbols (definitions)
  • a set of rules for manipulating those symbols (axioms)
  • a set of derived results (theorems)
In my view, the symbols are like the game pieces, the axioms are like the rules of the game, and a theorem is one particular game that can be played. What matters is internal consistency of the game. Since if there is a contradiction in the basic assumptions of the system, we can literally derive any result from them.

For example here is an inconsistent system, where two core axioms contradict each other:

System X

(1) X is true (assumption)
(2) X is not true (assumption)
(3) If X is true, then either X is true or pigs can fly. ('or' introduction from 1)
(4) But since X is not true (from 2), pigs can fly ('or' elimination from 1, 2)
(5) Therefore since we can replace 'pigs can fly' with any other random absurdity, if a system is inconsistent, we can derive any assertion from it.

So, if 'inconsistency' means that any result can be derived, 'consistency' just means there is there is least one thing that cannot be derived from the set of assumptions. To show consistency of a simple system consisting of '1=0', it's easy to show we cannot derive '1 != 0'. Since, from '1=0', the most we may derive is '1=2, 1=3, 1=4, ...'.

Therefore '1=0' is only inconsistent if we introduce definitions/axioms that make it so.


Usefulness of 1=0

Though, my next thought is "So '1=0' may be logically consistent, but is it useless? What can you do with a number system in which 1=0?"

However, consider a larger context of use. Likewise we may not see a good use for the number "zero" in only the context of itself. But when combined with other numbers, in a larger system, zero is useful precisely because it is the trivial case. And the trivial case becomes a pivot point for solving an equation, given it's unique properties when applied to operators.

So what is simple a real world example? Suppose we have a ceiling fan or lamp, that has a cyclic switch with four settings:
  • off
  • low
  • medium
  • high
Then in this context of settings it makes sense to state that 4=0 (mod 4). Or in alternate notation system we could simply write '0=4'. Since 0 and 4 can be used interchangeably without changing the truth value of an assertion like "if you click the switch N times, the fan will turn off." This is a cyclic number system that loops back on itself.

Now we could physically replace the fan switch with one with fewer possible states (3, 2, or 1). In the smallest number of states, we have a switch that is hardwired to be either always on or off. This is a system where 1 = 0 (mod 1) best models the situation. So we could view a wire as a cyclic switch, where states 1=0. A collection of switches AND wires, therefore, reduce to a collection of only switches. Not that this is the only way to see a problem, but the benefit is that it leads to a different way to see a problem (without requiring as many different types of components).


Combining inconsistent branches into a consistent superstructure:

There can be a fork in mathematics where on one branch '1=0' is an axiom, and on another branch '1!=0' is an axiom. Both are consistent when taken individually, but they are inconsistent in relation to each other. But are these two systems truly incompatible though?

Not necessarily. Both could be combined into one axiomatic superstructure, where the "loop" property of the number line was a variable.

For example, in a system where '1=0' the numbers loop at 1. In modular arithmetic, the line loops at some finite number > 1. And for standard arithmetic, the loop could be placed somewhere past the largest number we need. Not that this is the only approach to combining the two systems, but it's just an example.

So I think the interesting results from this line of reasoning are:

1. For any statement that is derivable in one axiomatic system, there exists at least one alternate axiomatic system such that the exact opposite result is derivable. Since at least, we may take that opposite result to be the starting axiom of the new system.

2. In general, any two incompatible axiomatic systems can be brought together under one super set of axioms, by simply adding one (or more) variables to axioms that switch results down one branch or the other. This is similar to re-factoring in software engineering, where different cases can always be brought together within the same handler, simply by introducing more variables.

3. The difference between "internal inconsistency of one system" and "external inconsistency between two systems" is arbitrary. Any subset of assumptions may be considered to be an independent axiomatic system. So, consistency problems within a single given system can likewise be resolved by the addition of (at least) one new variable. For example, considering "System X" again, we can introduce a new variable Y that easily resolves the contradiction:

System X+Y

(1') X is true if Y (assumption)
(2') X is not true if not Y (assumption)
(3') it's not possible to derive 'pigs can fly'

So rather than seeing two complete systems or axioms as inconsistent, we may see both as special cases of a larger framework of axioms.

The pros/cons of adding new variables to core axioms is that they increase the resolution of detail, but decrease the simplicity. Really, the practical problem in designing an axiomatic system isn't so much in getting the system to be consistent, but in preventing it from becoming too complex and unwieldy to use.

Sunday, July 18, 2010

Paradox: I'm lying, and that's a promise

I remember years ago, on the old "Star Trek" series, Spock told a robot that he was lying, and it made the robot's head explode.

That paradox fascinated me, because it is such a simple paradox, but it is tricky to analyze. It cleverly sets all the logic about itself in a tight loop. I wondered:

  • Does the statement have a truth value?
  • Is the statement valid?
  • If something is screwy with the statement, what exactly is it?
After giving it some thought, my analysis of this type of paradox was:

Consider:

(1) This sentence is false.

(2) Suppose the statement at (1) is either true or false. The analysis will explore the two branches independently.
(3.a) First assume it is true. Then from (1), we can easily derive that the statement is false.
(3.b) Now assume it is false. No further deduction can be made using (1) within this branch. Since any attempt to prove the truth of (1) would also be relying on (1) as an assumption, which we just assumed to be false.
(4) Hence, either way, the reasoning terminates on the conclusion that the statement at (1) is false.

What's curious is the logic stemming from the paradox is not really symmetrical.

In deriving the falsity of the statement (1), we have a valid line of reasoning (reductio ad absurdum). However, attempting to derive the opposite result -- that the statement is is true -- is invalid (circular reasoning). Using (1) in any manner to prove that (1) is true assumes the conclusion. And if the statement is false, we don't know that the mechanism that would allow a desired inference would even be supported, as there's more than one way a statement can be false.

So then what exactly is screwy with the statement? The problem is simple, but to model this more precisely, I will need better notation.

Define a set of distinct truth values {0, 1, null}.

As an analogy, "0" will function like "false", "1" will function like "true," and just to be safe "null" is anything else that doesn't fit in the previous two categories, for example, an incomplete thought, or gibberish. The value "null" value will propagate to anything it touches.

But how would I determine if a statement would map to one of these values?
What does it means for a mathematical statement to be "true?"

For a simple example, if I defined numbers like:

Let 1 be a primitive
Let + be an operation
Let 2 = 1+1
Let 3 = 1 + 1 + 1
Let 4 = 1 + 1 + 1 + 1
...

Then a statement like 2+2=4 is "true" since it's derivable from the basic definitions/axioms:

4 = 1+1+1+1 = (1+1) + (1+1) = 2+2

Generally, in math, if "a statement is true" it just means that it's derivable from the given set of definitions/axioms. So more precisely:

Define a function truth_value(P) that maps an assertion P to its truth value such that:
The return value is 1, if P is derivable from the given set of definitions/axioms.
The return value is 0, if a contradiction (like 1=0) can be derived from P and the given set of definitions/axioms.
The return value is null otherwise.

Also the statement at (1) contains a semantic structure like "P is false," which operates like an inverter on the truth value. For example if P is true, "P is false" is false. If P is false, "P is false" is true. This function essentially just flips the truth value of P. To model this more precisely:

Define a truth function inverter(x) such that:
The return value is 1, if x = 0.
The return value is 0, if x = 1.

Note: if the number is a value 1 or 0, the function is just:

inverter(x) = 1 - x.

Now the statement at (1) is only talking about truth values. And it's asserting (at least) two different things. If we let the variable S refer to the statement at (1), the assertions are:

The statement is false:

truth_value(S) = 0

and a self-reference roughly like "S = 'S is false'" sets up an identity statement about the truth values:

truth_value(S) = inverter(truth_value(S))

I can extract more things from the statement (like more complex combinations of the above two identities), but ultimately, in exploding a statement into a package of simpler assertions, all these things would be AND'ed together to form the complete thought.

But I'm only interested in showing the falsity of the entire package. It's sufficient that if any one of these components is false, any larger AND statement containing these two assertions will also be false.

Now simplifying, if we let:

x = truth_value(S)

Then what is asserted at the bottom of the paradox is a set of linear equations:

x = 0
x = 1 - x
...

The "solution" implies that 1 = 0. By definition, this is a contradiction, so we can say the entire the complete package of assertions in (1) is false (in a system of binary truth values). The self-reference implicitly sets up an impossible set of constraints, so the reference is exactly what is false.

The interesting morals of the story, I think, are:

Generally a reference can bear a truth value. For example, suppose a wrecking crew shows up, and someone asks "Hey boss, where's the house we are supposed to demolish?" If the boss man points to the wrong house and says "That," it's precisely the reference that is false.

Self-references are fine, but they are assertions, as they implicitly set up an identity relation. Those assertions can be incorrect just like anything else. But in pointing a reference back to the statement containing the reference, the self-reference is effectively camouflaged so as to hardly look like an assertion at all.

Circular reasoning is a tricky issue to diagnose, and any kind of recursive definition will naturally lend itself to this problem.

Atari 2600 games

The Atari emulator called "Stella" brings the old Atari 2600 games back to life. Honestly these games are sometimes terrible by modern standards. :) Though, they do have an interesting primitive appeal, and I wanted screen shots of them. Maybe I will make them into a desktop background.

I think my favorite was H.E.R.O, where you could explore caverns (across multiple screens) and rescue trapped minors.

Here are more or less all the games I purchased back in the day...











































Wednesday, July 7, 2010

Google Voice

Google has a new (free) phone service that's interesting. You can set up a new phone number that will forward a call to any number of other phones. So it's like a virtual phone, pointing to physical devices. Here's a quick overview:

http://www.google.com/googlevoice/about.html

I had been thinking of something similar for mailing addresses. If the postal service would recognize a set of virtual addresses, it would be possible to make a free service that would resolve a virtual address to a physical mailing addresses as well. Then if you move from one physical address to another, you could just update a pointer in the abstraction layer rather than notifying hundreds of people about the change. The virtual mailing address could always be the same.

Thursday, June 10, 2010

Music collaboration from two physical locations (using free software)

Here's a proof of concept where two or more people contribute tracks to a project from two different physical locations. I will show how to do set this up at the lower level. This can all be accomplished without any centralized servers. What's needed are three things:

1. Network configuration
2. Multitrack recording software
3. Source control

Also a simple Instant Messenger can be used for each person to know what's state the project is in.


1. Network Configuration

To get machines to communicate directly with each other, first we need to know their IP addresses. Actually, there's usually more than one IP address we need. To get the external IP address that the world sees, the easiest thing is to go to a site like

http://www.whatsmyip.com

This is the public IP address that would need to be given to all the contributors of a project.

Another way to get this IP on Linux, I added this to my ~/.profile file:

alias whatsmyip="wget -q -O - checkip.dyndns.org|sed -e 's/.*Current IP Address: //' -e 's/<.*$//'"

Then I can just run this to get my IP:

whatsmyip


Now, usually all machines on a small network will share the same external IP address. Inside the network, they are usually given a different "internal" IP address. The problem now, packets coming from the outside will need to be routed to the particular machine with the project files.

This is configured in the router, and will be different for each router brand/make/model. It may be called DMZ (after demilitarized zone), port forwarding, or under Applications/Games settings.

Ideally you can forward network packets to a static mac address of the computer (a mac address won't change).

Though my router only allows routing packets to an internal IP. My home network is DHCP (which is standard configuration, for a wireless router plugged into a cable modem). It's the easiest way to set up a network at home. If I plug my computer into the router, it is assigned a *dynamic* internal IP. But this also means if I unplug my machine, the internal IP's addresses can change and reset when plugging them back in to the network. That makes it a problem if you always want the same packets going to the same internal IP address.

There's a couple approaches around this.

The simplest: once a machine is plugged in, it can just be left on. The IP shouldn't change unless it's unplugged. And even then, it may not.

Also, you can have static IP's on a DHCP network. One way to do this is to set the DHCP address of the machine directly when it boots up. For example, on Linux:

ifconfig eth0 ip.addr.goes.here

To make this run automatically on every boot, drop this line in /etc/rc.local

So let's say my router is at 192.168.0.1, and assign a static IP to my machine on the same network:

ifconfig eth0 192.168.0.100

Then in the router, I would forward all internet traffic to a port to this address 192.168.0.100. This setup will be different for different routers. In my Linksys wireless router, I went to the web interface, which by default was at http://192.168.0.1 and found this under "Applications & Gaming" Let's say we are forwarding all traffic going to port 8000. Route this to the machine at 192.168.0.100.

Overall, whenever someone makes a request to the external IP, that request needs to reach the particular machine on your network. It's best to only expose the particular port(s) you will need.

The network routing will look something like:



internet traffic: hits external IP on port 8000 (public IP)
actually goes to: 192.168.0.1 (router)
which fowards to: machine 192.168.0.100 (machine with project)



Also for security, I would say to be sure you changed the user/password on the router, if you are exposing any ports or machines in your network to the internet. If anything doesn't work, it's probably going to be at the routing level.


2. Picking a multitrack recorder

For free software, I think Audacity or Traverso are good picks for collaboration. Audacity and Traverso are both simple and run on Windows, Mac, and Linux. The only point I'd say they are lacking, is in supporting real time LAPSDA effects. Still for the basic task, it's perfectly usable. Any software should work though, so long as everyone has it, and is using the same version.


3. Picking a version control system

The simplest method of sharing files and collaborating is to FTP files up to a central server. For simple and small projects, that's probably the best approach.

Although with multiple contributors, this has some pros and cons long term. What happens if a file gets corrupted? Or two people edit the same file, and the last person overwrites the changes without realizing? Or someone loses a change, and needs to "undo"

Version Control Systems are like FTP, but add several things:

(1) allows an unlimited number of "undos" every time the files are "saved." Like a running backup.
(2) source control protects against one change clobbering another.
(3) can automatically merge changes made to two locations of the same file

Looking at different systems for large binary files, I've ranked the best for this task IMO:

mercurial
git
bazaar


svn (requires central server)

IMO Mercurial may be the best pick here (though I haven't used it much). Mercurial has good support on all major platforms and works well with large binary files.  Git should also work ok.

A very short mercurial tutorial: http://linux.com/feature/121157

Mercurial has four ways to publish files for other users:

1. over a file system (the directory IS the repository)
2. a built in web server
3. cgi (with apache)
4, ssh

Probably the easiest is option 2. It's not the most robust only supports one connection at a time. But it's very lightweight and easy to set up. The best option for heavy use, is probably 4.

To create a new repository on the main machine 192.168.0.100 (which is has a port exposed to the internet)

cd project_dir # navigate to the new project dir
hg init # create the repository
hg add # add all the new files
hg commit -m "some message" # commit (or okO them to the repository
hg serve # set up a mini web server on port 8000 (default)
# this will run untill you kill it.


hg is the chemical symbol for mercury :)

Now you can allow this process to run untill the other person is synced up, and kill it when you are done. No real need to have it always running. On rare occasion, something might already

The other person can pull files down with:

# pull a copy of your project down from the address
# http://ip:port
hg clone http://your.extern.ip.addr:8000 project_dir

After adding new files to the project, they can run:

hg add # add all their new files
hg commit -m "another note" # commit (or ok) the changes to the repository
hg push http://your.extern.ip.addr:8000 # push changes back to the repository

Note this will not delete files as they are deleted from the system (as in cleaning up unused sources, although it wouldn't save disk space any way, since source control will still keep a versioned record of them.

Likewise, when you add more to the project, you can just do:

hg add # add all the new files
hg commit -m "explain changes" # commit them to the repository
# no need to push ... your directory is the repository

If they want to get additional changes they use:

cd project_dir # navigate to the project dir
hg pull # get all the new files
hg commit -m "another note" # commit (or ok) the changes to the repository
hg push # push changes back to the repository


Running into an ssl problem

By default push requires ssl. You can start the service with

hg serve --certificate

On a trusted network, or lower security testing, you can use edit this file (in the repository that will be accepting data):

.hg/hgrc

Add this configuration to allow files from everyone, over http

[Web]
push_ssl = false
allow_push = *

For a little more security around accepting data, limit by username:

allow_push = frodo, sam
deny_push = gandalf

And turn off the server when you're not expecting a file. Probably this is pretty low risk, if you are just trading audio files back and forth (like sending files over email).

Though, if there's a lot of file sharing I'd recommend spending time to set up https or ssh. This guide is more or less a bare-bones approach of setting it up, and deciding if it's workable.

Hopefully that explains it all ... the only problem is getting these components to work together in a way that is easy for the end user. :)

mercurial book:

http://hgbook.red-bean.com/read/a-tour-of-mercurial-the-basics.html


4. Making it easy to Use

All the pieces exist, but it's just a matter or hooking them together, and making it easy to use. Which IMO means the user interface for the multitrack recorder should have a couple standard options:

Open, Save, Save As, ...

But also the file menu could have options like:

Create Shared Project
Checkout Shared Project
Commit Shared Project

When setting up a local repository, there could also be options to limit users/IP's.

Then, instead of opening up a project file on the local machine, you could give it a URL where a project repository exists. "Checkout" pulls the changes down from the server, and "Commit" pushes up new changes.

Network configuration is about the only thing that couldn't be automated, unless there were a centralized server that everything routed traffic through.

Saturday, June 5, 2010

Growing Butterflies

Caterpillars arrived:



Forming chrysalids:


Transporting to the cage:



I found some parts of them left "behind" in their old container :)


It's alive!


A bloody stool (gets rid of excess tissue):


It's hard to get a picture with the wings open: