Created
December 13, 2025 15:33
-
-
Save perfaram/0946decf624f6ed006b8a9034f5e6159 to your computer and use it in GitHub Desktop.
a turing machine in clickhouse?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| WITH RECURSIVE turing AS ( | |
| SELECT | |
| [ | |
| ('RSET', 3, 42), -- Register SET (register#, int val): set register #LHS to value in RHS | |
| ('PASS', 0, 0), -- is no-op | |
| ('IADD', 2, 2), -- Integer ADD (register#, int val): add the value in RHS to the register #LHS | |
| ('RGTE', 2, 3), -- Register Greater Than or Equal (register#, register#): sets the comparison register (register #1) to truthy if register #LHS is >= register #RHS | |
| ('CJMP', 7, 0), -- Conditional JuMP: jump to the program index #LHS if the comparison register (register #1) is truthy (> 0) | |
| ('UJMP', 2, 0), -- Unconditional JUMP: jump to the program index #LHS (here never reached) | |
| ('STOP', 0, 0) -- STOP: stop the VM (terminates the request) | |
| ] AS program, | |
| 0::UInt64 AS pcounter, | |
| [0::UInt64, 0, 0, 0] AS registers, | |
| 0::UInt64 AS steps | |
| UNION ALL | |
| SELECT | |
| program, | |
| multiIf( | |
| program[pcounter].1 == 'UJMP', program[pcounter].2, | |
| program[pcounter].1 == 'CJMP', if(registers[1] > 0, program[pcounter].2, pcounter+1), | |
| pcounter+1 | |
| ) AS pcounter, | |
| multiIf( | |
| program[pcounter].1 == 'RSET', arrayMap((i, r) -> if(i == program[pcounter].2, program[pcounter].3, r), arrayEnumerate(registers), registers), | |
| program[pcounter].1 == 'IADD', arrayMap((i, r) -> if(i == program[pcounter].2, r+program[pcounter].3, r), arrayEnumerate(registers), registers), | |
| program[pcounter].1 == 'RMOV', arrayMap((i, r) -> if(i == program[pcounter].2, registers[program[pcounter].3], r), arrayEnumerate(registers), registers), | |
| program[pcounter].1 == 'RGTE', arrayMap((i, r) -> if(i == 1 /*bool-ish register for conditional instructions*/, registers[program[pcounter].2] >= registers[program[pcounter].3], r), arrayEnumerate(registers), registers), | |
| registers | |
| ) AS registers, | |
| steps+1 AS steps | |
| FROM turing | |
| WHERE program[pcounter].1 <> 'STOP' AND steps < 1000 | |
| ) | |
| SELECT | |
| program[pcounter] AS instruction, | |
| registers AS registers_after, | |
| pcounter AS program_counter | |
| FROM turing; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment