universal_turing_machine.sf 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Universal_Turing_machine#Sidef
  4. #
  5. func run_utm(state="", blank="", rules=[], tape=[blank], halt="", pos=0) {
  6. if (pos < 0) {
  7. pos += tape.len;
  8. }
  9. if (pos !~ tape.range) {
  10. die "Bad initial position";
  11. }
  12. loop {
  13. print "#{state}\t";
  14. tape.range.each { |i|
  15. var v = tape[i];
  16. print (i == pos ? "[#{v}]" : " #{v} ");
  17. };
  18. print "\n";
  19. if (state == halt) {
  20. break;
  21. }
  22. for s0, v0, v1, dir, s1 in rules {
  23. if ((s0 != state) || (tape[pos] != v0)) {
  24. next;
  25. }
  26. tape[pos] = v1;
  27. given(dir) {
  28. when ('left') {
  29. if (pos == 0) { tape.unshift(blank) }
  30. else { --pos };
  31. }
  32. when ('right') {
  33. if (++pos >= tape.len) {
  34. tape.append(blank)
  35. }
  36. }
  37. }
  38. state = s1;
  39. goto :NEXT;
  40. }
  41. die 'No matching rules';
  42. @:NEXT;
  43. }
  44. }
  45. print "incr machine\n";
  46. run_utm(
  47. halt: 'qf',
  48. state: 'q0',
  49. tape: %w(1 1 1),
  50. blank: 'B',
  51. rules: [
  52. %w(q0 1 1 right q0),
  53. %w(q0 B 1 stay qf),
  54. ]);
  55. say "\nbusy beaver";
  56. run_utm(
  57. halt: 'halt',
  58. state: 'a',
  59. blank: '0',
  60. rules: [
  61. %w(a 0 1 right b),
  62. %w(a 1 1 left c),
  63. %w(b 0 1 left a),
  64. %w(b 1 1 right b),
  65. %w(c 0 1 left b),
  66. %w(c 1 1 stay halt),
  67. ]);
  68. say "\nsorting test";
  69. run_utm(
  70. halt: 'STOP',
  71. state: 'A',
  72. blank: '0',
  73. tape: %w(2 2 2 1 2 2 1 2 1 2 1 2 1 2),
  74. rules: [
  75. %w(A 1 1 right A),
  76. %w(A 2 3 right B),
  77. %w(A 0 0 left E),
  78. %w(B 1 1 right B),
  79. %w(B 2 2 right B),
  80. %w(B 0 0 left C),
  81. %w(C 1 2 left D),
  82. %w(C 2 2 left C),
  83. %w(C 3 2 left E),
  84. %w(D 1 1 left D),
  85. %w(D 2 2 left D),
  86. %w(D 3 1 right A),
  87. %w(E 1 1 left E),
  88. %w(E 0 0 right STOP),
  89. ]);