def test4(): x = SyExp("x", []) y = SyExp("d1", []) c = CegarQBF(x, y) print("status: ", c.any_hope()) assert c
def test_satproxy_2(): spec = SyExp("and", [SyExp("x", []), SyExp("y", [])]) syn_exp = SyExp("x", []) sp = SatProxy(spec, syn_exp) a, b = sp.solve() print(a) print(b)
def synthesize(self): # print("count_dict: ", self.G.count_dict) k = 0 suc = False all_ct = self.G.count_dict[self.G.start] # print("all_ct:", all_ct) delta_stats = {} while k < all_ct: self.partial_tree = SyExp(self.G.start, []) status = self.search(self.G.start, k) if status: suc = True break delta = self.countNT(self.G.start, self.partial_tree) if delta not in delta_stats: delta_stats[delta] = 0 delta_stats[delta] += 1 # print("k:", k) # print("partial_tree: ", self.partial_tree) # print("delta:", delta) k += delta if suc: print("delta stats:", delta_stats) print("k=", k, "solution is found: ", self.partial_tree.to_py()) else: print("No solution exists!")
def test10(): x = SyExp("x", []) y = SyExp("y", []) e = SyExp("and", [x, y]) c = CegarQBF(e, y) status = c.any_hope() print("status: ", status) assert status is False
def test6(): x = SyExp("x", []) y = SyExp("y", []) e1 = SyExp("or", [x, y]) e2 = SyExp("and", [x, SyExp("d1", [])]) c = CegarQBF(e1, e2) status = c.any_hope() print("status: ", status) assert status is False
def test_simplify_bdd(): x = SyExp("x", []) y = SyExp("y", []) e1 = SyExp("or", [x, y]) e2 = SyExp("and", [SyExp("x", []), SyExp("d1", [])]) e3 = SyExp("eqv", [e1, e2]) print("before e3: ", e3.show2(0)) e4 = e3.simplify_bdd() print("after e3: ", e4.show2(0))
def __init__(self, spec, syn_exp): assert isinstance(spec, SyExp) assert isinstance(syn_exp, SyExp) self.spec = spec self.syn_exp = syn_exp #self.spec_tseitin_cnf = None #self.syn_exp_tseitin_cnf = None eqv = SyExp("eqv", [self.spec, self.syn_exp]) self.overall_exp = eqv.simplify_bdd() self.overall_cnf = TseitinCNF(self.overall_exp, 1)
def forward(self, env, mem, use_random, eps=0.05): spectree = env.specsample.spectree if env.t == 0: attention = self.gen_attention(mem, env) # get attention self.state = self.tree_encoder(mem, attention, env) # generate overall state value = self.value_net(self.state) # get state value self.nll = 0.0 syexp = env.expand_ls.pop(0) cfg_mapping = env.get_cfg_mapping() act_space = cfg_mapping[syexp.app][ 1:] # get all index except for the node itself avail_act_embedding = mem[act_space] if len(avail_act_embedding.shape) == 1: avail_act_embedding = avail_act_embedding.unsqueeze(0) # # stack the embeddings of currently available nodes # act_space = spectree.grammar.productions[syexp.app] # e.g. [['and', 'depth1', 'depth1'], ['LN29']] # avail_act_embedding = [] # for avail_act in act_space: # nodename = avail_act[0] # if nodename in constants.OP_NAME2IND: # ind = Variable(torch.LongTensor([constants.OP_NAME2IND[nodename]]), requires_grad=False) # avail_act_embedding.append(self.op_embedding(ind)) # else: # avail_act_embedding.append(mem[spectree.nodename2ind[nodename], :].unsqueeze(0)) # avail_act_embedding = torch.cat(avail_act_embedding, dim=0) # choose node to add act = self.choose_action(self.state, avail_act_embedding, use_random, eps) act_embedding = torch.index_select(avail_act_embedding, 0, act) # call RewardRedistributionLSTM for prediction if cmd_args.use_rudder: t = Variable(torch.Tensor([env.t]), requires_grad=False) rr_lstm_input = torch.cat([self.state.detach(), act_embedding, t], dim=-1) self.rr_lstm(rr_lstm_input) self.update_state(act_embedding) # expand the syexp prod_rule = spectree.grammar.productions[ syexp.app] # e.g. [['and', 'depth1', 'depth1'], ['LN29']] act_ind = act.data.cpu()[0] syexp.app = prod_rule[act_ind][0] # e.g syexp.app='and' arg_name_ls = prod_rule[act_ind][1:] syexp.args = [SyExp(arg_name, []) for arg_name in arg_name_ls ] # e.g. syexp.args=[SyExp('depth1', []), ...] # push to stack for pre-order visit env.expand_ls = syexp.args[::-1] + env.expand_ls return self.nll, value
def test0(): x = SyExp("x", []) y = SyExp("y", []) e1 = SyExp("and", [x, y]) t = TseitinCNF(e1, 1) vids, names = t.get_primitive_vars() print(vids) print(names) cnf = t.cnfs cnf.append([t.get_overall_id()]) status = qbf([1], cnf) print(e1, cnf) print("qbf: ", status) assert status is False
def test1b(): x = SyExp("x", []) y = SyExp("y", []) e1 = SyExp("and", [x, y]) e2 = SyExp("eqv", [e1, x]) t = TseitinCNF(e2, 1) vids, names = t.get_primitive_vars() print(vids) print(names) cnf = t.cnfs cnf.append([t.get_overall_id()]) print(e2, cnf) # forall x, x /\y === x status = qbf([2], cnf) print("qbf: ", status) assert status is True
def test11(): x = SyExp("x", []) y = SyExp("y", []) z = SyExp("z", []) d1 = SyExp("depth1", []) e1 = SyExp("or", [x, SyExp("and", [y, z])]) e2 = SyExp("not", [SyExp("not", [y])]) c = CegarQBF(e1, e2) status = c.any_hope() print("status: ", status) assert status is False
def __init__(self, spec, partial_tree): # extract forall vars (assume all of which are in spec) vnames = spec.get_vars() # print("vnames:", vnames) ptree = deepcopy(partial_tree) ptree, sid = rename_nonT(ptree) eqv = SyExp("eqv", [spec, ptree]) eqv = eqv.simplify_bdd() # print("eqv:", eqv.show2(0)) # get cnf t = TseitinCNF(eqv) n2v = t.get_name2var() # print("names:", n2v) self.v_forall = [n2v[name] for name in vnames] cnf = t.cnfs cnf.append( [t.get_overall_id()] ) self.cnf = cnf
def __init__(self, specsample): """ specsample: a SpecSample object containing the SpecTree of the original program """ self.specsample = specsample self.pg = specsample.pg self.t = 0 self.generated_tree = SyExp('Start', []) self.expand_ls = [self.generated_tree]
def test_simplify(): spec = get_def() syn_exp = SyExp("and", [SyExp("LN231", []), SyExp("LN218", [])]) overall = SyExp("eqv", [spec, syn_exp]) print("overall:", overall) x = overall.simplify_bdd() print("after simplify:", x)
def recursive_decode(self, syexp, spectree, mem, use_random, eps): """ Completely expand a SyExp object according to the production rule provided by the grammar of spectree syexp: a SyExp object to be expanded spectree: SpecTree object containing CFG object (grammar) and other info about the original program mem: external memory, i.e. embedding table of vars and ops use_random: eps: """ # if SyExp is terminal node then return if syexp.app in spectree.grammar.terminals: return # stack the embeddings of currently available nodes act_space = spectree.grammar.productions[ syexp.app] # e.g. [['and', 'depth1', 'depth1'], ['LN29']] avail_act_embedding = [] for avail_act in act_space: nodename = avail_act[0] if nodename in constants.OP_NAME2IND: ind = Variable(torch.LongTensor( [constants.OP_NAME2IND[nodename]]), requires_grad=False) avail_act_embedding.append(self.op_embedding(ind)) else: avail_act_embedding.append( mem[spectree.nodename2ind[nodename], :].unsqueeze(0)) avail_act_embedding = torch.cat(avail_act_embedding, dim=0) # choose node to add act = self.choose_action(self.state, avail_act_embedding, use_random, eps) self.update_state(torch.index_select(avail_act_embedding, 0, act)) # expand the syexp act_ind = act.data.cpu()[0] syexp.app = act_space[act_ind][0] # e.g syexp.app='and' arg_name_ls = act_space[act_ind][1:] syexp.args = [SyExp(arg_name, []) for arg_name in arg_name_ls ] # e.g. syexp.args=[SyExp('depth1', []), ...] # recursively expand the child nodes for child_syexp in syexp.args: self.recursive_decode(child_syexp, spectree, mem, use_random, eps)
def rename_nonT(sexp, sid=0): if sexp.args == []: if sexp.app in nonT: return SyExp(sexp.app + ("-%d" % sid),[]), sid+1 else: return sexp, sid assert sexp.app not in nonT args = [] for x in sexp.args: a, sid = rename_nonT(x, sid) args.append(a) sexp.args = args return sexp, sid
def search(self, nonT, from_k): # evaluate the K-th program of (non-)terminal nonT if nonT in self.G.terminals: return self.any_hope() status, node = self.partial_tree.dfs_find(nonT) if not status: print("nonT:", nonT) print("pt:", self.partial_tree) assert status k = from_k all_ct = self.G.count_dict[nonT] assert k < all_ct if not self.any_hope(): # no need to expand return False # decide which rule to pick res = 0 rules = self.G.productions[nonT] pick_rule = None index = k for r in rules: tmp = 1 for i in range(1, len(r)): tmp *= self.G.count_dict[r[i]] if index >= tmp: index -= tmp else: pick_rule = r break # print("search: nonT=", nonT, "picke_rule:", pick_rule) assert pick_rule # print("\n\nbefore replacing: ", self.partial_tree) node.app = pick_rule[0] node.args = [] if len(pick_rule) > 1: for i in range(1, len(pick_rule)): node.args.append(SyExp(pick_rule[i], [])) # print("replaced ", nonT, " with ", pick_rule) # print("partial tree:", self.partial_tree) # print("\n\n") return self.search_in_rule(pick_rule, index)
def test_satproxy_1(): #spec = get_def() #t = TseitinCNF(spec, 1) #t.show() spec = SyExp("and", [SyExp("LN231", []), SyExp("LN218", [])]) #syn_exp = SyExp("and", [ SyExp("LN231", []), SyExp("LN218", []) ] ) syn_exp = SyExp("xor", [SyExp("LN231", []), SyExp("LN240", [])]) sp = SatProxy(spec, syn_exp) a, b = sp.solve() print(a) print(b)
def test9(): x = SyExp("x", []) y = SyExp("y", []) z = SyExp("z", []) e1 = SyExp("or", [x, SyExp("and", [y, z])]) # e2 = SyExp("and", [SyExp("and", [y,y]), SyExp("and", [y,y])]) # e1 = SyExp("or", [x,y] ) e2 = SyExp("and", [y, y]) c = CegarQBF(e1, e2) status = c.any_hope() print("status: ", status) assert status is False
def __init__(self, sy_exp): self.productions = dict() self.nonTerminals = set() self.terminals = set() self.start = "Start" # print("syexp: ", sy_exp) for se in sy_exp.get_args(): assert len(se.args) == 2 nt = se.get_app() self.nonTerminals.add( nt ) typ = se.args[0] # type information, useless for now # print("typ: ", typ) derivations = [] if se.args[1].app != "": derivations.append( SyExp(se.args[1].app, []) ) derivations.extend( se.args[1].get_args() ) # print("app: ", se.args[1].app, len(se.args[1].app)) res = [] for prod in derivations: # print("prod:", prod) #print("prod.app = ", prod.app) #assert prod.app in ["and", "or", "xor", "not"] body = [prod.app] + [ x.app for x in prod.args] res.append( body ) for x in body: self.terminals.add(x) self.productions[nt] = res for x in self.nonTerminals: if x in self.terminals: self.terminals.remove(x) self.count_dict = {} self.compute_count(self.start)
def interpret(self, cl): if len(cl) == 0: return SyExp("empty",[]) if len(cl) == 1: x = cl[0] assert self.exists_id( abs(x) ) if x > 0: return self.id_to_exp[ x ] else: exp = self.id_to_exp[ -x ] return SyExp("not", [exp]) neg = [] pos = [] for x in cl: assert self.exists_id( abs(x) ) if x > 0: pos.append(x) else: neg.append(-x) if pos == []: return SyExp("at lest one should be false",[ self.id_to_exp[x] for x in neg ] ) if neg == []: return SyExp("at least one should be true" ,[ self.id_to_exp[x] for x in pos ]) neg_exp = None pos_exp = None if len(neg) == 1: neg_exp = self.id_to_exp[ neg[0] ] else: neg_exp = SyExp("AND",[ self.id_to_exp[x] for x in neg ] ) if len(pos) == 1: pos_exp = self.id_to_exp[ pos[0] ] else: pos_exp = SyExp("OR" ,[ self.id_to_exp[x] for x in pos ]) return SyExp("=>", [neg_exp, pos_exp] )
def test2b(): x = SyExp("x", []) y = SyExp("y", []) e1 = SyExp("and", [x, y]) e2 = SyExp("or", [x, SyExp("not", [y])]) e3 = SyExp("eqv", [e1, e2]) t = TseitinCNF(e3, 1) vids, names = t.get_primitive_vars() print(vids) print(names) cnf = t.cnfs cnf.append([t.get_overall_id()]) status = qbf([1], cnf) print(e3, cnf) print("qbf: ", status) assert status is True status = qbf([1, 2], cnf) print("qbf: ", status) assert status is False
def test_satproxy_3(): spec = SyExp( "or", [SyExp("x", []), SyExp("and", [SyExp("y", []), SyExp("z", [])])]) syn_exp = SyExp("or", [ SyExp("or", [SyExp("y", []), SyExp("z", [])]), SyExp("and", [SyExp("y", []), SyExp("z", [])]) ]) proxy = SatProxy(spec, syn_exp) status, ce_model = proxy.find_counter_example() # a,b = proxy.solve() # print(a) # print(b) print("status:", status) print("ce_model:", ce_model)
def deepcopy(sexp): res = SyExp(sexp.app, []) for x in sexp.args: res.args.append( deepcopy(x) ) return res
class QBFSearch(object): def __init__(self, spec, grammar): self.spec = spec self.G = grammar self.partial_tree = SyExp(grammar.start, []) self.done = False def any_hope(self): checker = CegarQBF(self.spec, self.partial_tree) status = checker.any_hope() return status def countNT(self, nonT, sexp): # just count the number of cominbations of nonT if nonT == sexp.app: return self.G.count_dict[nonT] rules = self.G.productions[nonT] pick_rule = None for r in rules: if sexp.app == r[0]: pick_rule = r break if pick_rule is None: print("countNT cannot find picked rule!! nonT:", nonT, " sexp:", sexp) res = 1 for i in range(1, len(pick_rule)): res *= self.countNT(pick_rule[i], sexp.args[i - 1]) return res def search_in_rule(self, pick_rule, index): # decide the part of the body to fill if len(pick_rule) == 1: return self.search(pick_rule[0], 0) bases = [1] cts = [] n = len(pick_rule) for i in range(1, n): bases.append(self.G.count_dict[pick_rule[i]]) for i in range(n): tmp = 1 for j in range(i + 1, n): tmp *= bases[j] cts.append(tmp) indices = [] # the index for each part of the body c = index for i in range(n): indices.append(c // cts[i]) c = c % cts[i] assert indices[0] == 0 for i in range(1, n): nonT = pick_rule[i] k = indices[i] status = self.search(nonT, k) if not status: return False return True def search(self, nonT, from_k): # evaluate the K-th program of (non-)terminal nonT if nonT in self.G.terminals: return self.any_hope() status, node = self.partial_tree.dfs_find(nonT) if not status: print("nonT:", nonT) print("pt:", self.partial_tree) assert status k = from_k all_ct = self.G.count_dict[nonT] assert k < all_ct if not self.any_hope(): # no need to expand return False # decide which rule to pick res = 0 rules = self.G.productions[nonT] pick_rule = None index = k for r in rules: tmp = 1 for i in range(1, len(r)): tmp *= self.G.count_dict[r[i]] if index >= tmp: index -= tmp else: pick_rule = r break # print("search: nonT=", nonT, "picke_rule:", pick_rule) assert pick_rule # print("\n\nbefore replacing: ", self.partial_tree) node.app = pick_rule[0] node.args = [] if len(pick_rule) > 1: for i in range(1, len(pick_rule)): node.args.append(SyExp(pick_rule[i], [])) # print("replaced ", nonT, " with ", pick_rule) # print("partial tree:", self.partial_tree) # print("\n\n") return self.search_in_rule(pick_rule, index) def synthesize(self): # print("count_dict: ", self.G.count_dict) k = 0 suc = False all_ct = self.G.count_dict[self.G.start] # print("all_ct:", all_ct) delta_stats = {} while k < all_ct: self.partial_tree = SyExp(self.G.start, []) status = self.search(self.G.start, k) if status: suc = True break delta = self.countNT(self.G.start, self.partial_tree) if delta not in delta_stats: delta_stats[delta] = 0 delta_stats[delta] += 1 # print("k:", k) # print("partial_tree: ", self.partial_tree) # print("delta:", delta) k += delta if suc: print("delta stats:", delta_stats) print("k=", k, "solution is found: ", self.partial_tree.to_py()) else: print("No solution exists!")
def __init__(self, spec, grammar): self.spec = spec self.G = grammar self.partial_tree = SyExp(grammar.start, []) self.done = False
def reset(self): self.t = 0 self.generated_tree = SyExp('Start', [])
return self.env.get_id( self.exp ) # def get_first_child_id(self): # assert self.exp.app == "eqv" # spec = self.exp.args[0] # assert self.env.exists( spec ) # return self.env.get_id( spec ) def interpret(self, K): assert K < len(self.cnfs) cl = self.cnfs[K] print("interpret cl: ", cl) return self.env.interpret( cl ) if __name__ == '__main__': # (or (not (xor (xor LN231 LN240 ) LN218 ) ) LN336 ) LN231 = SyExp("LN231", []) LN240 = SyExp("LN240", []) LN218 = SyExp("LN218", []) LN336 = SyExp("LN336", []) e1 = SyExp("not", [ SyExp("xor", [SyExp("xor", [LN231, LN240]), LN218]) ] ) e2 = SyExp("or", [e1, LN336]) t = TseitinCNF(e2, 1) t.show()