User:PkmnQ/Hypercomputable implementations
Jump to navigation
Jump to search
These are implementations for hypercomputable esolangs in "Banana pseudoPython". I hope to rewrite these in Banana Scheme at some later point, but I'll have to learn Scheme first.
Brainhype, Hyperon, and Loop preventing brainfuck
These implementations use pseudoPython-omega.
import collections, sys def find_degree(code, open, close): max_nesting, nesting = 0, 0 for instruction in code: if instruction in open: nesting += 1 if instruction in close: nesting -= 1 max_nesting = max(max_nesting, nesting) return max_nesting def find_matches(code, open, close): matches, stack = {}, [] for i, instruction in code: if instruction in open: stack.append(i) if instruction in close: match = stack.pop() matches[i], matches[match] = match, i return matches # mostly adapted from [[brainfuck Python interpreter]] def brainhype(code, tape=None, p=0): matches = find_matches(code, "[{", "]}") if tape is None: tape = collections.defaultdict(int) cp=0 while cp<len(code): if code[cp]=='+': tape[p]=(tape[p]+1)%256 if code[cp]=='-': tape[p]=(tape[p]-1)%256 if code[cp]==',': c=sys.stdin.read(1) tape[p]=(ord(c) if c else 0)%256 if code[cp]=='.': print(chr(tape[p]),end=) if code[cp]=='<': p-=1 if code[cp]=='>': p+=1 if code[cp]=='[': if not tape[p]: cp=matches[cp] if code[cp]==']': if tape[p]: cp=matches[cp] if code[cp]=='{': subprogram = code[cp+1:matches[cp]] if halts(find_degree(subprogram, "{", "}"), lambda: brainhype(subprogram, tape, p)): tape[p] = 0 cp = matches[cp] cp+=1 def hyperon(code, tape=None, p=0): matches = find_matches(code, "[{", "]}") if tape is None: tape = collections.defaultdict(int) cp=0 while cp<len(code): if code[cp]=='+': tape[p]=(tape[p]+1)%256 if code[cp]=='-': tape[p]=(tape[p]-1)%256 if code[cp]==',': c=sys.stdin.read(1) tape[p]=(ord(c) if c else 0)%256 if code[cp]=='.': print(chr(tape[p]),end=) if code[cp]=='<': p-=1 if code[cp]=='>': p+=1 if code[cp]=='[': if not tape[p]: cp=matches[cp] if code[cp]==']': if tape[p]: cp=matches[cp] if code[cp]=='{': subprogram = code[cp+1:matches[cp]] if halts(find_degree(subprogram, "{", "}"), lambda: hyperon(subprogram, tape, p)): tape[p] += 1 cp = matches[cp] cp+=1 def loop_preventing_brainfuck(code, tape=None, p=0): matches = find_matches(code, "([", "|") if tape is None: tape = collections.defaultdict(int) cp=0 while cp<len(code): if code[cp]=='+': tape[p]=tape[p]+1 if code[cp]=='-': tape[p]=tape[p]-1 if code[cp]==',': c=sys.stdin.read(1) tape[p]=ord(c) if c else 0 if code[cp]=='.': print(chr(tape[p]),end=) if code[cp]=='<': p-=1 if code[cp]=='>': p+=1 if code[cp]=='[': if not tape[p]: cp=matches[cp] if code[cp]=='|': if tape[p]: cp=matches[cp] if code[cp]=='(': subprogram = code[cp+1:matches[cp]] if halts(find_degree(subprogram, "([", "|"), lambda: loop_preventing_brainfuck(subprogram, tape, p)): loop_preventing_brainfuck(subprogram, tape, p) cp = matches[cp] cp+=1
Beeping cyclic tag
This implementation uses pseudoPython-2. If looping infinitely instead of erroring out is acceptable, pseudoPython-1 can be used instead.
import itertools q1, q2, q = [], [], False def run_until_beep(commands): global q1, q2, q while True: current_queue = q2 if q else q1 if next(commands): if q1[0] == True: current_queue.append(next(commands)) if q: return elif next(commands): q = not q else: current_queue.pop(0) if q: return def almost_beeping_cyclic_tag(commands): global q1, q2, q while halts(0, lambda: run_until_beep(commands)): run_until_beep(commands) return q2 def beeping_cyclic_tag(code, inputs=None): global q1, q2, q if inputs: q1 = inputs else: q1 = [True] commands = itertools.cycle(code) if halts(1, lambda: almost_beeping_cyclic_tag(commands)): return almost_beeping_cyclic_tag(commands) raise Exception("Q2 is updated infinitely")
Try to Take
This implementation uses pseudoPython-omega. The program is represented as follows:
- is represented as
None
. - Variables are represented by numbers (each variable must be represented by a distinct number).
- is represented by
(variable, term1, term2)
(where the variable is represented as the number that represents it and each term is represented in the given manner).
def find_degree(program): if program is None or type(program) is int: return 0 _, term1, term2 = program return max(find_degree(term1), find_degree(term2)+1) def try_to_take(program, variables=None): if variables is None: variables = {} if program is None: return 1 if type(program) is int: return variables[program] variable, term1, term2 = program result = try_to_take(term1, variables) def find_nonzero(): new_variables = {**variables, variable: 0} while (takeaway := try_to_take(term2, new_variables)) == 0: new_variables[variable] += 1 return takeaway while result > 0 and halts(find_degree(program), find_nonzero): result -= find_nonzero() return result