示例#1
0
    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)}
示例#2
0
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)
示例#3
0
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)
示例#4
0
文件: lexer.py 项目: pierg/pycolite
 def t_error(self, t):
     LOG.debug("Illegal character '%s'" % t.value[0])
     t.lexer.skip(1)
示例#5
0
文件: parser.py 项目: pierg/pycolite
 def p_error(self, p):
     LOG.debug('Error')
     print p.value
     raise GeneralError(p)
示例#6
0
    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
示例#7
0
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
示例#8
0
    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)
示例#9
0
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()
示例#10
0
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.
示例#11
0
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