def run(self): ''' process one output at a time :return: ''' print('\tprocessing port %s' % self.pivot_name) for spec in self.spec_list: # build composition w_spec = spec.copy() w_spec1 = spec.copy() w_spec2 = spec.copy() mapping = CompositionMapping([w_spec1, w_spec2]) # connect pivot output port w_spec.connect_to_port(w_spec.output_ports_dict[self.pivot_name], w_spec1.output_ports_dict[self.pivot_name]) # connect inputs for name, in_port in w_spec.input_ports_dict.items(): w_spec.connect_to_port(in_port, w_spec1.input_ports_dict[name]) w_spec.connect_to_port(in_port, w_spec2.input_ports_dict[name]) # # add explicit naming # mapping.add(w_spec1.input_ports_dict[name], # '1_' + name) # mapping.add(w_spec2.input_ports_dict[name], # '2_' + name) # connect remaining outputs for name, out_port in w_spec.output_ports_dict.items(): # add explicit naming mapping.add(w_spec1.output_ports_dict[name], '1_' + name) mapping.add(w_spec2.output_ports_dict[name], '2_' + name) if name != self.pivot_name: w_spec.connect_to_port(out_port, w_spec2.output_ports_dict[name]) # compose composition = w_spec1.compose([w_spec2], composition_mapping=mapping) passed = composition.is_refinement(w_spec) if passed is False: break self.res_queue.put((self.pivot_name, passed)) self.semaphore.release() return
def __init__(self, components, context=None): ''' Extract contracts from components ''' self.components = components self.composition_mapping = CompositionMapping( [component.contract for component in components], context) return
def get_mapping_copies(self): ''' returns a copy of the contracts and an updated LibraryPortMapping object related to those copies :returns: a pair, in which the first element is a dictionary containing a reference to the copied contracts, and a LibraryPortMapping object ''' new_contracts = { contract: contract.copy() for contract in self.composition_mapping.contracts } new_mapping = CompositionMapping(new_contracts.viewvalues()) for mapped_name, ports in self.composition_mapping.mapping.viewitems(): for port in ports: new_mapping.add( new_contracts[port.contract].ports_dict[port.base_name], mapped_name) return (new_contracts, new_mapping)
def valid_manual_design(): ''' use basic contracts to define design satisfiyng spec ''' c_a = A('a_des') c_b = B('b_des') mapping = CompositionMapping([c_a, c_b]) mapping.connect(c_a.a, c_b.a) mapping.add(c_a.b, 'b_a') mapping.add(c_b.b, 'b_b') c_ab = c_a.compose(c_b, new_name='design', composition_mapping=mapping) return c_ab
def test_manual_6_10_dc_9spec(acdc_lib): ''' Performs simple synthesis ''' spec11 = GenIsolation1D('G1') spec2 = GenIsolation2D('G2') spec3 = GenIsolation3D('G3') spec4 = GenIsolation4D('G4') spec5 = NoShortD('G5') spec6 = NoParallelShortD('G6') spec7 = IsolateEmergencyBusD('G7') spec8 = DCRightD('G8') spec1 = DCLeftD('G9') gl = StdGenerator('gl') gr = StdGenerator('gr') gtie = AC4WayBackup('gtie') ll = DCLoadContactor('ll') lr = DCLoadContactor('rl') ltie = DCTwoSideTie('ltie') contracts = [gr, gtie, ll, lr, ltie] mapping = CompositionMapping([gl] + contracts) mapping.connect(gtie.fail1, gl.fail) mapping.connect(gtie.fail4, gr.fail) mapping.connect(ltie.fail1, ll.fail1) mapping.connect(ltie.fail2, lr.fail2) mapping.connect(ll.fail2, lr.fail2) mapping.connect(lr.fail1, ll.fail1) mapping.add(gl.c, 'cs1') mapping.add(gtie.fail2, 'gt_fail2') mapping.add(gtie.fail3, 'gt_fail3') #mapping.add(gr.c, 'cs4') #mapping.add(ll.fail1, 'lfail1') #mapping.add(lr.fail1, 'lfail2') #mapping.add(gr.c, 'cs4') #mapping.add(gr.c, 'cs4') #mapping.add(gr.c, 'cs4') mapping.add(ll.c, 'c_dcl') #gtie.connect_to_port(gtie.fail1, gl.fail) #gtie.connect_to_port(gtie.fail4, gr.fail) #ltie.connect_to_port(ltie.fail1, ll.p_fail1) #ltie.connect_to_port(ltie.fail2, lr.p_fail2) spec1.connect_to_port(spec1.fail1, gl.fail) spec1.connect_to_port(spec1.fail4, gr.fail) spec1.connect_to_port(spec1.fail2, gtie.fail2) spec1.connect_to_port(spec1.fail3, gtie.fail3) spec1.connect_to_port(spec1.fail_r1, ll.fail1) spec1.connect_to_port(spec1.fail_r2, lr.fail2) spec1.connect_to_port(spec1.c1, gl.c) spec1.connect_to_port(spec1.c4, gr.c) spec1.connect_to_port(spec1.c2, gtie.c2) spec1.connect_to_port(spec1.c3, gtie.c3) spec1.connect_to_port(spec1.c5, gtie.c1) spec1.connect_to_port(spec1.c6, gtie.c2) spec1.connect_to_port(spec1.c7, ltie.c1) spec1.connect_to_port(spec1.c8, ltie.c2) spec1.connect_to_port(spec1.c9, ll.c) spec1.connect_to_port(spec1.c10, lr.c) comp = gl.compose([gr, gtie, ll, lr, ltie], composition_mapping=mapping) assert comp.is_refinement(spec1)
def run(self): ''' process one output at a time :return: ''' print('\tmultiple output clusters, processing port %s' % ', '.join(self.init_cluster)) # LOG.debug(pivot_name) cluster = {x for x in self.init_cluster} done = {x for x in self.init_cluster} # done.add(self.pivot_name) while True: passed = True for spec in self.spec_list: unknowns = set(spec.output_ports_dict.keys()) - done # LOG.debug(unknowns) # LOG.debug(cluster) if len(unknowns) == 0: # we are done break # elif len(unknowns) == 1: # # last one must go with the previous one # elem = unknowns.pop() # cluster.add(elem) # done.add(elem) else: # build composition w_spec = spec.copy() w_spec1 = spec.copy() w_spec2 = spec.copy() mapping = CompositionMapping([w_spec1, w_spec2]) # connect pivot output port for name in cluster: w_spec.connect_to_port(w_spec.output_ports_dict[name], w_spec1.output_ports_dict[name]) # connect inputs for name, in_port in w_spec.input_ports_dict.items(): w_spec.connect_to_port(in_port, w_spec1.input_ports_dict[name]) w_spec.connect_to_port(in_port, w_spec2.input_ports_dict[name]) # connect remaining outputs for name, out_port in w_spec.output_ports_dict.items(): # add explicit naming mapping.add(w_spec1.output_ports_dict[name], '1_' + name) mapping.add(w_spec2.output_ports_dict[name], '2_' + name) if name not in cluster: w_spec.connect_to_port( out_port, w_spec2.output_ports_dict[name]) # compose composition = w_spec1.compose([w_spec2], composition_mapping=mapping) # LOG.debug(composition) # LOG.debug(w_spec1) # LOG.debug(w_spec2) # add conditionals # (G(a1=a2 & b1!=b2 &...) | G(b1=b2 & a1!=a2 & ...)...) -> Spec ref. formula # left_formula = [] # for pivot in unknowns: # formula_l = [TrueFormula()] # # # formula_l.append(Negation(Globally(Equivalence(w_spec1.ports_dict[pivot].literal, # # w_spec2.ports_dict[pivot].literal, # # merge_literals=False) # # ) # # ) # # ) # # for name in unknowns - {pivot}: # formula_l.append(Globally(Equivalence(w_spec1.ports_dict[name].literal, # w_spec2.ports_dict[name].literal, # merge_literals=False) # ) # ) # # formula = reduce(lambda x, y: Conjunction(x, y, merge_literals=False), formula_l) # # left_formula.append(formula) # # formula = reduce(lambda x, y: Disjunction(x, y, merge_literals=False), left_formula) # get refinement formula verifier = NuxmvRefinementStrategy(composition) ref_formula = verifier.get_refinement_formula(w_spec) # formula = Implication(formula, ref_formula, merge_literals=False) # l_passed, trace = verify_tautology(formula, return_trace=True) l_passed, trace = verify_tautology(ref_formula, return_trace=True) # LOG.debug(l_passed) # LOG.debug(formula.generate()) if not l_passed: # build monitored vars dict monitored = {} for name in unknowns: monitored[composition.ports_dict[ '1_' + name].unique_name] = name monitored[ w_spec.ports_dict[name].unique_name] = name # LOG.debug(composition) # LOG.debug(cluster) # LOG.debug(unknowns) # LOG.debug(done) # LOG.debug(monitored) # LOG.debug(trace) diff = parse_counterexample(trace, monitored) # LOG.debug(diff) assert len(diff) > 0 # LOG.debug(diff) for elem in diff: cluster.add(elem) done.add(elem) passed &= l_passed # go out of the while loop if passed: break assert len(cluster) >= 1 for pivot in self.init_cluster: self.res_queue.put((pivot, frozenset(cluster))) self.semaphore.release() return