def manage_selection_list(local_package, selection_list): res = [ package.manage_selection(local_package, *selection) for selection in selection_list ] if (len(res) is 0): return local_package._name else: return gzl.And(local_package._name, *res)
def _get_spc_depend_element(self, parse_tree): if parse_tree[1][0].name == "choice": subs = tuple( self._get_spc_depend_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "depend_element"))) C = package.manage_node_choice(parse_tree[1]) return C(subs) if parse_tree[1][0].name == "condition": subs = tuple( self._get_spc_depend_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "depend_element"))) return gzl.Implies(self._get_spc_condition(parse_tree[1]), gzl.And(subs) if (len(subs) > 1) else subs[0]) if parse_tree[1][1] == "(": # inner subs = tuple( self._get_spc_depend_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "depend_element"))) return gzl.And(subs) if (len(subs) > 1) else subs[0] # otherwise, it is an atom neg = identity if parse_tree[1][1] == "!": # not atom if parse_tree[2][1] == "!": neg = gzl.Not atom = parse_tree[3][1] i = 4 else: neg = gzl.Not atom = parse_tree[2][1] i = 3 else: atom = parse_tree[1][1] i = 2 dependencies = self._repo.get_atom(atom) self._dep_atom.add(atom) self._dep_package.update(dependencies) selection_list = [ self._get_spc_selection(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "selection")) ] #print("SELECTION in {} for {}: {}".format(self._name, atom, [('!' if(selection_type is gzl.Not) else 'id', use, default, '?' if(suffix is gzl.Implies) else '<=>') for selection_type, use, default, suffix in selection_list])) return neg( gzl.Or([ package.manage_selection_list( self._repo.get_package(local_cpv), selection_list) for local_cpv in dependencies ]))
def test_solve(self, cps): z3_translator = gzl.toZ3Visitor().visit z3_solver = z3.Solver() z3_solver.add( z3_translator( gzl.And([gzl.Or(self._repo.get_atom(cp)) for cp in cps]))) for cp_, c in self._fm: z3_solver.add(z3_translator(c)) if (z3_solver.check() == z3.sat): self._solution = z3_solver.model() else: self._solution = None
def get_spc(self): """Returns the feature model of this package. Note that a package's feature model always has the form "cpv => (REQUIRED_USE and DEPEND and BDEPEND and RDEPEND and PDEPEND )" """ self.compute_spc() res = frozenset().union((el[0] for el in self._spc_required_use), (el[0] for el in self._spc_depend), (el[0] for el in self._spc_bdepend), (el[0] for el in self._spc_rdepend), (el[0] for el in self._spc_pdepend)) return gzl.Implies(self._name, gzl.And(res))
def _get_spc_require_element(self, parse_tree): if parse_tree[1][0].name == "choice": subs = tuple( self._get_spc_require_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "require_element"))) C = package.manage_node_choice(parse_tree[1]) return C(subs) if parse_tree[1][0].name == "condition": subs = tuple( self._get_spc_require_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "require_element"))) return gzl.Implies(self._get_spc_condition(parse_tree[1]), gzl.And(subs) if (len(subs) > 1) else subs[0]) if parse_tree[1][1] == "(": # inner subs = tuple( self._get_spc_require_element(el) for el in parse_tree if ((len(el) > 0) and (el[0].name == "require_element"))) return gzl.And(subs) if (len(subs) > 1) else subs[0] # otherwise, it is a use flag neg = parse_tree[1][1] == "!" if neg: return gzl.Not(self.get_feature(parse_tree[2][1])) else: return self.get_feature(parse_tree[1][1])
def _add(self, depend): """ This method creates a dummy package with the intput constraint as its dependency, and preprocesses this new package Parameters: depend (str with the DEPEND syntax): the added constraint """ dummy_package = self._repo.get_dummy_package(name='input', depend=depend) dummy_package.compute_spc() constraint = self._z3_translator.visit( gzl.And(tuple(el[0] for el in dummy_package._spc_depend))) return self._manage_constraint(constraint, dummy_package._name, dep_solver.kind.cpv)
def get_cp(self, cp): """ Returns the SLOT constraint corresponding to the input cp. Parameter: cp (string): the category/package for which we want the SLOT constraint """ res = self._cps.get(cp) if (res is None): packages = [self.get_package(cpv) for cpv in self.get_atom(cp)] slots = dictlist() for p in packages: slots.add(p._slot, p._name) res = [ gzl.Conflict(names) for names in slots.values() if (len(names) > 1) ] if (len(res) > 1): res = gzl.And(res) elif (len(res) is 1): res = res[0] else: res = True self._cps[cp] = res return res
def write_fm(self, fname): c = gzl.And(*tuple(el[1] for el in self._fm)) converter = analyser.toCNFConverter() converter.convert(c) with open(fname, 'w') as f: f.write(str(converter))
def print_fm(self): c = gzl.And(*tuple(el[1] for el in self._fm)) converter = analyser.toCNFConverter() converter.convert(c) print(str(converter))