def decode(self, data, shared = None): """ Decode a term to its SMT representation. """ if cc.is_symb(data): s = "|{}|".format(cc.get_symb(data)) if s not in self.vars and s not in self.aux_vars: self.aux_vars.append(s) self.commands.append(["declare-const", s, "Term"]) return s elif cc.is_int(data): return ["int", build_int(cc.get_int(data))] elif cc.is_float(data): return ["real", build_real(cc.get_float(data))] elif cc.is_atom(data): return ["atom", build_ilist(cc.get_atom_chars(data))] elif cc.is_list(data): items = cc.get_list_subterms(data) if shared is None: shared = cc.get_shared(data) return ["list", build_tlist([self.decode(item, shared) for item in items])] elif cc.is_tuple(data): items = cc.get_tuple_subterms(data) if shared is None: shared = cc.get_shared(data) return ["tuple", build_tlist([self.decode(item, shared) for item in items])] elif cc.is_bitstring(data): return ["str", build_slist(cc.get_bits(data))] elif cc.is_alias(data): return self.decode(shared[cc.get_alias(data)], shared) clg.debug_info("decoding failed: " + str(data)) assert False
def bitmatch_const_false_reversed(self, cnstValue, size, termBitstr): """ Assert that: Not (termBitstr =/= <<cnstValue/size, termRest>>). """ n = cc.get_int(cnstValue) b = cc.get_int(size) t = self.decode(termBitstr) conj = [ "and", ["is-str", t], ] slist = ["sv", t] for bit in self.int2bv(n, b): conj.append(["is-sc", slist]) conj.append(["=", ["sh", slist], bit]) slist = ["st", slist] self.commands.append(["assert", conj])
def bitmatch_const_false(self, cnstValue, size, termBitstr): """ Assert that: termBitstr =/= <<cnstValue/size, termRest>>. """ n = cc.get_int(cnstValue) b = cc.get_int(size) t = self.decode(termBitstr) conj = [ "and", ["is-str", t], ] slist = ["sv", t] for bit in self.int2bv(n, b): conj.append(["is-sc", slist]) conj.append(["=", ["sh", slist], bit]) slist = ["st", slist] self.commands.append( Log(comment= "Term is not a binary of in the form of <<constVal/size, Rest>>.", expr=["assert", ["not", conj]]))
def bitmatch_const_true(self, termRest, cnstValue, size, termBitstr): """ Assert that: termBitstr == <<cnstValue/size, termRest>>. """ r = self.decode(termRest) n = cc.get_int(cnstValue) b = cc.get_int(size) t = self.decode(termBitstr) conj = [ "and", ["is-str", t], ["is-str", r], ] slist = ["sv", t] for bit in self.int2bv(n, b): conj.append(["is-sc", slist]) conj.append(["=", ["sh", slist], bit]) slist = ["st", slist] conj.append(["=", slist, ["sv", r]]) self.commands.append(["assert", conj])
def tuple_not_sz(self, term, num): """ Assert that: term is not a tuple of size num. """ t = self.decode(term) n = cc.get_int(num) l = ["and", ["is-tuple", t]] c = ["tv", t] while n > 0: l.append(["is-tc", c]) c = ["tt", c] n -= 1 l.append(["is-tn", c]) self.commands.append(["assert", ["not", l]])
def tuple_sz(self, term, num): """ Assert that: term is a tuple of size num. """ t = self.decode(term) n = cc.get_int(num) l = ["and", ["is-tuple", t]] c = ["tv", t] while n > 0: l.append(["is-tc", c]) c = ["tt", c] n -= 1 l.append(["is-tn", c]) self.commands.append( Log(comment="Term is a tuple of a specific size.", expr=["assert", l]))
def bitmatch_var_false_reversed(self, size, termBitstr): """ Assert that: Not (termBitstr =/= <<term1/size, term2>>). """ b = cc.get_int(size) t = self.decode(termBitstr) assert b >= 0, "b must be a non-negative integer" conj = [ "and", ["is-str", t], ] slist = ["sv", t] while b > 0: conj.append(["is-sc", slist]) slist = ["st", slist] b -= 1 self.commands.append(["assert", conj])
def make_bitstr(self, symb, encodedValue, size): """ Make a bitstring by encoding an appropriate term. """ t = self.decode(symb) n = self.decode(encodedValue) b = cc.get_int(size) conj = [ "and", ["is-str", t], ] slist = ["sv", t] for bit in self.var2bv(n, b): conj.append(["is-sc", slist]) conj.append(["=", ["sh", slist], bit]) slist = ["st", slist] conj.append(["is-sn", slist]) self.commands.append(["assert", conj])
def bitmatch_var_false_reversed(self, size, termBitstr): """ Assert that: Not (termBitstr =/= <<term1/size, term2>>). """ b = cc.get_int(size) t = self.decode(termBitstr) assert b >= 0, "b must be a non-negative integer" conj = [ "and", ["is-str", t], ] slist = ["sv", t] while b > 0: conj.append(["is-sc", slist]) slist = ["st", slist] b -= 1 self.commands.append( Log(comment= "Term is not a binary of not in the form of <<otherTerm/size, Rest>>.", expr=["assert", conj]))
def bitmatch_var_true(self, term1, term2, size, termBitstr): """ Assert that: termBitstr == <<term1/size, term2>>. """ r = self.decode(term2) n = self.decode(term1) b = cc.get_int(size) t = self.decode(termBitstr) conj = [ "and", ["is-str", r], ["is-str", t], ] slist = ["sv", t] for bit in self.var2bv(n, b): conj.append(["is-sc", slist]) conj.append(["=", ["sh", slist], bit]) slist = ["st", slist] conj.append(["=", slist, ["sv", r]]) self.commands.append(["assert", conj])
def pretty(d): global scnt, symbs try: # Symbolic Variable if cc.is_symb(d): s = cc.get_symb(d) if s in symbs: return symbs[s] else: scnt += 1 x = "x%s" % scnt symbs[s] = x return x # Type if cc.is_type_message(d): return pretty_type(d) # Int if cc.is_int(d): return str(cc.get_int(d)) # Float if cc.is_float(d): return str(cc.get_float(d)) # Atom if cc.is_atom(d): cs = cc.get_atom_chars(d) return "".join(map(chr, cs)) # List if cc.is_list(d): return "[%s]" % pretty_list(cc.get_list_subterms(d)) # Bitstring if cc.is_bitstring(d): bits = map(lambda x: 1 if x else 0, cc.get_bits(d)) return "<<%s>>" % pretty_list(bits) except KeyError: pass return str(d)
def pretty(d): global scnt, symbs try: # Symbolic Variable if cc.is_symb(d): s = cc.get_symb(d) if s in symbs: return symbs[s] + "(" + s + ")" else: scnt += 1 x = "x%s" % scnt symbs[s] = x return x + "(" + s + ")" # Type if cc.is_type_message(d): return pretty_type(d) # Int if cc.is_int(d): return str(cc.get_int(d)) # Float if cc.is_float(d): return str(cc.get_float(d)) # Atom if cc.is_atom(d): cs = cc.get_atom_chars(d) return "".join(map(chr, cs)) # List if cc.is_list(d): return "[%s]" % pretty_list(cc.get_list_subterms(d)) # Bitstring if cc.is_bitstring(d): bits = map(lambda x: 1 if x else 0, cc.get_bits(d)) return "<<%s>>" % pretty_list(bits) except KeyError: pass return str(d)