|
|
Line 1: |
Line 1: |
| '''FRACTRAN''' is a [[Turing-complete]] [[esoteric programming language]] invented by the mathematician [[John Horton Conway|John Conway]]. A FRACTRAN program is an [[sequence|ordered list]] of positive [[fraction (mathematics)|fractions]] together with an initial positive integer input ''n''. The program is run by updating the integer ''n'' as follows:
| | Hi there, I am Alyson Boon although it is not the title on my birth certificate. Invoicing is what I do for a residing but I've usually needed my personal company. Mississippi is where her home is but her spouse tarot card readings - [https://www.machlitim.org.il/subdomain/megila/end/node/12300 www.machlitim.org.il], wants them to transfer. As a lady what she truly likes is style and she's been performing it for fairly a while.<br><br>Also visit my web-site ... [http://www.aseandate.com/index.php?m=member_profile&p=profile&id=13352970 psychic readings online] reader - [http://www.prayerarmor.com/uncategorized/dont-know-which-kind-of-hobby-to-take-up-read-the-following-tips/ www.prayerarmor.com], |
| #for the first fraction ''f'' in the list for which ''nf'' is an integer, replace ''n'' by ''nf''
| |
| #repeat this rule until no fraction in the list produces an integer when multiplied by ''n'', then halt.
| |
| | |
| Conway gave an interesting [[formula for primes]] in FRACTRAN:
| |
| | |
| : <math>\left( \frac{17}{91}, \frac{78}{85}, \frac{19}{51}, \frac{23}{38}, \frac{29}{33}, \frac{77}{29}, \frac{95}{23}, \frac{77}{19}, \frac{1}{17}, \frac{11}{13}, \frac{13}{11}, \frac{15}{14}, \frac{15}{2}, \frac{55}{1} \right)</math>
| |
| | |
| Starting with ''n''=2, this FRACTRAN program generates the following sequence of integers:
| |
| | |
| :2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, ... {{OEIS|id=A007542}}
| |
| | |
| After 2, this sequence contains the following powers of 2:
| |
| | |
| :<math>2^2=4,\, 2^3=8,\, 2^5=32,\, 2^7=128,\, 2^{11}=2048,\, 2^{13}=8192,\, 2^{17}=131072,\, 2^{19}=524288,\, \dots</math> {{OEIS|id=A034785}}
| |
| | |
| which are the prime powers of 2.
| |
| | |
| == Understanding a FRACTRAN program ==
| |
| A FRACTRAN program can be seen as a type of [[register machine]] where the registers are stored in prime exponents in the argument ''n''.
| |
| | |
| Using [[Gödel numbering]], a positive integer ''n'' can encode an arbitrary number of arbitrarily large positive integer variables.<ref group=note>[[Gödel numbering]] cannot be directly used for negative integers, floating point numbers or text strings, although conventions could be adopted to represent these data types indirectly. Proposed extensions to FRACTRAN include [http://www.esolangs.org/wiki/Fractran_plus_plus FRACTRAN++] and [http://home.nvg.org/~oerjan/esoteric/bag/ Bag].</ref> The value of each variable is encoded as the exponent of a prime number in the [[Integer factorization|prime factorization]] of the integer. For example, the integer
| |
| | |
| :<math>60 = 2^2 \times 3^1 \times 5^1</math>
| |
| | |
| represents a register state in which one variable (which we will call v2) holds the value 2 and two other variables (v3 and v5) hold the value 1. All other variables hold the value 0.
| |
| | |
| A FRACTRAN program is an ordered list of positive fractions. Each fraction represents an instruction that tests one or more variables, represented by the prime factors of its [[denominator]]. For example:
| |
| | |
| :<math>f_1 = \frac{21}{20} = \frac{3 \times 7}{2^2 \times 5^1}</math>
| |
| | |
| tests v2 and v5. If <math>v_2 \ge 2</math> and <math>v_5 \ge 1</math>, then it subtracts 2 from v2 and 1 from v5 and adds 1 to v3 and 1 to v7. For example:
| |
| | |
| :<math>60 \cdot f_1 = 2^2 \times 3^1 \times 5^1 \cdot \frac{3 \times 7}{2^2 \times 5^1} = 3^2 \times 7^1</math>
| |
| | |
| Since the FRACTRAN program is just a list of fractions, these test-decrement-increment instructions are the only allowed instructions in the FRACTRAN language. In addition the following restrictions apply:
| |
| | |
| :*Each time an instruction is executed, the variables that are tested are also decremented.
| |
| :*The same variable cannot be both decremented and incremented in a single instruction (otherwise the fraction representing that instruction would not be in its [[lowest terms]]). Therefore each FRACTRAN instruction consumes variables as it tests them.
| |
| :*It is not possible for a FRACTRAN instruction to directly test if a variable is 0 (However, an indirect test can be implemented by creating a default instruction that is placed after other instructions that test a particular variable.).
| |
| | |
| == Creating simple programs ==
| |
| === Addition ===
| |
| The simplest FRACTRAN program is a single instruction such as
| |
| | |
| :<math>\left( \frac{3}{2} \right)</math>
| |
| | |
| This program can be represented as a (very simple) algorithm as follows:
| |
| | |
| :{| class="wikitable"
| |
| |-
| |
| ! FRACTRAN<br>Instruction
| |
| ! Condition
| |
| ! Action
| |
| |-
| |
| | align="center" | <math>\frac{3}{2}</math>
| |
| | v2 > 0
| |
| | Subtract 1 from v2<br>Add 1 to v3
| |
| |-
| |
| |
| |
| | v2 = 0
| |
| | Stop
| |
| |}
| |
| | |
| Given an initial input of the form <math>2^a 3^b</math>, this program will compute the sequence <math>2^{a-1} 3^{b+1}</math>, <math>2^{a-2} 3^{b+2}</math>, etc, until eventually, after <math>a</math> steps, no factors of 2 remain and the product with <math>\frac{3}{2}</math> no longer yields an integer; the machine then stops with a final output of <math> 3^{a + b} </math>. It therefore adds two integers together.
| |
| | |
| === Multiplication ===
| |
| We can create a "multiplier" by "looping" through the "adder". In order to do this we need to introduce [[State (computer science)|states]] into our algorithm. This algorithm will take a number <math>2^a 3^b</math> and produce <math>5^{ab}</math>:
| |
| | |
| :{| class="wikitable"
| |
| |-
| |
| ! Current State
| |
| ! Condition
| |
| ! Action
| |
| ! Next State
| |
| |-
| |
| | rowspan="4" align="center" | A
| |
| | v7 > 0
| |
| | Subtract 1 from v7<br>Add 1 to v3
| |
| | align="center" | A
| |
| |-
| |
| | v7 = 0 and<br>v2 > 0
| |
| | Subtract 1 from v2
| |
| | align="center" | B
| |
| |-
| |
| | v7 = 0 and<br>v2 = 0 and<br>v3 > 0
| |
| | Subtract 1 from v3
| |
| | align="center" | A
| |
| |-
| |
| | v7 = 0 and<br>v2 = 0 and<br>v3 = 0
| |
| | Stop
| |
| |
| |
| |-
| |
| | rowspan="2" align="center" | B
| |
| | v3 > 0
| |
| | Subtract 1 from v3<br>Add 1 to v5<br>Add 1 to v7
| |
| | align="center" | B
| |
| |-
| |
| | v3 = 0
| |
| | None
| |
| | align="center" | A
| |
| |}
| |
| | |
| State B is a loop that adds v3 to v5 and also moves v3 to v7, and state A is an outer control loop that repeats the loop in state B v2 times. State A also restores the value of v3 from v7 after the loop in state B has completed.
| |
| | |
| We can implement states using new variables as state indicators. The state indicators for state B will be v11 and v13. Note that we require two state control indicators for one loop; a primary flag (v11) and a secondary flag (v13). Because each indicator is consumed whenever it is tested, we need a secondary indicator to say "continue in the current state"; this secondary indicator is swapped back to the primary indicator in the next instruction, and the loop continues.
| |
| | |
| Adding FRACTRAN state indicators and instructions to the multiplication algorithm table, we have:
| |
| | |
| :{| class="wikitable"
| |
| |-
| |
| ! FRACTRAN<br>Instruction
| |
| ! Current State
| |
| ! State<br>Indicators
| |
| ! Condition
| |
| ! Action
| |
| ! Next State
| |
| |-
| |
| | align="center" | <math>\frac{3}{7}</math>
| |
| | rowspan="4" align="center" | A
| |
| | rowspan="4" | None
| |
| | v7 > 0
| |
| | Subtract 1 from v7<br>Add 1 to v3
| |
| | align="center" | A
| |
| |-
| |
| | align="center" | <math>\frac{11}{2}</math>
| |
| | v7 = 0 and<br>v2 > 0
| |
| | Subtract 1 from v2
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{1}{3}</math>
| |
| | v7 = 0 and<br>v2 = 0 and<br>v3 > 0
| |
| | Subtract 1 from v3
| |
| | align="center" | A
| |
| |-
| |
| |
| |
| | v7 = 0 and<br>v2 = 0 and<br>v3 = 0
| |
| | Stop
| |
| |
| |
| |-
| |
| | align="center" | <math>\frac{5 \cdot 7 \cdot 13}{3 \cdot 11}, \frac{11}{13}</math>
| |
| | rowspan="2" align="center" | B
| |
| | rowspan="2" | v11, v13
| |
| | v3 > 0
| |
| | Subtract 1 from v3<br>Add 1 to v5<br>Add 1 to v7
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{1}{11}</math>
| |
| | v3 = 0
| |
| | None
| |
| | align="center" | A
| |
| |}
| |
| | |
| When we write out the FRACTRAN instructions, we must put the state A instructions last, because state A has no state indicators - it is the default state if no state indicators are set. So as a FRACTRAN program, the multiplier becomes:
| |
| | |
| :<math>\left( \frac{455}{33}, \frac{11}{13}, \frac{1}{11}, \frac{3}{7}, \frac{11}{2}, \frac{1}{3} \right)</math>
| |
| | |
| With input 2<sup>''a''</sup>3<sup>''b''</sup> this program produces output 5<sup>''ab''</sup>. <ref group=note>A similar multiplier algorithm is described at the [http://www.esolangs.org/wiki/Fractran Esolang FRACTRAN page].</ref>
| |
| | |
| [[File:FRACTRANmult0.gif|thumb|544px|center|The above FRACTRAN program, computing 3 times 2 (so that its input is <math>2^3\times 3^2=72</math> and its output should be <math>5^6</math> because 3 times 2 happens to be 6, at least in a FRACTRAN world...]]
| |
| | |
| === Subtraction and division ===
| |
| In a similar way, we can create a FRACTRAN "subtracter", and repeated subtractions allow us to create a "quotient and remainder" algorithm as follows:
| |
| | |
| :{| class="wikitable"
| |
| |-
| |
| ! FRACTRAN<br>Instruction
| |
| ! Current State
| |
| ! State<br>Indicators
| |
| ! Condition
| |
| ! Action
| |
| ! Next State
| |
| |-
| |
| | align="center" | <math>\frac{7 \cdot 13}{2 \cdot 3 \cdot 11}, \frac{11}{13}</math>
| |
| | rowspan="3" align="center" | A
| |
| | rowspan="3" | v11, v13
| |
| | v2 > 0 and<br>v3 > 0
| |
| | Subtract 1 from v2<br>Subtract 1 from v3<br>Add 1 to v7
| |
| | align="center" | A
| |
| |-
| |
| | align="center" | <math>\frac{1}{3 \cdot 11}</math>
| |
| | v2 = 0 and<br>v3 > 0
| |
| | Subtract 1 from v3
| |
| | align="center" | X
| |
| |-
| |
| | align="center" | <math>\frac{5 \cdot 17}{11}</math>
| |
| | v3 = 0
| |
| | Add 1 to v5
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{3 \cdot 19}{7 \cdot 17}, \frac{17}{19}</math>
| |
| | rowspan="2" align="center" | B
| |
| | rowspan="2" | v17, v19
| |
| | v7 > 0
| |
| | Subtract 1 from v7<br>Add 1 to v3
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{11}{17}</math>
| |
| | v7 = 0
| |
| | None
| |
| | align="center" | A
| |
| |-
| |
| | align="center" | <math>\frac{1}{3}</math>
| |
| | rowspan="2" align="center" | X
| |
| | rowspan="2" |
| |
| | v3 > 0
| |
| | Subtract 1 from v3
| |
| | align="center" | X
| |
| |-
| |
| |
| |
| | v3 = 0
| |
| | Stop
| |
| |
| |
| |}
| |
| | |
| Writing out the FRACTRAN program, we have:
| |
| | |
| :<math>\left( \frac{91}{66}, \frac{11}{13}, \frac{1}{33}, \frac{85}{11}, \frac{57}{119}, \frac{17}{19}, \frac{11}{17}, \frac{1}{3} \right)</math>
| |
| | |
| and input 2<sup>''n''</sup>3<sup>''d''</sup>11 produces output 5<sup>''q''</sup>7<sup>''r''</sup> where ''n'' = ''qd'' + ''r'' and 0 ≤ ''r'' < ''d''.
| |
| | |
| == Conway's prime algorithm ==
| |
| | |
| Conway's prime generating algorithm above is essentially a quotient and remainder algorithm within two loops. Given input of the form <math>2^n 7^m</math> where 0 ≤ ''m'' < ''n'', the algorithm tries to divide ''n''+1 by each number from ''n'' down to 1, until it finds the largest number ''k'' that is a divisor of ''n''+1. It then returns 2<sup>''n''+1</sup> 7<sup>''k''-1</sup> and repeats. The only times that the sequence of state numbers generated by the algorithm produces a power of 2 is when ''k'' is 1 (so that the exponent of 7 is 0), which only occurs if the exponent of 2 is a prime. A step-by-step explanation of Conway's algorithm can be found in Havil(2007).
| |
| | |
| == Other examples == | |
| The following FRACTRAN program:
| |
| | |
| :<math>\left( \frac{3 \cdot 11}{2^2 \cdot 5} , \frac{5}{11}, \frac{13}{2 \cdot 5}, \frac{1}{5}, \frac{2}{3}, \frac{2 \cdot 5}{7}, \frac{7}{2} \right)</math>
| |
| | |
| calculates the [[Hamming weight]] H(''a'') of the binary expansion of ''a'' i.e. the number of 1s in the binary expansion of ''a''.<ref>John Baez, [http://golem.ph.utexas.edu/category/2006/10/puzzle_4.html Puzzle #4], The ''n''-Category Café</ref> Given input 2<sup>''a''</sup>, its output is 13<sup>H(''a'')</sup>. The program can be analysed as follows:
| |
| | |
| :{| class="wikitable"
| |
| |-
| |
| ! FRACTRAN<br>Instruction
| |
| ! Current State
| |
| ! State<br>Indicators
| |
| ! Condition
| |
| ! Action
| |
| ! Next State
| |
| |-
| |
| | align="center" | <math>\frac{3 \cdot 11}{2^2 \cdot 5}, \frac{5}{11}</math>
| |
| | rowspan="3" align="center" | A
| |
| | rowspan="3" | v5, v11
| |
| | v2 > 1
| |
| | Subtract 2 from v2<br>Add 1 to v3
| |
| | align="center" | A
| |
| |-
| |
| | align="center" | <math>\frac{13}{2 \cdot 5}</math>
| |
| | v2 = 1
| |
| | Subtract 1 from v2<br>Add 1 to v13
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{1}{5}</math>
| |
| | v2 = 0
| |
| | None
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{2}{3}</math>
| |
| | rowspan="4" align="center" | B
| |
| | rowspan="4" | None
| |
| | v3 > 0
| |
| | Subtract 1 from v3<br>Add 1 to v2
| |
| | align="center" | B
| |
| |-
| |
| | align="center" | <math>\frac{2 \cdot 5}{7}</math>
| |
| | v3 = 0 and<br>v7 > 0
| |
| | Subtract 1 from v7<br>Add 1 to v2
| |
| | align="center" | A
| |
| |-
| |
| | align="center" | <math>\frac{7}{2}</math>
| |
| | v3 = 0 and<br>v7 = 0 and<br>v2 > 0
| |
| | Subtract 1 from v2<br>add 1 to v7
| |
| | align="center" | B
| |
| |-
| |
| |
| |
| | v2 = 0 and<br>v3 = 0 and<br>v7 = 0
| |
| | Stop
| |
| |
| |
| |}
| |
| | |
| == Notes ==
| |
| {{reflist|group=note|}}
| |
| | |
| == References ==
| |
| {{Reflist}}
| |
| {{refbegin}}
| |
| *{{cite book
| |
| | last = Conway
| |
| | first = John H.
| |
| | coauthors = Guy, Richard K.
| |
| | title = The Book of Numbers
| |
| | publisher = Springer-Verlag New York, Inc.
| |
| | year = 1996
| |
| | isbn = 0-387-97993-X}}
| |
| *{{cite book
| |
| | last = Havil
| |
| | first = Julian
| |
| | title = Nonplussed!
| |
| | publisher = Princeton University Press
| |
| | year = 2007
| |
| | isbn = 0-691-12056-0}}
| |
| *{{cite book | title=The Ultimate Challenge: the 3x+1 problem | editor=Jeffrey C. Lagarias | last=Conway | first=John | authorlink=John Horton Conway | chapter=FRACTRAN: A simple universal programming language for arithmetic | pages=249–264 | publisher=American Mathematical Society | year=2010 | isbn=978-0-8218-4940-8 | zbl=1216.68068 }}
| |
| {{refend}}
| |
| | |
| == External links ==
| |
| *[http://scienceblogs.com/goodmath/2006/10/27/prime-number-pathology-fractra/ "Prime Number Pathology: Fractran"]
| |
| * {{MathWorld |urlname=FRACTRAN |title=FRACTRAN}}
| |
| *[http://brainwagon.org/?p=2207 ''Prime Number Pathology'']
| |
| *[http://www.esolangs.org/wiki/Fractran FRACTRAN] - (Esolang wiki)
| |
| *[http://www.dev.gd/20130121-fun-with-john-conways-fractran.html Ruby implementation and example programs]
| |
| | |
| [[Category:Models of computation]]
| |
| [[Category:Esoteric programming languages]]
| |
| [[Category:Recreational mathematics]]
| |