FRACTRAN

FRACTRAN is a Turing-completeesoteric programming language invented by the mathematician John Conway. A FRACTRAN program is an ordered list of positive fractions together with an initial positive integer input n. The program is run by updating the integer n as follows:

  1. for the first fraction f in the list for which nf is an integer, replace n by nf
  2. repeat this rule until no fraction in the list produces an integer when multiplied by n, then halt.

Conway 1987 gives the following FRACTRAN program, called PRIMEGAME, which finds successive prime numbers:

(1791,7885,1951,2338,2933,7729,9523,7719,117,1113,1311,152,17,551){\displaystyle \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}{2}},{\frac {1}{7}},{\frac {55}{1}}\right)}

Starting with n=2, this FRACTRAN program generates the following sequence of integers:

  • 2, 15, 825, 725, 1925, 2275, 425, 390, 330, 290, 770, ... (sequence A007542 in the OEIS), i.e. the sequence of PRIMEGAME numbers

After 2, this sequence contains the following powers of 2:

22=4,23=8,25=32,27=128,211=2048,213=8192,217=131072,219=524288,{\displaystyle 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 }(sequence A034785 in the OEIS)

The exponent part of these powers of two are primes, 2, 3, 5, etc.

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{\displaystyle n}.

Using Gödel numbering, a positive integer n{\displaystyle n} can encode an arbitrary number of arbitrarily large positive integer variables.[note 1] The value of each variable is encoded as the exponent of a prime number in the prime factorization of the integer. For example, the integer

60=22×31×51{\displaystyle 60=2^{2}\times 3^{1}\times 5^{1}}

represents a register state in which one variable (which we will call v2{\displaystyle v_{2}}) holds the value 2 and two other variables (v3{\displaystyle v_{3}} and v5{\displaystyle v_{5}}) 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:

f1=2120=3×722×51{\displaystyle f_{1}={\frac {21}{20}}={\frac {3\times 7}{2^{2}\times 5^{1}}}}

tests v2{\displaystyle v_{2}} and v5{\displaystyle v_{5}}. If v22{\displaystyle v_{2}\geq 2} and v51{\displaystyle v_{5}\geq 1}, then it subtracts 2 from v2{\displaystyle v_{2}} and 1 from v5{\displaystyle v_{5}} and adds 1 to v3{\displaystyle v_{3}} and 1 to v7{\displaystyle v_{7}}. For example:

60f1=22×31×513×722×51=32×71{\displaystyle 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}}

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.
  • لا يمكن إنقاص قيمة المتغير نفسه وزيادتها في نفس التعليمة (وإلا لما كان الكسر الذي يمثل تلك التعليمة في أبسط صورة ). لذلك، تستهلك كل تعليمة في لغة FRACTRAN متغيرات أثناء اختبارها.
  • لا يمكن لتعليمات FRACTRAN أن تختبر بشكل مباشر ما إذا كان المتغير يساوي 0 (ومع ذلك، يمكن تنفيذ اختبار غير مباشر عن طريق إنشاء تعليمات افتراضية يتم وضعها بعد التعليمات الأخرى التي تختبر متغيرًا معينًا).

إنشاء برامج بسيطة

إضافة

أبسط برنامج في لغة FRACTRAN هو تعليمة واحدة مثل:

(32){\displaystyle \left({\frac {3}{2}}\right)}

يمكن تمثيل هذا البرنامج كخوارزمية (بسيطة للغاية) على النحو التالي:

تعليمات FRACTRANحالةفعل
32{\displaystyle {\frac {3}{2}}}v2{\displaystyle v_{2}}> 0اطرح 1 منv2{\displaystyle v_{2}} أضف 1 إلىv3{\displaystyle v_{3}}
v2{\displaystyle v_{2}}= 0قف

بافتراض وجود مدخلات أولية على الشكل التالي2أ3ب{\displaystyle 2^{a}3^{b}}سيقوم هذا البرنامج بحساب التسلسل2أ-13ب+1{\displaystyle 2^{a-1}3^{b+1}}،2أ-23ب+2{\displaystyle 2^{a-2}3^{b+2}}إلخ، حتى النهاية، بعدأ{\displaystyle a}بعد الخطوات، لم يتبق أي عامل من عوامل العدد 2، ويكون الناتج مع32{\displaystyle {\frac {3}{2}}}لم يعد البرنامج يُنتج عددًا صحيحًا؛ ثم يتوقف البرنامج مع الناتج النهائي التالي:3أ+ب{\displaystyle 3^{a+b}}وبالتالي، فهو يجمع عددين صحيحين معاً.

