def test_unknown_const_1(): #IGNORE:C01111
    msg = '''Test correct treatment of unknown constants.'''
    py.test.skip(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, DataFlowChecker
    from freeode.interpreter import (Interpreter, IFloat) 
    from freeode.ast import DotName, NodeAssignment

    prog_text = \
'''
data c1: Float const

class A:
    data a, b: Float
    data c2: Float const
    
    func dynamic(this):       
        a = c1
        b = c2

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
#    c = sim.get_attribute(DotName('c1'))
#    c = sim.get_attribute(DotName('c2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b)#,  ' c2:', hexid(c)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #check data flow of all functions
    fc = DataFlowChecker()
    fc.set_sim_object(sim)
    
    
    assert False, 'This program should raise an exceptions because unknown const attributes were used'
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111
    msg = '''Test the creation of data flow annotations.'''
    #py.test.skip(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations
    from freeode.interpreter import (Interpreter, IFloat) 
    from freeode.ast import DotName, NodeAssignment

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c,d: Float
    
    func dynamic(this):       
        a = p1
        b = a - p2
        if a > p1:
            c = p1
            d = p1
        else:
            c = p2 
            d = p2

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
    c = sim.get_attribute(DotName('c'))
    d = sim.get_attribute(DotName('d'))
    p1 = sim.get_attribute(DotName('p1'))
    p2 = sim.get_attribute(DotName('p2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))    
    #print object ids in hex (for easier manual testing)
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b),  ' c:', hexid(c),  ' d:', hexid(d), \
          ' p1:', hexid(p1),  ' p2:', hexid(p2) 

    #------- the test -------------------
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #dd.decorate_main_function(dyn)

    #see if the inputs and outputs were detected correctly
    # a = p1   
    stmt = dyn.statements[0]
    assert stmt.inputs == set([p1])
    assert stmt.outputs == set([a])
    #  b = a - p2
    stmt = dyn.statements[1]
    assert stmt.inputs == set([a, p2])
    assert stmt.outputs == set([b])
    
    #'if' statement
    stmt = dyn.statements[2]
    #look at inputs
    assert stmt.inputs.issuperset(set([a, p1, p2])) 
    #there is an additional constant IFloat(1) in the condition of the else
    one_set = stmt.inputs - set([a, p1, p2])
    assert len(one_set) == 1
    one_obj = one_set.pop()
    assert one_obj == IFloat(1)
    #look at outputs
    assert stmt.outputs == set([c, d])
    
    #the dynamic function
    assert dyn.inputs == set([p1, p2, one_obj])
    assert dyn.outputs == set([a, b, c, d])
示例#3
0
def test_VariableUsageChecker_1(): #IGNORE:C01111
    msg = '''Test checking of variable usage. Simple program with no errors.
    Use individual checking functions.
    
    These are the rules:
    Constants (rules enforced in the interpreter):
        - All constants must be known.
        - No assignments to constants.
        
    Parameters:
        - All must be assigned in all init**** function.
        - No assignment to parameters elsewhere.
        
    Variables:
        - All derivatives must be assigned in dynamic function.
        - No states must be assigned in dynamic function.
        - All states must be assigned initial values in init*** function.
    '''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker
    from freeode.interpreter import Interpreter
    from freeode.util import DotName#, aa_make_tree

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c: Float
    
    func init_1(this, ext1, ext2):
        ext2 = 1 #not useful but legal for simplicity
        p1 = ext1
        p2 = 1
        a = 0
        
    func initialize(this):
        p1 = 1
        p2 = 1
        a = 0
        print(time)
        data lo: Float
        lo = p1
        
    func dynamic(this): 
        $a = p1
        b = a - p2
        
        if a > p1:
            c = p1
        else:
            c = p2 
        data lo: Float variable
        lo = p1


    func final(this):
        b = 1
        print(a, b, p1)
        data lo: Float variable
        lo = p1
        
        
compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print aa_make_tree(sim)
    #print aa_make_tree(sim.func_locals)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)

    #Find all input and output variables
    vu = VariableUsageChecker()
    vu.set_annotated_sim_object(sim) 
    
    #Check the usage of the variables 
    init_1 = vu.main_funcs[DotName('init_1')]
    vu.check_initialize_function(init_1) 
    
    initialize = vu.main_funcs[DotName('initialize')]
    vu.check_initialize_function(initialize) 
    
    dynamic = vu.main_funcs[DotName('dynamic')]
    vu.check_dynamic_function(dynamic) 
    
    final = vu.main_funcs[DotName('final')]
    vu.check_final_function(final) 
示例#4
0
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111
    msg = '''Test the creation of data flow annotations.'''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations
    from freeode.interpreter import Interpreter, IFloat
    #from freeode.ast import NodeAssignment
    from freeode.util import DotName

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c,d: Float
                              #5 
    func dynamic(this):            
        a = p1
        b = a - p2
        if a > p1:
            c = p1           #10
            d = p1
        else:
            c = p2 
            d = p2
        print(a)

compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #print sim
    #get attributes
    a = sim.get_attribute(DotName('a'))
    b = sim.get_attribute(DotName('b'))
    c = sim.get_attribute(DotName('c'))
    d = sim.get_attribute(DotName('d'))
    p1 = sim.get_attribute(DotName('p1'))
    p2 = sim.get_attribute(DotName('p2'))
    #get generated main function
    dyn = sim.get_attribute(DotName('dynamic'))    
    #print object ids in hex (for easier manual testing)
    hexid = lambda x: hex(id(x))
    print 'a:', hexid(a), ' b:', hexid(b),  ' c:', hexid(c),  ' d:', hexid(d), \
          ' p1:', hexid(p1),  ' p2:', hexid(p2) 

    #------- the test -------------------
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)
    #dd.decorate_main_function(dyn)

    #see if the inputs and outputs were detected correctly
    # a = p1--------------------------------------
    stmt0 = dyn.statements[0]
    assert stmt0.inputs == set([p1])
    assert stmt0.outputs == set([a])
    #  b = a - p2 --------------------------------
    stmt1 = dyn.statements[1]
    assert stmt1.inputs == set([a, p2])
    assert stmt1.outputs == set([b])
    
    #'if' statement ------------------------------
    stmt2 = dyn.statements[2]
    #look at inputs
    assert stmt2.inputs.issuperset(set([a, p1, p2])) 
    #there is an additional constant IFloat(1) in the condition of the else
    one_set = stmt2.inputs - set([a, p1, p2])
    assert len(one_set) == 1
    one_obj = one_set.pop()
    assert one_obj == IFloat(1)
    #look at outputs
    assert stmt2.outputs == set([c, d])
    
    #print(a) -------------------------------------
    stmt3 = dyn.statements[3]
    assert stmt3.inputs == set([a])
    assert stmt3.outputs == set()
    #the dynamic function as a whole --------------
    assert dyn.inputs == set([p1, p2, one_obj])
    assert dyn.outputs == set([a, b, c, d])
    
    #The input_locs, output_locs mappings for creating error messages
    #Parameter p1
    assert p1 not in dyn.output_locs #p1 is written nowhere
    p1_in_locs = dyn.input_locs[p1]
    assert len(p1_in_locs) == 4 #p1 read in 4 places
    assert p1_in_locs[0].line_no() == stmt0.loc.line_no() #read in statement 0
    assert p1_in_locs[1].line_no() == stmt2.loc.line_no() #read in 'if' statement
    #  + read in two lines in body of 'if' statement
#    for loc in p1_in_locs:
#        print loc
    #Variable a
    a_out_loc = dyn.output_locs[a]
    assert len(a_out_loc) == 1 #a written in 1 place
    assert a_out_loc[0].line_no() == stmt0.loc.line_no() #written in statement 0
    a_in_loc = dyn.input_locs[a]
    assert len(a_in_loc) == 3 #a read in 3 places
    assert a_in_loc[0].line_no() == stmt1.loc.line_no()
    assert a_in_loc[1].line_no() == stmt2.loc.line_no()
    assert a_in_loc[2].line_no() == stmt3.loc.line_no()
def test_VariableUsageChecker_1(): #IGNORE:C01111
    msg = '''Test checking of variable usage. Provoke all errors at least once.'''
    #skip_test(msg)
    print msg
    
    from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker
    from freeode.interpreter import Interpreter
    from freeode.util import DotName, UserException#, aa_make_tree

    prog_text = \
'''
class A:
    data p1,p2: Float param
    data a,b,c: Float
    
    #illegal read of parameter p1
    func init_1(this):
        p2 = p1
        a = 0
        
    #illegal write to derivative $a
    func init_2(this):
        $a = 1
        p1 = 1
        p2 = 1
        a = 0
    
    #Missing assignment to parameter p1
    func init_3(this):
        p2 = 1
        a = 0
        
    #illegal write to state variable a
    func dynamic(this): 
        a = 2
        $a = p1
        b = a - p2
        c = p1
        
    #illegal write to state variable a
    func final(this):
        a = 2
        b = 1
        print(a, b, p1)
        
        
compile A
'''

    #interpret the program
    intp = Interpreter()
    intp.interpret_module_string(prog_text, None, 'test')

    #the module
    #mod = intp.modules['test']
    #print mod
    
    #get the flattened version of the A class
    sim = intp.get_compiled_objects()[0]
    #aa_make_tree(sim)
    
    #create the input and output decorations on each statement of the 
    #function
    dd = MakeDataFlowDecorations()
    dd.decorate_simulation_object(sim)

    #Find all input and output variables
    vu = VariableUsageChecker()
    vu.set_annotated_sim_object(sim) 
    
    #illegal read of parameter p1
    initialize = vu.main_funcs[DotName('init_1')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500100, 
                  vu.check_initialize_function, initialize)
    
    #illegal write to derivative $a
    initialize = vu.main_funcs[DotName('init_2')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500200, 
                  vu.check_initialize_function, initialize)
    
    #Missing assignment to parameter p1
    initialize = vu.main_funcs[DotName('init_3')]
    #vu.check_initialize_function(initialize) 
    assert_raises(UserException, 4500300, 
                  vu.check_initialize_function, initialize)
    
    #illegal write to state variable a
    dynamic = vu.main_funcs[DotName('dynamic')]
    #vu.check_dynamic_function(dynamic) 
    assert_raises(UserException, 4500200, 
                  vu.check_dynamic_function, dynamic)
    
    #illegal write to state variable a
    final = vu.main_funcs[DotName('final')]
    #vu.check_final_function(final) 
    assert_raises(UserException, 4500200, 
                  vu.check_final_function, final)