# Modeling helper functions, not actual instructions: @Runtime([stackSize, stackSize + 1], boolSize) def PtrIsNull(ptr, curStackPtr): return 1 if (ptr == 0 or ptr >= curStackPtr) else 0 @Runtime([stackSize, stackSize, stackSize + 1], boolSize) def OnePtrIsNull(ptr1, ptr2, curStackPtr): if ptr1 == 0 or ptr1 >= curStackPtr or ptr2 == 0 or ptr2 >= curStackPtr: return 1 else: return 0 # Prefix instructions and arguments prefixInstructions = Param(numInstructions)[prefixLength] for i in range(0, prefixLength): # We allow access to the inputs and all registers written so far prefixInstructionsArg1[i] = Param(inputNum + i) prefixInstructionsArg2[i] = Param(inputNum + i) prefixInstructionsCondition[i] = Param(inputNum + i) prefixRegisterNum = inputNum + prefixLength # Choosing the combinator, its instructions and their arguments: combinator = Param(numCombinators) combinatorStartAcc = Param(prefixRegisterNum) combinatorInputList1 = Param(prefixRegisterNum) combinatorInputList2 = Param(prefixRegisterNum) lambdaInstructions = Param(numInstructions)[lambdaLength] for i in range(0, lambdaLength):
def Max(a, b): return b if a <= b else a @Runtime([numRegisters, numRegisters], boolSize) def EqualityTestReg(a, b): return 1 if a == b else 0 @Runtime([maxInt], boolSize) def GreaterThanZero(a): return 1 if a > 0 else 0 # Program parameters instructions = Param(numInstructions)[numBlocks] thenBlock = Param(numBlocks)[numBlocks] elseBlock = Param(numBlocks)[numBlocks] arg1Reg = Param(numRegisters)[numBlocks] arg2Reg = Param(numRegisters)[numBlocks] outReg = Param(numRegisters)[numBlocks] condReg = Param(numRegisters)[numBlocks] # State of registers, memory and program pointer during execution: isHalted = Var(boolSize)[numTimesteps + 1] blockPointer = Var(numBlocks)[numTimesteps + 1] registers = Var(maxInt)[numTimesteps + 1, numRegisters] memory = Var(maxInt)[numTimesteps + 1, maxInt] # Temporary values: tmpOutput = Var(maxInt)[numTimesteps]
# Runtime state stackCarValue = Var(maxScalar)[numTimesteps + 1, mutableStackSize] stackCdrValue = Var(maxScalar)[numTimesteps + 1, mutableStackSize] stackPtr = Var(mutableStackSize)[numTimesteps + 1] registers = Var(maxScalar)[numTimesteps + 1, numRegisters] instrPtr = Var(programLen)[numTimesteps + 1] returnValue = Var(maxScalar)[numTimesteps + 1] isHalted = Var(2)[numTimesteps + 1] # Program # Register Instructions: cons, car, cdr, zero/nil, add, inc, eq, gt, and, dec, or # Branch Instructions: jz, jnz, halt instructions = Param(numInstructions)[programLen] arg1s = Param(numRegisters)[programLen] arg2s = Param(numRegisters)[programLen] outs = Param(numRegisters)[programLen] branchAddr = Param(programLen)[programLen] # Temporary values tmpArg1Val = Var(maxScalar)[numTimesteps] tmpArg2Val = Var(maxScalar)[numTimesteps] tmpOutVal = Var(maxScalar)[numTimesteps] tmpArg1DerefCarValue = Var(maxScalar)[numTimesteps] tmpArg1DerefCdrValue = Var(maxScalar)[numTimesteps] tmpBranchCond = Var(2)[numTimesteps] tmpDoPushStack = Var(2)[numTimesteps] tmpDoWriteStack = Var(2)[numTimesteps, maxScalar]
@Runtime([stackSize, stackSize, stackSize + 1], boolSize) def OnePtrIsNull(ptr1, ptr2, curStackPtr): if ptr1 == 0 or ptr1 >= curStackPtr or ptr2 == 0 or ptr2 >= curStackPtr: return 1 else: return 0 @Runtime([maxScalar], boolSize) def ScalarAsBool(x): return 1 if x > 0 else 0 # Prefix instructions and arguments prefixInstructions = Param(numInstructions)[prefixLength] prefixInstructionsArg1 = Param(registerNum)[prefixLength] prefixInstructionsArg2 = Param(registerNum)[prefixLength] prefixInstructionsCondition = Param(registerNum)[prefixLength] prefixInstructionsOut = Param(registerNum)[prefixLength] # Choosing the loop, its instructions and their arguments: loop = Param(numLoops) loopInputList1 = Param(registerNum) loopInputList2 = Param(registerNum) loopBodyInstructions = Param(numInstructions)[loopBodyLength] loopBodyInstructionsOut = Param(registerNum)[loopBodyLength] loopBodyInstructionsArg1 = Param(loopRegisterNum)[loopBodyLength] loopBodyInstructionsArg2 = Param(loopRegisterNum)[loopBodyLength] loopBodyInstructionsCondition = Param(registerNum)[loopBodyLength]
@Runtime([stackSize, stackSize, stackSize + 1], boolSize) def OnePtrIsNull(ptr1, ptr2, curStackPtr): if ptr1 == 0 or ptr1 >= curStackPtr or ptr2 == 0 or ptr2 >= curStackPtr: return 1 else: return 0 @Runtime([maxScalar], boolSize) def ScalarAsBool(x): return 1 if x > 0 else 0 # Prefix instructions and arguments prefixInstructions = Param(numInstructions)[prefixLength] prefixInstructionsArg1 = Param(registerNum)[prefixLength] prefixInstructionsArg2 = Param(registerNum)[prefixLength] prefixInstructionsCondition = Param(registerNum)[prefixLength] prefixInstructionsOut = Param(registerNum)[prefixLength] # Choosing the combinator, its instructions and their arguments: combinator = Param(numCombinators) combinatorStartAcc = Param(registerNum) combinatorInputList1 = Param(registerNum) combinatorInputList2 = Param(registerNum) combinatorOut = Param(registerNum) lambdaInstructions = Param(numInstructions)[lambdaLength] lambdaInstructionsOut = Param(registerNum)[lambdaLength] lambdaInstructionsArg1 = Param(lambdaRegisterNum)[lambdaLength]
@Runtime([maxInt, maxInt], maxInt) def Sub(a, b): return (a - b) % maxInt @Runtime([maxInt], maxInt) def Dec(a): return (a - 1) % maxInt @Runtime([maxInt, maxInt], maxInt) def LessThan(a, b): return 1 if a < b else 0 @Runtime([maxInt, maxInt], boolSize) def EqualityTest(a, b): return 1 if a == b else 0 @Runtime([numRegisters, numRegisters], boolSize) def EqualityTestReg(a, b): return 1 if a == b else 0 @Runtime([maxInt], boolSize) def GreaterThanZero(a): return 1 if a > 0 else 0 # Program parameters numBlocksWithHalt = numBlocks + 1 instructions = Param(numInstructions)[numBlocksWithHalt] thenBlock = Param(numBlocksWithHalt)[numBlocksWithHalt] elseBlock = Param(numBlocksWithHalt)[numBlocksWithHalt] arg1Reg = Param(numRegisters)[numBlocksWithHalt] arg2Reg = Param(numRegisters)[numBlocksWithHalt] outReg = Param(numRegisters)[numBlocksWithHalt] condReg = Param(numRegisters)[numBlocksWithHalt] # State of registers, memory and program pointer during execution: blockPointer = Var(numBlocksWithHalt)[numTimesteps + 1] registers = Var(maxInt)[numTimesteps + 1, numRegisters] memory = Var(maxInt)[numTimesteps + 1, maxInt] # Temporary values: tmpOutput = Var(maxInt)[numTimesteps] tmpArg1Val = Var(maxInt)[numTimesteps]
from dummy import Hyper, Param, Var, Runtime, Input, Output, Inline numTapeSymbols = Hyper() numHeadStates = Hyper() tapeLength = Hyper() numTimesteps = Hyper() boolSize = 2 numDirections = 3 # Inputs and Output initial_tape = Input(numTapeSymbols)[tapeLength] final_is_halted = Output(2) final_tape = Output(numTapeSymbols)[tapeLength] # Turing Machine parameters write = Param(numTapeSymbols)[numHeadStates, numTapeSymbols] dir = Param(numDirections)[numHeadStates, numTapeSymbols] newState = Param(numHeadStates)[numHeadStates, numTapeSymbols] @Runtime([tapeLength, numDirections], tapeLength) def move(pos, dir): if dir == 0: return pos elif dir == 1: return (pos + 1) % tapeLength elif dir == 2: return (pos - 1) % tapeLength @Runtime([tapeLength, tapeLength], boolSize)
@Runtime([2], 2) def NOT(a): return int(not a) @Runtime([2], 2) def NOP(a): return a @Runtime([numWires, numWires], 2) def equalityTest(a, b): return 1 if a == b else 0 gate = Param(numGateTypes)[numGates] in1 = Param(numWires)[numGates] in2 = Param(numWires)[numGates] out = Param(numWires)[numGates] initial_wires = Input(2)[numWires] final_wires = Output(2)[numOutputs] wires = Var(2)[numGates + 1, numWires] tmpOutput = Var(2)[numGates] tmpDoWrite = Var(2)[numGates, numWires] tmpArg1 = Var(2)[numGates] tmpArg2 = Var(2)[numGates] for w in range(numWires): wires[0, w].set_to(initial_wires[w])