الضرب

يمكننا إنشاء "مضاعف" من خلال "التكرار" عبر "الجامع". وللقيام بذلك، نحتاج إلى إدخال حالات في خوارزميتنا. ستأخذ هذه الخوارزمية عددًا2أ3ب{\displaystyle 2^{a}3^{b}}وإنتاج5أب{\displaystyle 5^{ab}}:

الوضع الحاليحالةفعلالولاية التالية
أv7{\displaystyle v_{7}}> 0اطرح 1 منv7{\displaystyle v_{7}} أضف 1 إلىv3{\displaystyle v_{3}}أ
v7{\displaystyle v_{7}}= 0 وv2{\displaystyle v_{2}}> 0اطرح 1 منv2{\displaystyle v_{2}}ب
v7{\displaystyle v_{7}}= 0 وv2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}> 0اطرح 1 منv3{\displaystyle v_{3}}أ
v7{\displaystyle v_{7}}= 0 وv2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}= 0قف
بv3{\displaystyle v_{3}}> 0اطرح 1 من v3{\displaystyle v_{3}} أضف 1 إلىv5{\displaystyle v_{5}} أضف 1 إلىv7{\displaystyle v_{7}}ب
v3{\displaystyle v_{3}}= 0لا أحدأ

الحالة B عبارة عن حلقة تضيفv3{\displaystyle v_{3}}لv5{\displaystyle v_{5}}ويتحرك أيضًاv3{\displaystyle v_{3}}لv7{\displaystyle v_{7}}والحالة A هي حلقة تحكم خارجية تكرر الحلقة في الحالة Bv2{\displaystyle v_{2}}مرات. كما تعيد الحالة أ قيمةv3{\displaystyle v_{3}}منv7{\displaystyle v_{7}}بعد اكتمال الحلقة في الحالة B.

يمكننا تطبيق الحالات باستخدام متغيرات جديدة كمؤشرات للحالة. ستكون مؤشرات الحالة B هيv11{\displaystyle v_{11}}وv13{\displaystyle v_{13}}لاحظ أننا نحتاج إلى مؤشرين للتحكم في الحالة لحلقة واحدة؛ علامة أساسية (v11{\displaystyle v_{11}}) وعلم ثانوي (v13{\displaystyle v_{13}}). نظرًا لأن كل مؤشر يتم استهلاكه كلما تم اختباره، فإننا نحتاج إلى مؤشر ثانوي ليقول "استمر في الحالة الحالية"؛ يتم تبديل هذا المؤشر الثانوي مرة أخرى إلى المؤشر الأساسي في التعليمات التالية، وتستمر الحلقة.

بإضافة مؤشرات حالة FRACTRAN وتعليماتها إلى جدول خوارزمية الضرب ، نحصل على:

تعليمات FRACTRANالوضع الحاليمؤشرات الدولةحالةفعلالولاية التالية
37{\displaystyle {\frac {3}{7}}}ألا أحدv7{\displaystyle v_{7}}> 0اطرح 1 منv7{\displaystyle v_{7}}أضف 1 إلىv3{\displaystyle v_{3}}أ
112{\displaystyle {\frac {11}{2}}}v7{\displaystyle v_{7}}= 0 وv2{\displaystyle v_{2}}> 0اطرح 1 منv2{\displaystyle v_{2}}ب
13{\displaystyle {\frac {1}{3}}}v7{\displaystyle v_{7}}= 0 و v2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}> 0اطرح 1 منv3{\displaystyle v_{3}}أ
v7{\displaystyle v_{7}}= 0 و v2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}= 0قف
5713311،1113{\displaystyle {\frac {5\cdot 7\cdot 13}{3\cdot 11}},{\frac {11}{13}}}بv11{\displaystyle v_{11}}،v13{\displaystyle v_{13}}v3{\displaystyle v_{3}}> 0اطرح 1 منv3{\displaystyle v_{3}} أضف 1 إلىv5{\displaystyle v_{5}} أضف 1 إلىv7{\displaystyle v_{7}}ب
111{\displaystyle {\frac {1}{11}}}v3{\displaystyle v_{3}}= 0لا أحدأ

عند كتابة تعليمات FRACTRAN، يجب وضع تعليمات الحالة A في النهاية، لأن الحالة A لا تحتوي على مؤشرات حالة - فهي الحالة الافتراضية في حال عدم تعيين أي مؤشرات حالة. لذا، يصبح المضاعف في برنامج FRACTRAN كما يلي:

