def test_parse_steps_with_multiple_comparisons(): proclang = ''' main: 1. PRIMARY: set injector_valve to open 2. PRIMARY: [p1 < 100 and p2 < 100 and p3 < 100] set vent_valve to closed 3. PRIMARY: [p1 < 100 or p2 < 100 or p3 < 100] set vent_valve to open 4. PRIMARY: [p1 < 100 and p2 < 100 and p3 < 100 or p1 < 100 and p2 < 100] set vent_valve to open ''' suite = top.proclang.parse(proclang) p1 = top.Less('p1', 100) p2 = top.Less('p2', 100) p3 = top.Less('p3', 100) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [ (top.And([p1, p2, p3]), top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [(top.Or( [p1, p2, p3]), top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.StateChangeAction( 'vent_valve', 'open'), [ (top.Or([top.And([p1, p2, p3]), top.And([p1, p2])]), top.Transition('main', '4')) ], 'PRIMARY'), top.ProcedureStep('4', top.StateChangeAction('vent_valve', 'open'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_parse_steps_with_complex_comparisons(): proclang = ''' main: 1. PRIMARY: set injector_valve to open 2. PRIMARY: [p1 < 100 and p2 > 200] set vent_valve to closed 3. SECONDARY: [p1 > 100 or p2 < 200] set vent_valve to open 4. SECONDARY: [(p1 <= 100)] set vent_valve to closed 5. OPS: [p1 < 100 or p2 > 200 and p3 < 100] set vent_valve to open 6. OPS: [p1 < 100 and p2 > 200 or p3 < 100] set vent_valve to open 7. OPS: [(p1 < 100 or p2 > 200) and p3 < 100] set vent_valve to closed ''' suite = top.proclang.parse(proclang) comp_and = top.And([top.Less('p1', 100), top.Greater('p2', 200)]) comp_or = top.Or([top.Greater('p1', 100), top.Less('p2', 200)]) comp_and_or_1 = top.Or([ top.Less('p1', 100), top.And([top.Greater('p2', 200), top.Less('p3', 100)]) ]) comp_and_or_2 = top.Or([ top.And([top.Less('p1', 100), top.Greater('p2', 200)]), top.Less('p3', 100) ]) comp_and_or_3 = top.And([ top.Or([top.Less('p1', 100), top.Greater('p2', 200)]), top.Less('p3', 100) ]) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(comp_and, top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep( '2', top.StateChangeAction('vent_valve', 'closed'), [(comp_or, top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.StateChangeAction( 'vent_valve', 'open'), [(top.LessEqual( 'p1', 100), top.Transition('main', '4'))], 'SECONDARY'), top.ProcedureStep( '4', top.StateChangeAction('vent_valve', 'closed'), [(comp_and_or_1, top.Transition('main', '5'))], 'SECONDARY'), top.ProcedureStep('5', top.StateChangeAction('vent_valve', 'open'), [(comp_and_or_2, top.Transition('main', '6'))], 'OPS'), top.ProcedureStep('6', top.StateChangeAction('vent_valve', 'open'), [(comp_and_or_3, top.Transition('main', '7'))], 'OPS'), top.ProcedureStep('7', top.StateChangeAction( 'vent_valve', 'closed'), [], 'OPS') ]) ]) assert suite == expected_suite
def test_and_equality(): and_1 = top.And([top.Immediate(), top.Immediate()]) and_2 = top.And([top.Immediate(), top.Immediate()]) and_3 = top.And([NeverSatisfied(), top.Immediate()]) assert and_1 == and_2 assert and_1 != and_3 assert and_1 != 10 assert and_1 is not None
def test_nested_and_conditions(): and_sat = top.And( [top.Immediate(), top.And([top.Immediate(), top.Immediate()])]) and_unsat = top.And( [top.Immediate(), top.And([NeverSatisfied(), top.Immediate()])]) assert and_sat.satisfied() is True assert and_unsat.satisfied() is False
def test_waitfor_latex_export(): suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(top.And([ top.WaitFor(10e6), top.Or( [top.Less('p1', 400.0), top.GreaterEqual('p2', 17.0)]) ]), top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction( 'vent_valve', 'closed'), [], 'PRIMARY') ]) ]) export = suite.export(top.ExportFormat.Latex) expected_export = textwrap.dedent(r''' \subsection{main} \begin{checklist} \item \PRIMARY{} Open injector\_valve \item Wait 10 seconds and p1 is less than 400psi or p2 is greater than or equal to 17psi \item \PRIMARY{} Close vent\_valve \end{checklist}''') assert export == expected_export
def test_parse_combined_conditions(): proclang = ''' main: 1. PRIMARY: set s to v 2. PRIMARY: [p1 < 100 or 500s and p2 < 200] set s to v ''' suite = top.proclang.parse(proclang) comp_or = top.Or([ top.Less('p1', 100), top.And([top.WaitFor(1e6 * 500), top.Less('p2', 200)]) ]) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep('1', top.StateChangeAction('s', 'v'), [ (comp_or, top.Transition('main', '2')) ], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('s', 'v'), [], 'PRIMARY') ]) ]) assert suite == expected_suite
def test_nested_logic_works(): eq_cond_1 = top.Equal('A1', 100) eq_cond_2 = top.Equal('A2', 100) wait_cond = top.WaitFor(100) or_cond = top.Or([eq_cond_1, eq_cond_2]) and_cond = top.And([or_cond, wait_cond]) state_0 = {'pressures': {'A1': 0, 'A2': 0, 'A3': 0}, 'time': 0} state_1 = {'pressures': {'A1': 100, 'A2': 200, 'A3': 300}, 'time': 100} assert eq_cond_1.satisfied() is False assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is False assert or_cond.satisfied() is False assert and_cond.satisfied() is False and_cond.reinitialize(state_0) assert eq_cond_1.satisfied() is False assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is False assert or_cond.satisfied() is False assert and_cond.satisfied() is False and_cond.update(state_1) assert eq_cond_1.satisfied() is True assert eq_cond_2.satisfied() is False assert wait_cond.satisfied() is True assert or_cond.satisfied() is True assert and_cond.satisfied() is True
def test_and_updates_subconditions(): eq_cond = top.Equal('A1', 100) and_cond = top.And([eq_cond]) state = {'pressures': {'A1': 100}} assert eq_cond.satisfied() is False assert and_cond.satisfied() is False and_cond.update(state) assert eq_cond.satisfied() is True assert and_cond.satisfied() is True
def boolean_expr_and(self, data): """ Process `boolean_expr_and` nodes in the parse tree. `data` is a list of `boolean`'s that were interspersed in the text with logical AND's. """ if len(data) == 1: return data[0] else: return top.And(data)
def test_and_requires_all_satisfied(): eq_cond_1 = top.Equal('A1', 100) eq_cond_2 = top.Equal('A2', 100) and_cond = top.And([eq_cond_1, eq_cond_2]) state = {'pressures': {'A1': 100, 'A2': 200}} assert eq_cond_1.satisfied() is False assert eq_cond_2.satisfied() is False assert and_cond.satisfied() is False and_cond.update(state) assert eq_cond_1.satisfied() is True assert eq_cond_2.satisfied() is False assert and_cond.satisfied() is False
def test_parse_logical_operator_forms(): proclang = ''' main: 1. PRIMARY: set injector_valve to open 2. PRIMARY: [p1 < 100 and p2 < 100] set vent_valve to open 3. PRIMARY: [p1 < 100 AND p2 < 100] set vent_valve to open 4. PRIMARY: [p1 < 100 && p2 < 100] set vent_valve to open 5. CONTROL: [p1 < 100 or p2 < 100] set vent_valve to open 6. CONTROL: [p1 < 100 OR p2 < 100] set vent_valve to open 7. CONTROL: [p1 < 100 || p2 < 100] set vent_valve to open ''' suite = top.proclang.parse(proclang) comp_and = top.And([top.Less('p1', 100), top.Less('p2', 100)]) comp_or = top.Or([top.Less('p1', 100), top.Less('p2', 100)]) expected_suite = top.ProcedureSuite([ top.Procedure('main', [ top.ProcedureStep( '1', top.StateChangeAction('injector_valve', 'open'), [(comp_and, top.Transition('main', '2'))], 'PRIMARY'), top.ProcedureStep('2', top.StateChangeAction('vent_valve', 'open'), [(comp_and, top.Transition('main', '3'))], 'PRIMARY'), top.ProcedureStep('3', top.StateChangeAction('vent_valve', 'open'), [(comp_and, top.Transition('main', '4'))], 'PRIMARY'), top.ProcedureStep('4', top.StateChangeAction('vent_valve', 'open'), [(comp_or, top.Transition('main', '5'))], 'PRIMARY'), top.ProcedureStep('5', top.StateChangeAction('vent_valve', 'open'), [(comp_or, top.Transition('main', '6'))], 'CONTROL'), top.ProcedureStep('6', top.StateChangeAction('vent_valve', 'open'), [(comp_or, top.Transition('main', '7'))], 'CONTROL'), top.ProcedureStep('7', top.StateChangeAction('vent_valve', 'open'), [], 'CONTROL') ]) ]) assert suite == expected_suite
def test_string_representations(): immediate_cond = top.Immediate() waitFor_cond = top.WaitFor(1000000) equal_cond = top.Equal('A1', 100) less_cond = top.Less('A2', 100) greater_cond = top.Greater('A3', 100) lessEqual_cond = top.LessEqual('A4', 100) greaterEqual_cond = top.GreaterEqual('A5', 100) and_cond = top.And([less_cond, greater_cond]) or_cond = top.Or([lessEqual_cond, greaterEqual_cond]) assert str(immediate_cond) == 'Immediately' assert str(waitFor_cond) == 'Wait for 1 seconds' assert str(equal_cond) == 'A1 == 100' assert str(less_cond) == 'A2 < 100' assert str(greater_cond) == 'A3 > 100' assert str(lessEqual_cond) == 'A4 <= 100' assert str(greaterEqual_cond) == 'A5 >= 100' assert str(and_cond) == '(A2 < 100 and A3 > 100)' assert str(or_cond) == '(A4 <= 100 or A5 >= 100)'
def test_and_or_not_equal(): and_cond = top.And([NeverSatisfied(), top.Immediate()]) or_cond = top.Or([NeverSatisfied(), top.Immediate()]) assert and_cond != or_cond