def simplify_expr(self, terms, vec_to_symbol, symbol_to_vec): term1 = [] term2 = [] sms = symbols('X0:{}'.format(self.NB_VARS / 2)) for i in range(self.NB_VARS): #print(i) if terms[0][i] == 1: term1.append(vec_to_symbol[i]) if terms[1][i] == 1: term2.append(vec_to_symbol[i]) expr = '(' + ' & '.join(term1) + ')' + '|' + '(' + ' & '.join( term2) + ')' if (term2 == []) or (term1 == []): return [], [] simplified_expr = simplify_logic(expr, form='cnf', deep=False) action_index = np.zeros(self.NB_VARS) action = [] if (str(simplified_expr) == 'True'): print('check') if (str(simplified_expr) == 'False'): print('check') if ("|" in str(simplified_expr)) or ( str(simplified_expr) == 'True') or (str(simplified_expr) == 'False'): return [], [] else: for sy in str(simplified_expr).split('&'): action_index[symbol_to_vec[sy.strip()]] = 1 action.append(sy.strip()) return action, action_index
def old_boolean_func_from_coop_binding(world, channels, bindings): """Convert a coop binding into a boolean function""" # Can't assume all sites are unique, so we need to reconstruct a truth # table entries to pool together sites that are the same. unique = list(set(channels)) indexes = {unique[i]: i for i in range(len(unique))} # Generate all possible states all_states = [_ for _ in itertools.product([0, 1], repeat=len(bindings))] # We'll put the truth table entries that are TRUE into this is_true = [] for state in all_states: # We squash our entries down to the unique entries entry = [0] * len(unique) summed = 0 for s, c, b in zip(state, channels, bindings): # If the current column entry is true... if s: # ... make sure the corresponding entry is true entry[indexes[c]] = 1 # And add the binding strength in summed += b # This tracks what we do in the cpp class ... if summed >= len(bindings): is_true.append(entry) # This should be possible, but sympy barfs on 'E1' for some bizarre reason # names = [world.name_for_channel(u) for u in unique] # So, we use simple names and the replace at the end... names = list('abcdefghijklmnopqrstuvwxyz')[:len(unique)] sop = SOPform(names, is_true) # Now force the 0 and 1 (on and off channels) to be evaluated for i, u in enumerate(unique): # off channel if u == 0: # This is ALWAYS OFF sop = sop.subs(names[i], 0) # On channel if u == 1: # This is ALWAYS ON sop = sop.subs(names[i], 1) # Simplify the logic again sop = simplify_logic(sop) if sop == False: return "OFF" if sop == True: return "ON" text = detex(sop) # Necessary cos of the E1 problem for i, n in enumerate(names): text = text.replace(n, world.name_for_channel(unique[i])) return text
def simplifyRule(othersOR_letters, simp_form): ''' Given an expression (othersOR_letters) and a simp_form (str), simplify the expression based on the specified simp_form. Return the simplified result and the number of terms in it.''' res = str(simplify_logic(othersOR_letters, simp_form)) n = sum([len(w.split("&")) for w in \ res.replace("(", '').replace(")", '').replace(" ", '').split("|")]) return (res, n)
def toCnf(s): try: z=simplify_logic(s) x=to_cnf(z) return str(x) except: return 'this is wrong format'
def handle_else(pe): pe = simplify_logic(~pe,'dnf') # this function simplifies b to SOP form # now we do re-replacement to make it a python expression cond_str = str(pe) #print(cond_str) cond_str = cond_str.replace('&' , ' and ') cond_str = cond_str.replace('|', ' or ') cond_str = cond_str.replace('~', ' not ') return cond_str.split("or")
def convert_to_dict(node: Node) -> dict: children = OrderedDict() for node_property in node.properties: children[node_property] = convert_to_dict(node[node_property][0]) simplified = str( simplify_logic(parse_expr(''.join(to_token_sequence(node, []))), form='dnf')) if len(children) > 0: return dict(Name=node.name, Children=children, Symbol=simplified) else: return dict(Name=node.name, Symbol=simplified)
def petrick_method(mat, impl_list): symbols_tup = tuple(chr((ord('a') + i)) for i in range(len(mat))) col_mat = mat.swapaxes(0, 1) cnf = [ '(' + ' | '.join(itertools.compress(symbols_tup, col)) + ')' for col in col_mat ] mul_of_cnf = ' & '.join(cnf) sim_dnf = str(to_dnf(simplify_logic(mul_of_cnf))) min_combo = re.sub(r'[()\s]', '', sim_dnf[:sim_dnf.find('|')]).split('&') add_implicants = [impl_list[ord(ch) - ord('a')] for ch in min_combo] print(add_implicants)
def main(filename, sample_number, tree_max_size, variable_number, min_class_size): synthesized = defaultdict(lambda: set()) formula_generator = get_random_trees(sample_number, tree_max_size, variable_number) for i, tree in tqdm(list(enumerate(formula_generator))): eqnet_tree = tree.to_eqnet() simplified_str = str( simplify_logic(parse_expr(''.join(to_token_sequence( eqnet_tree, []))), form='dnf')) synthesized[simplified_str].add(tree) print("Number of formulas after filtering", sum(len(sats) for sats in synthesized.values()), file=sys.stderr) synthesized_expressions = { key: [tree.to_eqnet() for tree in trees] for key, trees in synthesized.items() } del synthesized # hope it would save some memory print("Number of classes before filtering", len(synthesized_expressions), file=sys.stderr) synthesized_expressions = { key: trees for key, trees in synthesized_expressions.items() if len(trees) >= min_class_size } print("Number of classes after filtering", len(synthesized_expressions), file=sys.stderr) def save_to_json_gz(data, filename): print("Converting to JSON", file=sys.stderr) converted_to_standard_format = {} for n, all_expressions in tqdm(data.items()): expression_dicts = [ dict(Tokens=list("whatever"), Tree=convert_to_dict(expr)) for expr in all_expressions ] converted_to_standard_format[n] = dict( Original=expression_dicts[0], Noise=expression_dicts[1:]) print("Saving", file=sys.stderr) save_result_as_gzipped_json(filename, converted_to_standard_format) save_to_json_gz(synthesized_expressions, filename + ".json.gz")
def Simplify(imps): p = ['a', 'b', 'c', 'd', 'e', 'f'] dnf = '' for imp in imps: imp_s = '' for i in range(0, 6): if (imp[i] == '0'): imp_s += ' & ' + '~' + p[i] if (imp[i] == '1'): imp_s += ' & ' + p[i] if (imp[i] == '~'): imp_s += '' dnf += '(' + imp_s[3:] + ') | ' dnf = dnf[0:-3] dnf = str(simplify_logic(dnf, 'dnf')) print(dnf)
def simple_boolean(self): """ Function returning the string representation of the Conjunctive Normal Form of an STL Formula """ if isinstance(self.tree, DTLearn.Leaf): return "True" simplified = str( simplify_logic(expr=self.toSimply(self.tree), form='cnf')) simplified = simplified.replace("~", "\\neg ") simplified = simplified.replace("|", "\\vee") simplified = simplified.replace("&", "\wedge") for predicate in reversed(sorted(self.dictnodestr.keys())): simplified = simplified.replace(predicate, self.dictnodestr[predicate]) return simplified
def simplify(ind: gp.PrimitiveTree, pset: gp.PrimitiveSet, symbol_map=None): """ Compile the primitive tree into a (possibly simplified) symbolic expression :param ind: a primitive tree :param pset: a primitive set :param symbol_map: map each function name in the primitive set to a symbolic version. If ``None``, use a default one. :return: a (simplified) symbol expression corresponding to the given PrimitiveTree """ assert isinstance(ind, gp.PrimitiveTree) from sympy.logic import simplify_logic if symbol_map is None: symbol_map = { operator.and_.__name__: sp.And, operator.or_.__name__: sp.Or, operator.not_.__name__: sp.Not } operand_stack = [] r = None # the elements in gp.PrimitiveTree in fact represents a prefix expression for node in reversed(ind): if isinstance(node, gp.Ephemeral): # a randomly generated constant operand_stack.append(node.value) elif isinstance(node, gp.Terminal): # whether this terminal represents an input? if node.value in pset.arguments: operand_stack.append(sp.Symbol(node.value)) else: # just a constant operand_stack.append(node.value) elif isinstance(node, gp.Primitive): # function sym_func = symbol_map[ node.name] # get the symbolic version of this function try: args = [operand_stack.pop() for _ in range(node.arity)] r = sym_func(*args) r = simplify_logic(r) operand_stack.append(r) except AttributeError as err: print(err) print(sym_func) print(args) print(type(arg) for arg in args) else: raise RuntimeError( 'Not recognized node type in the primitive tree: {}'.format( type(node))) return operand_stack.pop()
def _get_formula(truth_assignments, propositions): dnfs = [] props = dict([(p, symbols(p)) for p in propositions]) for truth_assignment in truth_assignments: dnf = [] for p in props: if p in truth_assignment: dnf.append(props[p]) else: dnf.append(Not(props[p])) dnfs.append(And(*dnf)) formula = Or(*dnfs) formula = simplify_logic(formula, form='dnf') formula = str(formula).replace('(', '').replace(')', '').replace( '~', '!').replace(' ', '') return formula
def fun_simplifyLogic(self,str_symbols,str_formula): import sympy from sympy import symbols from sympy import sympify from sympy.logic import simplify_logic from pyparsing import nestedExpr sympy.var(str_symbols) # use sympy to make the logic symbols into symbolic logic variables simplified_logic_equation = simplify_logic(sympify(str_formula)) # and use sympy to simplify the equation print('Simplified formula: '+str(simplified_logic_equation)) simplified_logic_equation = '('+str(simplified_logic_equation)+')' # needs to be surrounded by brackets so pyparsing can parse it into a list lst_nested_logic_statement = nestedExpr('(',')').parseString(simplified_logic_equation).asList() # use pyparsing to parse the simplified logic equation into a list return lst_nested_logic_statement
def convert_to_SOP(tt , carry_cond): cond_str = (astunparse.unparse(tt))[:-1] # [:-1] for removing \n which occurs as the last character # these replacements for converting the string to sympy logical expression # repalacing and with & , or with | , not with ~ cond_str = cond_str.replace("and" ,"&") cond_str = cond_str.replace("or" , "|") cond_str = cond_str.replace("not", "~") pe = parse_expr(cond_str) # this function helps to convert the arg. string to sympy expression pe = ~carry_cond & pe # use of carry_cond as explained above pe = simplify_logic(pe,'dnf') # this function simplifies pe to SOP form # dnf stands for disjunctive normal form other name for SOP form # now we do re-replacement to make it a python expression cond_str = str(pe) #print(cond_str) cond_str = cond_str.replace('&' , ' and ') cond_str = cond_str.replace('|', ' or ') cond_str = cond_str.replace('~', ' not ') return pe , cond_str.split("or")
def convert_to_dnf(frml): # frml = to_dnf(frml, force=True).replace(" ","") frml = frml.replace("^", "~") sub_frml = get_sub_formulas(frml, P="P", add_prefix="Q") for single_sub_frml_index in range(len(sub_frml)): sub_frml[single_sub_frml_index] = remove_iff_single_frml( sub_frml[single_sub_frml_index][1:-1]) print(sub_frml[single_sub_frml_index]) sub_frml[single_sub_frml_index] = str( to_dnf(sub_frml[single_sub_frml_index], force=True)).replace(" ", "") for i in range(len(sub_frml)): current_index = sub_frml[i].find("P", 0) while current_index != -1: end_index = sub_frml[i].find("Q", current_index + 1) to_switch_index = int(sub_frml[i][current_index + 1:end_index]) - 1 sub_frml[i] = sub_frml[i].replace( "P" + str(to_switch_index + 1) + "Q", sub_frml[to_switch_index]) current_index = sub_frml[i].find("P", current_index + 1) return simplify_logic(str(to_dnf(sub_frml[-1], force=True)).replace(" ", ""), force=True)
def _process_expr(self): self._num_vars = len(self._expr.binary_symbols) self._lit_to_var = [None] + sorted(self._expr.binary_symbols, key=str) self._var_to_lit = dict( zip(self._lit_to_var[1:], range(1, self._num_vars + 1))) if self._optimization or (not is_cnf(self._expr) and not is_dnf(self._expr)): expr = simplify_logic(self._expr) else: expr = self._expr if isinstance(expr, BooleanTrue): ast = 'const', 1 elif isinstance(expr, BooleanFalse): ast = 'const', 0 else: ast = get_ast(self._var_to_lit, expr) if ast[0] == 'or': self._nf = DNF(ast, num_vars=self._num_vars) else: self._nf = CNF(ast, num_vars=self._num_vars)
def simplified(self): return simplify_logic(parse_expr(self.get_token_string()))
print("processing iteration ", iteration) f.write(str(iteration)) f.write(';') f.write(str(dic[iteration][0])) f.write(';') f.write(dic[iteration][1]) f.write(';') f.write(dic[iteration][2]) f.write(';') try: f.write(str(simplify_logic(expr=dic[iteration][2], form='cnf'))) f.write(';') except AttributeError: f.write('True;') f.write(str((tim / 1000) * iteration)) f.write('\n') f.write('\n\n') for entry in dic2: f.write(entry) f.write(';') f.write(dic2[entry]) f.write('\n')
from sympy.logic import simplify_logic from sympy.abc import x, y, z from sympy import S from sympy.logic import SOPform minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]] SOPform(['w','x','y','z'], minterms, dontcares) from sympy.logic import POSform minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]] POSform(['w','x','y','z'], minterms, dontcares) expr = '(~x & y & ~z) | ( ~x & ~y & ~z)' simplify_logic(expr) S(expr) simplify_logic(_)
from typing import List, Dict from sympy import * from sympy.logic.boolalg import to_cnf from sympy.abc import A, B, D from sympy.logic.inference import satisfiable from sympy import Symbol from sympy.logic import simplify_logic x = Symbol('x') y = Symbol('y') z = Symbol('z') cnf_1 = simplify_logic(to_cnf(x>> ~y|z)) cnf_2 = simplify_logic(to_cnf(~(x | y) >> z)) print(satisfiable(cnf_1 & cnf_2))
def print_stats(): print("Generated None %s times, duplicates %s times" % (num_times_returned_no_tree, num_times_returned_duplicate)) print("Generated %s unique expressions (%s in total)" % (len(synthesized_expressions), sum(len(e[0]) for e in synthesized_expressions.values()))) max_num_elements = 500 # max num of expressions per semantically equivalent set to sample (reservoir sampling) tree_generator = generate_all_trees(Node('Start', ('child', ))) for i, tree in tqdm(enumerate(tree_generator)): if i % 5000 == 4999: print_stats() tokens = to_token_sequence(tree, []) expression = simplify_logic(parse_expr(''.join(tokens)), form='dnf') expression_str = str(expression) all_elements, count = synthesized_expressions[expression_str] if len(all_elements) < max_num_elements: # Reservoir sampling all_elements.append((tokens, tree)) else: idx = random.randint(0, count) if idx < max_num_elements: all_elements[idx] = tokens, tree synthesized_expressions[expression_str] = all_elements, count + 1 print_stats() def save_to_json_gz(data, filename): converted_to_standard_format = {} for n, all_expressions in data.items(): all_expressions = all_expressions[0]
print(solve(a) == solve(b)) # True a = ~ (x & y) b = ~x | ~y #print(solve(a)) #print(solve(b)) #print(solve(a) == solve(b)) # True x, y, z, t = symbols('x y z t') b = (~x & ~y & ~z) | ( ~x & ~y & z) print(simplify_logic(b)) a = ~ (x & y) b = ~x | ~y print(simplify_logic(a)==simplify_logic(b))
def canalizationEffect(modeltext, canalizingNodeDic): ''' :param modeltext: Network model :param canalizingNodeDic: Canalizing node dictionary :return: modeltext: residual network canalizedStateVectorDic: canalized state vector dictionary stepCanalizedStateVectorList: canalized state vector list according to the step allStateVectorDic: all state vector dictionary ''' # Strip whitespace modeltext = modeltext.strip() # Replace the logics with symbols modeltext = re.sub(r"\band\b", "&", modeltext) modeltext = re.sub(r"\bor\b", "|", modeltext) modeltext = re.sub(r"\bnot\b", "~", modeltext) # Split text lines modeltextLine = modeltext.splitlines() # Get all nodes allNodeList = [] for line in modeltextLine: allNodeList += re.findall(r'\w+', line) # Deduplication allNodeList = [ x for i, x in enumerate(allNodeList) if i == allNodeList.index(x) ] # Create a all state vector dictionary with no values allStateVectorDic = {} for node in allNodeList: allStateVectorDic[node] = "" # Recursive process canalizedStateVectorDic = {} stepCanalizedStateVectorList = [] process = True while process: # Update canalizing node list if canalizingNodeDic: for node in canalizingNodeDic: allStateVectorDic[node] = canalizingNodeDic[node] # Append canalized state vector list according to the step stepCanalizedStateVectorList.append(canalizingNodeDic) # Merge two dictionaries canalizedStateVectorDic = dict(**canalizedStateVectorDic, **canalizingNodeDic) # Get canalizing node list canalizingNodeList = list(canalizingNodeDic.keys()) # Split text lines modeltextLine = modeltext.splitlines() # Apply the canalization effect newCanalizingNodeDic = {} newModeltext = "" for line in modeltextLine: str1 = line.split("=") stateVariable = str1[0].strip() BooleanExpression = str1[1].strip() if not stateVariable in canalizingNodeList: for fixedNode in canalizingNodeDic: BooleanExpression = re.sub( r"\b" + fixedNode + r"\b", str(canalizingNodeDic[fixedNode]).lower(), BooleanExpression) simplifiedExpression = simplify_logic(BooleanExpression) if simplifiedExpression in [True]: newCanalizingNodeDic[ stateVariable] = simplifiedExpression else: if not simplifiedExpression: simplifiedExpression = stateVariable newModeltext += stateVariable + " = " + str( simplifiedExpression) + "\n" modeltext = newModeltext canalizingNodeDic = newCanalizingNodeDic else: break # Ordering canalizedStateVectorDic = dict( sorted(canalizedStateVectorDic.items(), reverse=False)) allStateVectorDic = dict(sorted(allStateVectorDic.items(), reverse=False)) # Node with value is False or logic additionalSolutionList = [] for node in allStateVectorDic: if allStateVectorDic[node] == "": additionalSolutionList.append(node) # If the canalizing node is not included in the network, subtract it newCanalizedStateVectorDic = {} for canalizedNode in canalizedStateVectorDic: if canalizedNode in allNodeList: newCanalizedStateVectorDic[ canalizedNode] = canalizedStateVectorDic[canalizedNode] return modeltext, additionalSolutionList, len(newCanalizedStateVectorDic)
regular = pre_cnf_to_cnf(res, props) print(regular) flist = build_formula_list(_input) print("f list") for f in flist: print(f) basis = build_res_set(flist, props) print("f set") for s in basis: for e in s: print(e, end=" ") print("\n") #attempt = resolution(basis, props) #print(attempt) var1 = "~(p & ~ q) | ~(~a & ~t)" print("var1 to cnf: %s" % (to_cnf(var1))) var1 = "r & (p | q)" print("var1 simp: %s" % (simplify_logic(var1))) var2 = "~u | (t | (~s & p))" print("var1 to cnf: %s" % (to_cnf(var2))) var2 = "~p | (q & r)" print("var1 simp: %s" % (simplify_logic(var2))) if a | b == b | a: print("yes they are!")
def simplify(self): self.expr = simplify_logic(self.expr)
def _compute_fol_formula(truth_table: np.array, predictions: np.array, feature_names: List[str], nonpruned_positions: List[np.array], simplify: bool = True, fan_in: int = None) -> str: """ Compute First Order Logic formulas. :param simplify: :param truth_table: input truth table. :param predictions: output predictions for the current neuron. :param feature_names: name of the input features. :param nonpruned_positions: position of non-pruned weights :param fan_in: :return: first-order logic formula """ # select the rows of the input truth table for which the output is true X = truth_table[np.nonzero(predictions)] # if the output is never true, then return false if np.shape(X)[0] == 0: return "False" # if the output is never false, then return true if np.shape(X)[0] == np.shape(truth_table)[0]: return "True" # filter common rows X, indices = np.unique(X, axis=0, return_index=True) # compute the formula formula = '' n_rows, n_features = X.shape for i in range(n_rows): # if the formula is not empty, start appending an additional term if formula != '': formula = formula + "|" # open the bracket formula = formula + "(" for j in range(n_features): # get the name (column index) of the feature feature_name = feature_names[nonpruned_positions[j]] # if the feature is not active, # then the corresponding predicate is false, # then we need to negate the feature if X[i][j] == 0: formula += "~" # append the feature name formula += feature_name + "&" formula = formula[:-1] + ')' # replace "not True" with "False" and vice versa formula = formula.replace('~(True)', '(False)') formula = formula.replace('~(False)', '(True)') # simplify formula try: if eval(formula) == True or eval(formula) == False: formula = str(eval(formula)) assert not formula == "-1" and not formula == "-2", "Error in evaluating formulas" except: formula = simplify_logic(formula, force=simplify) return str(formula)
def simplifylogic(): from sympy.logic import simplify_logic from sympy.abc import x, y, z from sympy import S b = input("Enter a expression to simplify using logic") print(simplify_logic(b))
from sympy.logic import simplify_logic from sympy.abc import x, y, z from sympy import S from sympy.logic import SOPform minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]] SOPform(['w', 'x', 'y', 'z'], minterms, dontcares) from sympy.logic import POSform minterms = [[0, 0, 0, 1], [0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]] dontcares = [[1, 1, 0, 1], [0, 0, 0, 0], [0, 0, 1, 0]] POSform(['w', 'x', 'y', 'z'], minterms, dontcares) expr = '(~x & y & ~z) | ( ~x & ~y & ~z)' simplify_logic(expr) S(expr) simplify_logic(_)
print(to_cnf(~(A | B) | D)) print(to_cnf((A | B) & (A | ~A), True)) #dnf from sympy.logic.boolalg import to_dnf from sympy.abc import A, B, C print(to_dnf(B & (A | C))) print(to_dnf((A & B) | (A & ~B) | (B & C) | (~B & C), True)) #to check cnf and dnf from sympy.logic.boolalg import is_cnf from sympy.abc import A, B, C from sympy.logic.boolalg import is_dnf from sympy.abc import A, B, C print(is_cnf(A | B | C)) print(is_cnf((A & B) | C)) print(is_dnf(A | B | C)) print(is_dnf(A & (B | C))) #simplify logic from sympy.logic import simplify_logic from sympy.abc import x, y, z from sympy import S b = (~x & ~y & ~z) | (~x & ~y & z) print(simplify_logic(b))