(45533،1113،111،37،112،13){\displaystyle \left({\frac {455}{33}},{\frac {11}{13}},{\frac {1}{11}},{\frac {3}{7}},{\frac {11}{2}},{\frac {1}{3}}\right)}

باستخدام المدخلات 2 أ 3 ب، ينتج هذا البرنامج المخرجات 5 أب . [ ملاحظة 2 ]

يقوم برنامج FRACTRAN المذكور أعلاه بحساب 3 مضروبة في 2 (بحيث يكون مُدخله هو23×32=72{\displaystyle 2^{3}\times 3^{2}=72}وينبغي أن يكون ناتجها56{\displaystyle 5^{6}}لأن 3 × 2 = 6.

الطرح والقسمة

وبالمثل، يمكننا إنشاء "طارح" في FRACTRAN، وتتيح لنا عمليات الطرح المتكررة إنشاء خوارزمية "القسمة والباقي" على النحو التالي:

تعليمات FRACTRANالوضع الحاليمؤشرات الدولةحالةفعلالولاية التالية
7132311،1113{\displaystyle {\frac {7\cdot 13}{2\cdot 3\cdot 11}},{\frac {11}{13}}}أv11{\displaystyle v_{11}}،v13{\displaystyle v_{13}}v2>0{\displaystyle v_{2}>0}و v3>0{\displaystyle v_{3}>0}اطرح 1 منv2{\displaystyle v_{2}} اطرح 1 منv3{\displaystyle v_{3}}أضف 1 إلىv7{\displaystyle v_{7}}أ
1311{\displaystyle {\frac {1}{3\cdot 11}}}v2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}> 0اطرح 1 منv3{\displaystyle v_{3}}X
51711{\displaystyle {\frac {5\cdot 17}{11}}}v3{\displaystyle v_{3}}= 0أضف 1 إلىv5{\displaystyle v_{5}}ب
319717،1719{\displaystyle {\frac {3\cdot 19}{7\cdot 17}},{\frac {17}{19}}}بv17{\displaystyle v_{17}}،v19{\displaystyle v_{19}}v7{\displaystyle v_{7}}> 0اطرح 1 منv7{\displaystyle v_{7}} أضف 1 إلىv3{\displaystyle v_{3}}ب
1117{\displaystyle {\frac {11}{17}}}v7{\displaystyle v_{7}}= 0لا أحدأ
13{\displaystyle {\frac {1}{3}}}Xv3{\displaystyle v_{3}}> 0اطرح 1 منv3{\displaystyle v_{3}}X
v3{\displaystyle v_{3}}= 0قف

عند كتابة برنامج FRACTRAN، نحصل على:

(9166،1113،133،8511،57119،1719،1117،13){\displaystyle \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)}

والمدخل 2 n 3 d 11 ينتج عنه المخرج 5 q 7 r حيث n = qd + r و 0 ≤ r < d .

خوارزمية كونواي الرئيسية

خوارزمية توليد الأعداد الأولية لكونواي المذكورة أعلاه هي في الأساس خوارزمية قسمة وباقي ضمن حلقتين. مع الأخذ في الاعتبار المدخلات بالشكل التالي:2ن7م{\displaystyle 2^{n}7^{m}}حيث 0 ≤ m < n ، تحاول الخوارزمية قسمة n + 1 على كل عدد من n إلى 1، حتى تجد أكبر عدد k يقسم n + 1. ثم تُرجع 2n + 1 7k - 1 وتُكرر العملية . لا ينتج عن سلسلة أعداد الحالات التي تُولدها الخوارزمية قوة للعدد 2 إلا عندما يكون k يساوي 1 (بحيث يكون أس 7 يساوي 0)، وهذا لا يحدث إلا إذا كان أس 2 عددًا أوليًا. يمكن الاطلاع على شرح مُفصّل لخوارزمية كونواي في هافيل (2007).

بالنسبة لهذا البرنامج، يتطلب الوصول إلى الأعداد الأولية 2، 3، 5، 7... على التوالي 19، 69، 281، 710،... خطوات (التسلسل A007547 في OEIS ) .

يوجد أيضًا شكل مختلف من برنامج كونواي، [ 1 ] والذي يختلف عن النسخة المذكورة أعلاه بكسرين: (1791،7885،1951،2338،2933،7729،9523،7719،117،1113،1311،1514،152،551){\displaystyle \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)}

