def balanced(self): if not (self.child0.balanced() and self.child1.balanced()): return False return ( (len(self.child0) <= len(self.child1) + 1) and (len(self.child1) <= len(self.child0) + 1) ) # Business as usual machine = TestMachine() # Because we might as well machine.add(basic_operations("trees")) # We can always generate leaf nodes. We ignore the Random argument we're given # because all Leaves are created equal. machine.add(generate(lambda _: Leaf(), "trees")) # Given two trees, we can join them together into a new tree machine.add(operation( argspec=("trees", "trees"), target="trees", function=lambda x, y: x.join(y), pattern="{0}.join({1})" )) # Assert that our trees are balanced.
machine = TestMachine() # testmachine.common defines a number of standard operations on different types # of variables. We're going to use some of those rather than implementing our # own. from testmachine.common import basic_operations, arithmetic_operations # We only have one type of variable. We'll call that floats, but this is just # an arbitrary name. We could call it steve if we wanted to. # We generate our basic floats as random numbers between 0 and 1. machine.generate(Random.random, "floats") # These are basic stack manipulation operations. They aren't very exciting, but # they expand the likelihood of producing interesting programs. Most machines # will use these. basic_operations(machine, "floats") # floats can be combined with the normal arithmetic operations arithmetic_operations(machine, "floats") # We want to demonstrate that floating point addition is not associative. This # check will read three variables off our stack of floats and see if adding t # them up in different orders produces the same value. def associative_add(x, y, z): return x + (y + z) == (x + y) + z # If the function we pass to a check returns a falsy value then the program # will fail. machine.check(associative_add, ("floats", "floats", "floats"))
# testmachine.common defines a number of standard operations on different types # of variables. We're going to use some of those rather than implementing our # own. from testmachine.common import ( basic_operations, arithmetic_operations, generate, check ) # We only have one type of variable. We'll call that floats, but this is just # an arbitrary name. We could call it steve if we wanted to. # We generate our basic floats as random numbers between 0 and 1. machine.add(generate(Random.random, "floats")) # These are basic stack manipulation operations. They aren't very exciting, but # they expand the likelihood of producing interesting programs. Most machines # will use these. machine.add(basic_operations("floats")) # floats can be combined with the normal arithmetic operations machine.add(arithmetic_operations("floats")) # We want to demonstrate that floating point addition is not associative. This # check will read three variables off our stack of floats and see if adding t # them up in different orders produces the same value. def associative_add(x, y, z): return x + (y + z) == (x + y) + z # If the function we pass to a check returns a falsy value then the program # will fail. machine.add(check(associative_add, ("floats", "floats", "floats")))
def balanced(self): if not (self.child0.balanced() and self.child1.balanced()): return False return ( (len(self.child0) <= len(self.child1) + 1) and (len(self.child1) <= len(self.child0) + 1) ) # Business as usual machine = TestMachine() # Because we might as well basic_operations(machine, "trees") # We can always generate leaf nodes. We ignore the Random argument we're given # because all Leaves are created equal. machine.generate(lambda _: Leaf(), "trees") # Given two trees, we can join them together into a new tree machine.operation( argspec=("trees", "trees"), target="trees", function = lambda x, y: x.join(y), pattern="%s.join(%s)" ) # Assert that our trees are balanced.