# Path: arybo/lib/mba_if.py
# class MBA(MBAImpl):
#     ''' Represents an MBA (Mixed Boolean Arithmetic) space of a fixed number of bits. '''
#     def var(self, name):
#         ''' Get an n-bit named symbolic variable
# 
#         Returns:
#             An :class:`MBAVariable` object representing a symbolic variable
# 
#         Example:
#             >>> mba.var('x')
#             Vec([
#             x0,
#             x1,
#             x2,
#             x3
#             ])
#         '''
# 
#         ret = self.from_vec(self.var_symbols(name)) 
#         ret.name = name
#         return ret
# 
#     def from_vec(self, v):
#         ''' Get an :class:`MBAVariable` object with the vector's values.
# 
#         Args:
#             v: a pytanque vector holding boolean expressions
# 
#         Returns:
#             An :class:`MBAVariable` object with the vector's values
#         '''
#         return MBAVariable.from_vec(self, v)
# 
#     def evaluate(self, E, values):
#         if isinstance(E, MBAVariable):
#             E = E.vec
#         return super(MBA, self).evaluate(E, values)
# 
#     def permut2expr(self, P):
#         ''' Convert a substitution table into an arybo application
# 
#         Args:
#             P: list of integers. The list must not contain more than 2**nbits elements.
# 
#         Returns:
#             A tuple containing an :class:`MBAVariable` object with the result
#             and the symbolic input variable used in this object. A typical use
#             case is to feed these into vectorial_decomp.
# 
#         Example:
#             >>> mba = MBA(4)
#             >>> P = [i^7 for i in range(16)]
#             >>> E,X = mba.permut2expr(P)
#             >>> E.vectorial_decomp([X])
#             App NL = Vec([
#             0,
#             0,
#             0,
#             0
#             ])
#             AffApp matrix = Mat([
#             [1, 0, 0, 0]
#             [0, 1, 0, 0]
#             [0, 0, 1, 0]
#             [0, 0, 0, 1]
#             ])
#             AffApp cst = Vec([
#             1,
#             1,
#             1,
#             0
#             ])
#         '''
#         if len(P) > (1<<self.nbits):
#             raise ValueError("P must not contain more than %d elements" % (1<<self.nbits))
#         X = self.var('X')
#         ret = super(MBA, self).permut2expr(P, X.vec)
#         return self.from_vec(ret), X
# 
#     def symbpermut2expr(self, P):
#         X = self.var('X')
#         ret = super(MBA, self).symbpermut2expr(P, X.vec)
#         return self.from_vec(ret), X
# 
#     def from_cst(self, C):
#         return self.from_vec(self.get_vector_from_cst(C))
# 
#     def from_bytes(self, s):
#         if not isinstance(s, bytes):
#             raise ValueError("s must be an instance of bytes!")
#         # TODO: fix this...
#         if self.nbits % 8 != 0:
#             raise ValueError("self.nbits must be a multiple of 8")
#         nbytes = self.nbits//8
#         if len(s) > nbytes:
#             s = s[:nbytes]
#         elif len(s) < nbytes:
#             s = s + 'b\x00'*(nbytes-len(s))
#         return self.from_vec(super(MBA, self).from_bytes(s))
# 
# def expand_esf_inplace(e):
#     ''' Expand ESF **inplace** in the expression or variable e. returns e for conveniance. '''
#     __call_impl_func_inplace(expand_esf_inplace_vec, e)
#     return e
# 
# def simplify_inplace(e):
#     ''' Simplify **inplace** the expression or variable e. returns e for conveniance. '''
#     __call_impl_func_inplace(simplify_inplace_vec, e)
#     return e
# 
# Path: arybo/lib/mba_exprs.py
# def eval_expr(e,use_esf=False):
#     ectx = init_ctxes(e)
# 
#     ret = Vector(e.nbits)
#     for i in range(e.nbits):
#         ret[i] = ectx.eval(ret, i, use_esf)
#     mba = MBA(len(ret))
#     return mba.from_vec(ret)
# 
# Path: arybo/lib/exprs_asm.py
# def to_llvm_function(exprs, vars_, name="__arybo"):
#     if not llvmlite_available:
#         raise RuntimeError("llvmlite module unavailable! can't assemble to LLVM IR...")
# 
#     if not isinstance(exprs, collections.abc.Iterable):
#         exprs = (exprs,)
# 
#     M = ll.Module()
#     args_types = [IntType(v.nbits) for v in vars_]
#     fntype = ll.FunctionType(IntType(exprs[-1].nbits), args_types)
#     func = ll.Function(M, fntype, name=name)
#     func.attributes.add("nounwind")
#     BB = func.append_basic_block()
# 
#     IRB = ll.IRBuilder()
#     IRB.position_at_end(BB)
# 
#     sym_to_value = {}
#     for i,v in enumerate(vars_):
#         arg = func.args[i]
#         arg.name = v.name
#         sym_to_value[v.name] = arg
#     ret = to_llvm_ir(exprs, sym_to_value, IRB)
#     IRB.ret(ret)
#     return M
# 
# Path: arybo/tools/triton_.py
# def _get_mba(n,use_esf):
# def tritonast2arybo(e, use_exprs=True, use_esf=False, context=None):
# def tritonexprs2arybo(exprs):


import unittest
import random
import operator
    import triton as TT
from arybo.lib import MBA, simplify_inplace, expand_esf_inplace
from arybo.lib.mba_exprs import eval_expr
from arybo.lib.exprs_asm import to_llvm_function
from arybo.tools import tritonast2arybo, tritonexprs2arybo, triton_available


if triton_available:
    ctx = TT.TritonContext()
    ctx.setArchitecture(TT.ARCH.X86)