هذا المتغير أسرع قليلاً: الوصول إلى 2، 3، 5، 7... يستغرق 19، 69، 280، 707... خطوة (التسلسل A007546 في OEIS ) . تستغرق دورة واحدة من هذا البرنامج، للتحقق من كون عدد معين N أوليًا، عدد الخطوات التالي: شمال-1+(6شمال+2)(شمال-ب)+2د=بشمال-1شمالد،{\displaystyle N-1+(6N+2)(N-b)+2\sum \limits _{d=b}^{N-1}\left\lfloor {\frac {N}{d}}\right\rfloor ,} أينب<شمال{\displaystyle b<N}هو أكبر قاسم صحيح للعدد N وx{\displaystyle \lfloor x\rfloor }هي دالة الجزء الصحيح . [ 2 ]

في عام 1999، قدم ديفين كيلمنستر برنامجًا أقصر يتكون من عشر تعليمات: [ 3 ](73،9998،1349،3935،3691،10143،4913،711،12،911).{\displaystyle \left({\frac {7}{3}},{\frac {99}{98}},{\frac {13}{49}},{\frac {39}{35}},{\frac {36}{91}},{\frac {10}{143}},{\frac {49}{13}},{\frac {7}{11}},{\frac {1}{2}},{\frac {91}{1}}\right).} بالنسبة للمدخل الأولي n = 10، يتم توليد الأعداد الأولية المتتالية بواسطة قوى متتالية للعدد 10.

أمثلة أخرى

برنامج FRACTRAN التالي:

(311225،511،1325،15،23،257،72){\displaystyle \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)}

يحسب البرنامج وزن هامينغ H( a ) للعدد الثنائي أي عدد الآحاد في التمثيل الثنائي للعدد a . [ 4 ] عند إدخال 2a ، يكون الناتج 13H ( a ) . يمكن تحليل البرنامج كما يلي:

تعليمات FRACTRANالوضع الحاليمؤشرات الدولةحالةفعلالولاية التالية
311225،511{\displaystyle {\frac {3\cdot 11}{2^{2}\cdot 5}},{\frac {5}{11}}}أv5{\displaystyle v_{5}}،v11{\displaystyle v_{11}}v2{\displaystyle v_{2}}> 1اطرح 2 منv2{\displaystyle v_{2}} أضف 1 إلىv3{\displaystyle v_{3}}أ
1325{\displaystyle {\frac {13}{2\cdot 5}}}v2{\displaystyle v_{2}}= 1اطرح 1 منv2{\displaystyle v_{2}} أضف 1 إلىv13{\displaystyle v_{13}}ب
15{\displaystyle {\frac {1}{5}}}v2{\displaystyle v_{2}}= 0لا أحدب
23{\displaystyle {\frac {2}{3}}}بلا أحدv3{\displaystyle v_{3}}> 0اطرح 1 من v3{\displaystyle v_{3}} أضف 1 إلىv2{\displaystyle v_{2}}ب
257{\displaystyle {\frac {2\cdot 5}{7}}}v3{\displaystyle v_{3}}= 0 و v7{\displaystyle v_{7}}> 0اطرح 1 منv7{\displaystyle v_{7}} أضف 1 إلىv2{\displaystyle v_{2}}أ
72{\displaystyle {\frac {7}{2}}}v3{\displaystyle v_{3}}= 0 و v7{\displaystyle v_{7}}= 0 و v2{\displaystyle v_{2}}> 0اطرح 1 منv2{\displaystyle v_{2}} أضف 1 إلىv7{\displaystyle v_{7}}ب
v2{\displaystyle v_{2}}= 0 و v3{\displaystyle v_{3}}= 0 و v7{\displaystyle v_{7}}= 0قف

ملحوظات

  1. لا يمكن استخدام ترقيم غودل مباشرةً للأعداد الصحيحة السالبة، أو الأعداد العشرية، أو النصوص، على الرغم من إمكانية اعتماد اصطلاحات لتمثيل هذه الأنواع من البيانات بشكل غير مباشر. تشمل الإضافات المقترحة لـ FRACTRAN كلاً من FRACTRAN++ و Bag .
  2. تم وصف خوارزمية مضاعف مماثلة في صفحة Esolang FRACTRAN .

انظر أيضاً

مراجع

  1. جاي 1983 ، ص 26 ؛ كونواي وجاي 1996 ، ص 147  
  2. جاي 1983 ، ص 33 
  3. هافيل 2007 ، ص 176 
  4. جون بايز، اللغز رقم 4 ،مقهى الفئة ن