Binary addition for Turing Machine simulator

Mark Jason Dominus <[email protected]>
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Perhaps someone can use this as a subroutine to put together a 
multiplication program.
To add 6 and 11, use

	perl tm.pl addition.tm 110_1011

which then outputs

	10001


I had forgotten how tedious it is to write these things.
It's almost impossible to do it without thinking about writing a 
compiler instead.
It would be very easy to extend the input language to support

	statename STEP LEFT THEN otherstate

which would abbreviate

	statename _ otherstate _ L
	statename 0 otherstate 0 L
	statename 1 otherstate 1 L
	...
	statename z otherstate z L

or one could add:

	statename SEEK RIGHT TO 0 THEN otherstate

which would abbreviate

	statename _ statename _ R
	statename 0 gen00127 0 R
	statename 1 statename 1 R
	...
	statename z otherstate z R
	gen00127 STEP LEFT THEN otherstate


Anyway, here is the adder.  I have tested it with all combinations of 
inputs up to 4 bits long, so I think it works correctly.


# The head is positioned at the leftmost addend digit
# Seek to space past addend
Amr0 1 Amr0 1 R
Amr0 0 Amr0 0 R
Amr0 X Amr0 X R
Amr0 _ Bmr0 _ R

Amr1 1 Amr1 1 R
Amr1 0 Amr1 0 R
Amr1 X Amr1 X R
Amr1 _ Bmr1 _ R

# The head is positioned at the leftmost augend digit
# Seek to the rightmost augend digit
Bmr0 0 Bmr0 0 R
Bmr0 1 Bmr0 1 R
Bmr0 X GB0  X L
Bmr0 _ GB0  _ L

Bmr1 0 Bmr1 0 R
Bmr1 1 Bmr1 1 R
Bmr1 X GB1  X L
Bmr1 _ GB1  _ L

# The head is either at the rightmost augend digit
# or it is in the separator
GB0 0 Bml0 X L
GB0 1 Bml1 X L
GB0 _ AXl0 _ L

GB1 0 Bml1 X L
GB1 1 Bml2 X L
GB1 _ AXl1 _ L

# Move left past the augend and the separator
Bml0 0 Bml0 0 L
Bml0 1 Bml0 1 L
Bml0 _ Aml0 _ L

Bml1 0 Bml1 0 L
Bml1 1 Bml1 1 L
Bml1 _ Aml1 _ L

Bml2 0 Bml2 0 L
Bml2 1 Bml2 1 L
Bml2 _ Aml2 _ L

# Find the rightmost digit of the addend and erase it
Aml0 0 Asl0 X L
Aml0 1 Asl1 X L
Aml0 X Aml0 X L
Aml0 _ Csl0 _ L

Aml1 0 Asl1 X L
Aml1 1 Asl2 X L
Aml1 X Aml1 X L
Aml1 _ Csl1 _ L

Aml2 0 Asl2 X L
Aml2 1 Asl3 X L
Aml2 X Aml2 X L
Aml2 _ Csl2 _ L

# Skip left past the rest of the addend
Asl0 0 Asl0 0 L
Asl0 1 Asl0 1 L
Asl0 _ Csl0 _ L

Asl1 0 Asl1 0 L
Asl1 1 Asl1 1 L
Asl1 _ Csl1 _ L

Asl2 0 Asl2 0 L
Asl2 1 Asl2 1 L
Asl2 _ Csl2 _ L

Asl3 0 Asl3 0 L
Asl3 1 Asl3 1 L
Asl3 _ Csl3 _ L

# Skip left past the sum and write the sum digit
Csl0 0 Csl0 0 L
Csl0 1 Csl0 1 L
Csl0 _ CLl0 0 L

Csl1 0 Csl1 0 L
Csl1 1 Csl1 1 L
Csl1 _ CLl0 1 L

Csl2 0 Csl2 0 L
Csl2 1 Csl2 1 L
Csl2 _ CLl1 0 L

Csl3 0 Csl3 0 L
Csl3 1 Csl3 1 L
Csl3 _ CLl1 1 L

# Now the head is to the left of the sum.  Move right one space
CLl0 _ Cmr0 _ R
CLl1 _ Cmr1 _ R

# The head is at the leftmost digit of the sum.  Locate the addend
Cmr0 0 Cmr0 0 R
Cmr0 1 Cmr0 1 R
Cmr0 _ Amr0 _ R

Cmr1 0 Cmr1 0 R
Cmr1 1 Cmr1 1 R
Cmr1 _ Amr1 _ R

# The following is the ending routine, reached when the augend is
# exhausted.  The head is at the rightmost digit of the addend.
# Scan left past Xes.
# If we find a digit, erase it and continue as usual.
# If not, the addend is exhausted as well.
AXl0 0 Asl0 X L
AXl0 1 Asl1 X L
AXl0 X AXl0 X L
AXl0 _ FINA _ R

AXl1 0 Asl1 X L
AXl1 1 Asl2 X L
AXl1 X AXl1 X L
AXl1 _ AEl1 _ L

# The head is at the rightmost digit of the sum; we have another 1
# left to write at the left end
AEl1 0 AEl1 0 L
AEl1 1 AEl1 1 L
AEl1 _ FINC 1 R

FINC 0 FINC 0 R
FINC 1 FINC 1 R
FINC _ FINA _ R

FINA X FINA _ R
FINA _ FINB _ R

FINB X FINB _ R
FINB _ HALT _ R
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.