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")) if __name__ == '__main__': # Attempt to find a falsifying example for the problem we've defined and # print it to stdout. If this cannot find any examples (it will), say so. machine.run()
Find an example demonstrating that lists can contain the same element multiple times. Example output: t1 = 1 t2 = [t1, t1] assert unique(t2) """ from testmachine import TestMachine from testmachine.common import ints, lists machine = TestMachine() # Populate the ints varstack with integer values ints(machine) # Populate the intlists varstack with lists whose elements are drawn from the # ints varstack lists(machine, source="ints", target="intlists") # Check whether a list contains only unique elements. If it contains duplicates # raise an error. machine.check( lambda s: len(s) == len(set(s)), argspec=("intlists",), name="unique" ) if __name__ == '__main__': # Find a program that creates a list with non-unique elements. machine.run()
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. machine.check( test=lambda x: x.balanced(), argspec=("trees",), # The pattern argument controls the output formatting when emitting an # example. It will be formatted with the name of the variable we are # checking. pattern="assert %s.balanced()" ) if __name__ == '__main__': machine.run()