def formulae_reverse_dict(self): ''' return a dict of lterals used in contract formulae, indexed by unique_name ''' #use the formulae instead of the dict because the dicts #overrides duplicates try: #unzip _, values = zip(* (self.assume_formula.get_literal_items() | \ self.guarantee_formula.get_literal_items())) except ValueError: LOG.debug('no literals??') return {} else: return {key_lit.unique_name: [literal for literal in values if literal.unique_name == key_lit.unique_name] for key_lit in set(values)}
def test_hotzi_totzi(composition_hotzi_totzi): ''' just check everything is in order tests true only for these contracts (refinement of composition) ''' (c1, c2, c12) = composition_hotzi_totzi LOG.debug(c1) LOG.debug(c2) LOG.debug(c12) assert c12.is_compatible() assert c12.is_consistent() assert not c12.is_refinement(c1) assert not c12.is_refinement(c2)
def test_easy_peasy(composition_easy_peasy): ''' just check everything is in order. Tests true only for these contracts(refinement of composition) ''' (c1, c2, c12) = composition_easy_peasy LOG.debug(c1) LOG.debug(c2) LOG.debug(c12) assert c12.is_compatible() assert c12.is_consistent() assert c12.is_refinement(c1) assert c12.is_refinement(c2)
def t_error(self, t): LOG.debug("Illegal character '%s'" % t.value[0]) t.lexer.skip(1)
def p_error(self, p): LOG.debug('Error') print p.value raise GeneralError(p)
def update(self, updated_subject): ''' Implementation of the update method from a attribute according to the observer pattern ''' updated_attribute = updated_subject.get_state() #if updated_attribute.base_name not in self.literals: # raise KeyError('attribute not in literals dict for the formula') #only if different: #if self.literals[updated_subject.base_name] != updated_attribute: #detach from the current attribute try: self.literals[updated_subject.base_name].detach(self) #update the literals list del self.literals[updated_subject.base_name] except KeyError as key: LOG.debug('%s not found.Look into this' % key) LOG.debug('it may happen for ports. they are observers') LOG.debug(self) LOG.debug(self.literals) LOG.debug(updated_subject) LOG.debug(updated_subject.base_name) #raise else: pass #attach to the new attribute updated_attribute.attach(self) self.literals[updated_attribute.base_name] = updated_attribute
def derive_valuation_from_trace(trace, variables, max_horizon=None): """ Derives a formula encoding the input sequence used in the trace :param trace: :param variables: :return: """ time_sequence = [] i = -1 unique_names = {p.unique_name: p for p in variables} # LOG.debug(trace) # LOG.debug(monitored_vars) #create structure to record values # #process only the first one # p = monitored_vars.keys()[0] # for p in input_variables: # # LOG.debug(p.base_name) # # LOG.debug(p.unique_name) # c_vars[p.unique_name]= None # var_assign[p] = set() # # for v_p in input_variables[p]['ports']: # # LOG.debug(v_p.base_name) # # LOG.debug(v_p.unique_name) # c_vars[v_p.unique_name] = None # var_assign[p].add(v_p) # LOG.debug(c_vars) lines = trace.split('\n') after_preamble = False pre_trace = True lasso_index = -1 for line in lines: line = line.strip() # LOG.debug(line) ## Only if with coi # if pre_trace: # if not line.startswith('-- Trace was successfully completed.'): # continue # else: # pre_trace = False if not after_preamble: if line.startswith('Trace Type: Counterexample'): after_preamble = True continue # LOG.debug('after preamble') continue # done with the preamble # analyze state by state if line.startswith('->'): i = i + 1 #time_sequence.append({}) if i == 0: time_sequence.append({x: None for x in unique_names}) else: time_sequence.append( {x: time_sequence[i - 1][x] for x in unique_names}) # new state, check consistency among vars # LOG.debug(c_vars) # for p in input_variables: # # if i > 0: # time_sequence[i][p.unique_name] = time_sequence[i-1][p.unique_name] # else: # time_sequence[i][p.unique_name] = Constant(0) # LOG.debug(diff) elif line.startswith('--'): # if lasso_index > -1: # continue #already have a loop # indicates loop in trace, skip line lasso_index = i + 2 else: line_elems = line.split('=') line_elems = [l.strip() for l in line_elems] # LOG.debug(line_elems) # LOG.debug(c_vars) if line_elems[0] in unique_names: # base_n = monitored_vars[line_elems[0]] if line_elems[1] == 'TRUE': val = TrueFormula() elif line_elems[1] == 'FALSE': val = FalseFormula() else: try: val = int(line_elems[1]) except ValueError: val = float(line_elems[1]) val = Constant(val) time_sequence[i][line_elems[0]] = val # time_sequence = time_sequence[:-1] formula_bits = [] for i in range(len(time_sequence)): inner = [] for u_name, val in time_sequence[i].items(): inner.append( Equivalence(unique_names[u_name].literal, val, merge_literals=False)) if len(inner) > 0: inner = reduce( lambda x, y: Conjunction(x, y, merge_literals=False), inner) for j in range(i): inner = Next(inner) formula_bits.append(inner) # formula_bits has i elements. We need to replicate the lasso sequence diff = len(formula_bits) - lasso_index horizon = len(formula_bits) # LOG.debug(trace) LOG.debug(diff) #include full loops. use max_horizon to figure out how many loops you need. while diff > 0 and max_horizon is not None and horizon <= max_horizon: partial = [] for j in range(diff, 0, -1): partial.append(formula_bits[-j]) #add horizons for j in range(len(partial)): for h in range(diff): partial[j] = Next(partial[j]) formula_bits += partial horizon = len(formula_bits) # if horizon > max_horizon+1: # formula_bits = formula_bits[:max_horizon+1] try: conj = reduce(lambda x, y: Conjunction(x, y, merge_literals=False), formula_bits) except TypeError: formula = None else: # formula = Globally(Eventually(conj)) formula = conj return formula, lasso_index
def define_composed_contract_ports(self): ''' Identifies and defines the input and output ports of the composed contract. Raises an exception in case of conflicts. Ports mapped on the same port will be connected. In case of missing mapping, this method will try to automatically derive new contract ports in case of no conflict. ''' new_input_ports = {} new_output_ports = {} #associate new var for performance (reverse_mapping is computed each time) reverse_map = self.reverse_mapping #returns a set of tuples conflict_set = self.find_conflicts() for port_set in conflict_set: if port_set > set(reverse_map.viewkeys()): #this means a conflict is not explicitely solved LOG.debug([ '%s - %s' % (port.contract.base_name, port.base_name) for port in (port_set - reverse_map.viewkeys()) ]) LOG.debug(reverse_map) raise PortMappingError() #connect and check port consistency #LOG.debug(self.mapping) for (name, port_set) in self.mapping.viewitems(): #we need to connects all the ports in port_set #error if we try to connect mulptiple outputs outputs = [port for port in port_set if port.is_output] if len(outputs) > 1: raise PortConnectionError('cannot connect multiple outputs') else: #merge port literals #LOG.debug([p.unique_name + ':'+p.l_type + ':'+p.literal.l_type for p in port_set]) port = port_set.pop() for p in port_set: port.merge(p) #port = reduce(lambda x, y: x.merge(y), port_set) if len(outputs) == 0: #all inputs -> input new_input_ports[name] = Port(name, l_type=port.l_type, literal=port.literal, context=self.context) else: #1 output -> output new_output_ports[name] = Port(name, l_type=port.l_type, literal=port.literal, context=self.context) #complete with implicit ports from contracts #we have disjoint ports or ports which have been previously connected #however we are sure, from the previous step, that there are not conflicting #port names input_pool = { name: Port(name, l_type=port.l_type, literal=port.literal, context=self.context) #port for contract in self.contracts for (name, port) in contract.input_ports_dict.viewitems() } output_pool = { name: Port(name, l_type=port.l_type, literal=port.literal, context=self.context) #port for contract in self.contracts for (name, port) in contract.output_ports_dict.viewitems() } mapped_ports = set([port.base_name for port in reverse_map]) #LOG.debug(mapped_ports) implicit_input_names = input_pool.viewkeys() - mapped_ports implicit_output_names = output_pool.viewkeys() - mapped_ports filtered_inputs = implicit_input_names - implicit_output_names #LOG.debug(implicit_input_names) for name in filtered_inputs: #also, check for feedback loops or connected I/O and do not add inputs in case if not any([ input_pool[name].is_connected_to(port) for port in output_pool.viewvalues() ]): new_input_ports[name] = Port(name, l_type=input_pool[name].l_type, literal=input_pool[name].literal, context=self.context) for name in implicit_output_names: new_output_ports[name] = Port(name, l_type=output_pool[name].l_type, literal=output_pool[name].literal, context=self.context) #import pdb #pdb.set_trace() return (new_input_ports, new_output_ports)
from pycolite.attribute import Attribute from pycolite.formula import Literal, Conjunction, Disjunction, Negation from pycolite.observer import Observer from copy import deepcopy #from pycolite.ltl3ba import (Ltl3baRefinementStrategy, Ltl3baCompatibilityStrategy, # Ltl3baConsistencyStrategy) from pycolite.nuxmv import (NuxmvRefinementStrategy, NuxmvCompatibilityStrategy, NuxmvConsistencyStrategy, NuxmvApproximationStrategy) from abc import ABCMeta, abstractmethod from pycolite import LOG from pycolite.types import Int, Bool LOG.debug('in contract.py') def verify_refinement(refined, abstract, refinement_mapping=None, strategy_obj=None): ''' Verifies that refined refines abstract. :returns: boolean ''' if refinement_mapping is None: refinement_mapping = RefinementMapping([refined, abstract]) #get copies contract_copies, mapping_copy = refinement_mapping.get_mapping_copies()
Basic implementation of ports and basic types Author: Antonio Iannopollo ''' from pycolite.formula import Literal, Conjunction, Disjunction, Negation from pycolite.observer import Observer from copy import deepcopy #from pycolite.ltl3ba import (Ltl3baRefinementStrategy, Ltl3baCompatibilityStrategy, # Ltl3baConsistencyStrategy) from abc import ABCMeta, abstractmethod from pycolite import LOG from pycolite.types import Int, Bool, Float LOG.debug('in port.py') class Port(Observer): ''' This class implements a port for a contract. It contains a literal but it keeps constant its base name ''' def __init__(self, base_name, l_type=Bool(), contract=None, literal=None, context=None): ''' Creates a new port and associates a literal.
def test_formula(a_formula): literals = [l for (_, l) in a_formula.get_literal_items()] LOG.debug('test ltl2smv') LOG.debug(ltl2smv(a_formula, '3', literals[:2], literals[2:])) assert True