# Path: arybo/lib/mba_if.py
# class MBA(MBAImpl):
#     ''' Represents an MBA (Mixed Boolean Arithmetic) space of a fixed number of bits. '''
#     def var(self, name):
#         ''' Get an n-bit named symbolic variable
# 
#         Returns:
#             An :class:`MBAVariable` object representing a symbolic variable
# 
#         Example:
#             >>> mba.var('x')
#             Vec([
#             x0,
#             x1,
#             x2,
#             x3
#             ])
#         '''
# 
#         ret = self.from_vec(self.var_symbols(name)) 
#         ret.name = name
#         return ret
# 
#     def from_vec(self, v):
#         ''' Get an :class:`MBAVariable` object with the vector's values.
# 
#         Args:
#             v: a pytanque vector holding boolean expressions
# 
#         Returns:
#             An :class:`MBAVariable` object with the vector's values
#         '''
#         return MBAVariable.from_vec(self, v)
# 
#     def evaluate(self, E, values):
#         if isinstance(E, MBAVariable):
#             E = E.vec
#         return super(MBA, self).evaluate(E, values)
# 
#     def permut2expr(self, P):
#         ''' Convert a substitution table into an arybo application
# 
#         Args:
#             P: list of integers. The list must not contain more than 2**nbits elements.
# 
#         Returns:
#             A tuple containing an :class:`MBAVariable` object with the result
#             and the symbolic input variable used in this object. A typical use
#             case is to feed these into vectorial_decomp.
# 
#         Example:
#             >>> mba = MBA(4)
#             >>> P = [i^7 for i in range(16)]
#             >>> E,X = mba.permut2expr(P)
#             >>> E.vectorial_decomp([X])
#             App NL = Vec([
#             0,
#             0,
#             0,
#             0
#             ])
#             AffApp matrix = Mat([
#             [1, 0, 0, 0]
#             [0, 1, 0, 0]
#             [0, 0, 1, 0]
#             [0, 0, 0, 1]
#             ])
#             AffApp cst = Vec([
#             1,
#             1,
#             1,
#             0
#             ])
#         '''
#         if len(P) > (1<<self.nbits):
#             raise ValueError("P must not contain more than %d elements" % (1<<self.nbits))
#         X = self.var('X')
#         ret = super(MBA, self).permut2expr(P, X.vec)
#         return self.from_vec(ret), X
# 
#     def symbpermut2expr(self, P):
#         X = self.var('X')
#         ret = super(MBA, self).symbpermut2expr(P, X.vec)
#         return self.from_vec(ret), X
# 
#     def from_cst(self, C):
#         return self.from_vec(self.get_vector_from_cst(C))
# 
#     def from_bytes(self, s):
#         if not isinstance(s, bytes):
#             raise ValueError("s must be an instance of bytes!")
#         # TODO: fix this...
#         if self.nbits % 8 != 0:
#             raise ValueError("self.nbits must be a multiple of 8")
#         nbytes = self.nbits//8
#         if len(s) > nbytes:
#             s = s[:nbytes]
#         elif len(s) < nbytes:
#             s = s + 'b\x00'*(nbytes-len(s))
#         return self.from_vec(super(MBA, self).from_bytes(s))
# 
# def expand_esf_inplace(e):
#     ''' Expand ESF **inplace** in the expression or variable e. returns e for conveniance. '''
#     __call_impl_func_inplace(expand_esf_inplace_vec, e)
#     return e
# 
# def simplify_inplace(e):
#     ''' Simplify **inplace** the expression or variable e. returns e for conveniance. '''
#     __call_impl_func_inplace(simplify_inplace_vec, e)
#     return e
# 
# Path: arybo/lib/mba_exprs.py
# def eval_expr(e,use_esf=False):
#     ectx = init_ctxes(e)
# 
#     ret = Vector(e.nbits)
#     for i in range(e.nbits):
#         ret[i] = ectx.eval(ret, i, use_esf)
#     mba = MBA(len(ret))
#     return mba.from_vec(ret)
# 
# Path: arybo/lib/exprs_asm.py
# def to_llvm_function(exprs, vars_, name="__arybo"):
#     if not llvmlite_available:
#         raise RuntimeError("llvmlite module unavailable! can't assemble to LLVM IR...")
# 
#     if not isinstance(exprs, collections.abc.Iterable):
#         exprs = (exprs,)
# 
#     M = ll.Module()
#     args_types = [IntType(v.nbits) for v in vars_]
#     fntype = ll.FunctionType(IntType(exprs[-1].nbits), args_types)
#     func = ll.Function(M, fntype, name=name)
#     func.attributes.add("nounwind")
#     BB = func.append_basic_block()
# 
#     IRB = ll.IRBuilder()
#     IRB.position_at_end(BB)
# 
#     sym_to_value = {}
#     for i,v in enumerate(vars_):
#         arg = func.args[i]
#         arg.name = v.name
#         sym_to_value[v.name] = arg
#     ret = to_llvm_ir(exprs, sym_to_value, IRB)
#     IRB.ret(ret)
#     return M
# 
# Path: arybo/tools/triton_.py
# def _get_mba(n,use_esf):
# def tritonast2arybo(e, use_exprs=True, use_esf=False, context=None):
# def tritonexprs2arybo(exprs):


# Path: tests/tools/triton_.py
import unittest
import random
import operator
    import triton as TT
from arybo.lib import MBA, simplify_inplace, expand_esf_inplace
from arybo.lib.mba_exprs import eval_expr
from arybo.lib.exprs_asm import to_llvm_function
from arybo.tools import tritonast2arybo, tritonexprs2arybo, triton_available



if triton_available:
    ctx = TT.TritonContext()
    ctx.setArchitecture(TT.ARCH.X86)

    TAst = ctx.getAstContext()