def gen_main_check_function(checker_env, id_prop_map): function_name = "neco_check" builder = cyast.Builder() variable_provider = VariableProvider() checker_env.push_cvar_env() checker_env.push_variable_provider(variable_provider) marking_var = variable_provider.new_variable( variable_type=checker_env.marking_type.type) atom_var = variable_provider.new_variable( variable_type=TypeInfo.get('Int')) builder.begin_FunctionCDef( name=function_name, args=(cyast.A(marking_var.name, type=checker_env.type2str(marking_var.type)).param( atom_var.name, type=checker_env.type2str(TypeInfo.get('Int')))), returns=cyast.Name("int"), decl=[], public=True, api=True) for (i, (ident, _)) in enumerate(id_prop_map.iteritems()): if i == 0: builder.begin_If( test=cyast.Compare(left=cyast.Name(atom_var.name), ops=[cyast.Eq()], comparators=[cyast.Num(ident)])) else: builder.begin_Elif( test=cyast.Compare(left=cyast.Name(atom_var.name), ops=[cyast.Eq()], comparators=[cyast.Num(ident)])) builder.emit_Return( checker_env.get_check_function("check_{}".format(ident)).call( [cyast.Name(marking_var.name)])) for _ in id_prop_map: builder.end_If() builder.emit( cyast.Print(dest=cyast.E('sys.stderr'), values=[ cyast.Str(s='!W! invalid proposition identifier'), cyast.Name(atom_var.name) ], nl=True)) builder.emit_Return(cyast.Num(n=0)) builder.end_FunctionDef() tree = cyast.to_ast(builder) checker_env.register_check_function(function_name, FunctionWrapper(function_name, tree)) return tree
def gen_multiset_comparison(checker_env, marking_var, cython_op, left, right): if left.isPlaceMarking(): left_multiset = multiset_expr_from_place_name(checker_env, marking_var, left.place_name) elif left.isMultisetConstant(): left_multiset = build_multiset(left.elements) elif left.isMultisetPythonExpression(): left_multiset = cyast.E(left.expr) else: raise NotImplementedError if right.isPlaceMarking(): right_multiset = multiset_expr_from_place_name(checker_env, marking_var, right.place_name) elif right.isMultisetConstant(): right_multiset = build_multiset(right.elements) elif right.isMultisetPythonExpression(): right_multiset = cyast.E(right.expr) else: raise NotImplementedError return cyast.Compare(left=left_multiset, ops=[cython_op], comparators=[right_multiset])
def gen_different(self, indices): base = None current = None first_index = indices.pop() for index in indices: check = cyast.If(test=cyast.Compare( left=cyast.Name(first_index.name), ops=[cyast.NotEq()], comparators=[cyast.Name(index.name)]), body=[], orelse=[]) if not base: base = check current = check else: current.body.append(check) current = check inner = current if len(indices) > 1: _, inner = self.gen_different(indices) current.body.append(base) return base, inner
def gen_check_expression(checker_env, marking_var, formula): if formula.isIntegerComparison(): operator = operator_to_cyast(formula.operator) left = gen_check_expression(checker_env, marking_var, formula.left) right = gen_check_expression(checker_env, marking_var, formula.right) return cyast.Compare(left=left, ops=[operator], comparators=[right]) elif formula.isMultisetComparison(): operator = operator_to_cyast(formula.operator) return gen_multiset_comparison(checker_env, marking_var, operator, formula.left, formula.right) elif formula.isIntegerConstant(): return cyast.Num(int(formula.value)) elif formula.isMultisetCardinality(): multiset = formula.multiset if multiset.isPlaceMarking(): return checker_env.place_card_expression(marking_var, multiset.place_name) else: raise NotImplementedError elif formula.isSum(): operands = formula.operands head = operands[0] tail = operands[1:] left = gen_check_expression(checker_env, marking_var, head) if len(tail) > 1: right = gen_check_expression(checker_env, marking_var, Sum(tail)) else: right = gen_check_expression(checker_env, marking_var, tail[0]) return cyast.BinOp(left=left, op=cyast.Add(), right=right) elif formula.isDeadlock(): pass # nothing to do just add option -d DEAD to neco-spot elif formula.isFireable(): return checker_env.is_fireable_expression(marking_var, formula.transition_name) elif formula.isAll(): return checker_env.is_all_expression(marking_var, formula.place_name, formula.function_name) elif formula.isAny(): return checker_env.is_any_expression(marking_var, formula.place_name, formula.function_name) elif formula.isMultisetCard(): return checker_env.gen_multiset_card_expression( marking_var, formula.multiset) else: print >> sys.stderr, "Unknown atomic proposition {!s}".format(formula) raise NotImplementedError
def gen_InPlace_function(checker_env, function_name, place_name): marking_type = checker_env.marking_type variable_provider = VariableProvider() checker_env.push_cvar_env() checker_env.push_variable_provider(variable_provider) builder = cyast.Builder() marking_var = variable_provider.new_variable( variable_type=marking_type.type) place_type = marking_type.get_place_type_by_name(place_name) token_var = variable_provider.new_variable( variable_type=place_type.token_type) # check_var = variable_provider.new_variable(variable_type=TypeInfo.Int) builder.begin_FunctionCDef( name=function_name, args=(cyast.A(marking_var.name, type=checker_env.type2str(marking_var.type)).param( name=token_var.name, type=checker_env.type2str(token_var.type))), returns=cyast.Name("int"), decl=[], public=False, api=False) main_body = [] loop_var = variable_provider.new_variable( variable_type=place_type.token_type) inner_body = cyast.If( cyast.Compare(cyast.Name(token_var.name), [cyast.Eq()], [cyast.Name(loop_var.name)]), [cyast.Return(cyast.Num(1))]) node = place_type.enumerate_tokens(checker_env, loop_var, marking_var, body=inner_body) main_body.append(node) main_body.append(cyast.Return(value=cyast.Num(0))) for stmt in main_body: builder.emit(stmt) builder.end_FunctionDef() return FunctionWrapper(function_name, cyast.to_ast(builder))