def _process_expr(self): self._num_vars = self._expr.degree ast = self._expr.to_cnf().to_ast() ast = LogicExpressionOracle._normalize_literal_indices( ast, self._expr.usupport) if self._optimization == 'off': self._nf = CNF(ast, num_vars=self._num_vars) else: # self._optimization == 'espresso': expr_dnf = self._expr.to_dnf() if expr_dnf.is_zero() or expr_dnf.is_one(): self._nf = CNF(('const', 0 if expr_dnf.is_zero() else 1), num_vars=self._num_vars) else: expr_dnf_m = espresso_exprs(expr_dnf)[0] expr_dnf_m_ast = LogicExpressionOracle._normalize_literal_indices( expr_dnf_m.to_ast(), expr_dnf_m.usupport) if isinstance(expr_dnf_m, AndOp): self._nf = CNF(expr_dnf_m_ast, num_vars=self._num_vars) elif isinstance(expr_dnf_m, OrOp): self._nf = DNF(expr_dnf_m_ast, num_vars=self._num_vars) else: raise AquaError( 'Unexpected espresso optimization result expr: {}'. format(expr_dnf_m))
def fbp(self, symbols, steps, context_given=set(), context_not_given=set()): symbolSet = Reaction._create_symbol_set(symbols) if not isinstance(steps, int) or steps < 0: raise ExceptionReactionSystem.InvalidNumber() if (not isinstance(context_given, set) or not isinstance(context_not_given, set)): raise ExceptionReactionSystem.InvalidContextSet() self._cg = context_given self._cng = context_not_given self._calculated_items = {} if 'time' in sys.argv: start = time.time() formula = ONE for symbol in symbolSet: formula = And(formula, self.cause(symbol)) formula = formula.to_dnf() formula = self._fbs_iterative(formula, steps) if not isinstance(formula, Atom) and formula.is_dnf(): formula = espresso_exprs(formula)[0] if 'time' in sys.argv: print(time.time() - start) return formula
def eval_espresso(self): """ Minimize this puzzle's formula using espresso :return Expr: the minimized form of this puzzle """ esp_form, = espresso_exprs(self.formula.to_dnf()) return esp_form
def minimize_rule(rule): """ Given a rule in string form 'a | b & c', return (as strings) the espresso minimized form of the rule and the support (set of variables in the minimized rule) Why don't we just return the minimized rule? There can be problems converting the minimized rule back to an expression due to recursion depth. """ f1 = expr(rule) if f1.is_one() or f1.is_zero(): reduced_rule = str(bool(f1)) return reduced_rule, set() else: f1_min, = espresso_exprs(f1.to_dnf()) return str(f1_min), set(str(x) for x in f1_min.support)
def perform_bin_expr_min(base_tokens: list, wildcard='*'): """ Perform binary expression minimization for a list of base tokens :param list base_tokens: list of base tokens that have same length. Each base token is a list of '0' or '1'. :param wildcard: the element to denote "do not care" character :returns: list of minimized tokens of '0', '1' or 'wildcard' """ if not base_tokens: return [] dim = len(base_tokens[0]) X = exprvars('x', dim) f = expr(0) # start of an OR for baseToken in base_tokens: prod = expr(1) # start of an AND for i in range(dim): if baseToken[i] == 1: prod = prod & X[i] else: prod = prod & ~X[i] f = f | prod # minimize fm, = espresso_exprs(f.to_dnf()) min_tokens = [] for s in fm.cover: min_token = [] for i in range(dim): if X[i] in s: min_token.append(1) elif ~X[i] in s: min_token.append(0) else: min_token.append(wildcard) min_tokens.append(min_token) return min_tokens
def simplify(expression): simplified_expr, = eda.espresso_exprs(eda.expr(expression).to_dnf()) return EspressoSimplifier.convert(simplified_expr)
def general_pcu_search(fInName, str4true, str4false, desiredResponses=None, subsetConstraints=None): ''' Accepts a file containing comma-separated value rows of responses and minimises according to the desiredResponses and constraints imposed ''' # = Read in the header, which creates allResponses, and order our desiredResponses to correspond to that a = time.clock() print('Started. Obtaining list of unobserveds ...') fIn = open(fInName) csv_f = csv.reader(fIn) allResponses = next(csv_f) fIn.close() # = Get subsetResponses, so that they're in order of appearance in the file we're using, they are the response outcomes we're including in the minimisation if subsetConstraints: fileIdx = [allResponses.index(sR[0]) for sR in subsetConstraints] subsetResponses = tuple(zip(*sorted(zip(fileIdx,subsetConstraints))))[1] subsetResponses = tuple(zip(*subsetResponses)) #subset responses so it's ( (resp1, resp2, ...), (val1, val2, ...) ) in order of appearance else: subsetResponses = None # = Get desiredResponses, so that they're in order of appearance in the file we're using, they are the responses species we're including in the minimisation if desiredResponses: # Sort our desiredResponses according to the order they appear in allResponses fileIdx = [allResponses.index(dR) for dR in desiredResponses] desiredResponses = list(zip(*sorted(zip(fileIdx,desiredResponses))))[1] else: if subsetResponses: # Make sure our subsetted responses aren't included desiredResponses = list(filter(lambda r: not r in subsetResponses[0], allResponses)) else: desiredResponses = allResponses boolLen = len(desiredResponses) # = Create masks desiredResponsesMask = [aR in desiredResponses for aR in allResponses] if subsetResponses: subsetMask = [r in subsetResponses[0] for r in allResponses] else: subsetMask = None # = Get all of our unobserved combinations of desiredResponses as a set of integers if subsetConstraints: unobservedInts = getUnobservedInts(fInName, desiredResponsesMask, boolLen, str4true, subsetMask, subsetResponses[1]) else: unobservedInts = getUnobservedInts(fInName, desiredResponsesMask, boolLen, str4true) # = Turn our set of unobserveds into a boolean expression = b = time.clock() print(b-a) print('List of unobserved obtained (length=' + str(len(unobservedInts)) + '). Boolean expression being generated ...') # Create our boolean variables and some useful dictionaries x, x2s, r2idx = getRespvarList2BoolvarList(desiredResponses, str4true, str4false) # Turn each integer representing unobserved into a # boolean-and into boolean expression unobservedBoolexpr = intList2boolexpr(unobservedInts, x) # = Use espresso to minimise the unobservedBoolexpr c = time.clock() print(c-b) print('Boolean expression generated. Minimisation being performed ...') boolExprMin, = espresso_exprs(unobservedBoolexpr) # Turn boolean expression into list of list of strings PCUList = boolexpr2RespvalList(boolExprMin, x2s) # = Write a file of the results d = time.clock() print(d-c) print('Minimisation complete.') # = Write the PCUs we've found to a file fOutName = fInName.split('.c')[0] if subsetConstraints: # Write the subsetMask as an integer, use as identifier for file subsetID = int(''.join(['1' if a else '0' for a in subsetMask]),2) fOutName += '_sub' + str(subsetID) # Write the desiredResponseMask as an integer, use as identifier drID = int(''.join(['1' if a else '0' for a in desiredResponsesMask]),2) fOutName += '_dr' + str(drID) + '_pcus.py' fOut = open(fOutName,'w') print('Writing ' + fOutName + ' ...') # Write a preamble about the subsetting, if needed if subsetConstraints: fOut.write('# Minimisation performed on a subset subject to the following constraints\n') for sName, sConst in subsetConstraints: fOut.write('# ') fOut.write(sName + ': ' + sConst + '\n') # First write the desiredResponses, so we know on which part the search was done fOut.write('searchedResponses = [\'' + '\',\''.join(desiredResponses) + '\']\n') # Now write each PCU fOut.write('PCUList = [\n') for PCU in PCUList: fOut.write('[\'' + '\',\''.join(PCU) + '\'],\n') fOut.write(']\n') fOut.close()
b = time.clock() print('b') # Create our boolean variables and some useful dictionaries x, x2s, r2idx = getRespvarList2BoolvarList(desiredResponses, str4true, str4false) # Turn each integer representing unobserved into a # boolean-and into boolean expression unobservedBoolexpr = intList2boolexpr(unobservedInts, x) # = Use espresso to minimise the unobservedBoolexpr c = time.clock() print('c') boolExprMin, = espresso_exprs(unobservedBoolexpr) PCUList = boolexpr2RespvalList(boolExprMin, x2s) # = Write a file of the results d = time.clock() print('d') print(d-c) print(c-b) print(b-a) # Write the PCUs we've found to a file fOutName = fInName.split('.c')[0] fOutName = fOutName + '_pcus.py'