# This file was automatically generated by SWIG (http://www.swig.org).
# Version 4.0.0
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.

"""pyAgrum is a Python wrapper for the C++ aGrUM library. It provides a high-level interface to the part of aGrUM allowing to create, model, learn, use, calculate with and embed Bayesian Networks. Some specific (python and C++) codes are added in order to simplify and extend the aGrUM API. The module is mainly generated by the SWIG interface generator."""

from sys import version_info as _swig_python_version_info
if _swig_python_version_info < (2, 7, 0):
    raise RuntimeError('Python 2.7 or later required')

# Import the low-level C/C++ module
if __package__ or '.' in __name__:
    from . import _pyAgrum
else:
    import _pyAgrum

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
    if name == "thisown":
        return self.this.own(value)
    if name == "this":
        if type(value).__name__ == 'SwigPyObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name, None)
    if method:
        return method(self, value)
    if not static:
        object.__setattr__(self, name, value)
    else:
        raise AttributeError("You cannot add attributes to %s" % self)


def _swig_setattr(self, class_type, name, value):
    return _swig_setattr_nondynamic(self, class_type, name, value, 0)


def _swig_getattr(self, class_type, name):
    if name == "thisown":
        return self.this.own()
    method = class_type.__swig_getmethods__.get(name, None)
    if method:
        return method(self)
    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))


def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "thisown":
            self.this.own(value)
        elif name == "this":
            set(self, name, value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


import weakref

class SwigPyIterator(object):
    r"""Proxy of C++ swig::SwigPyIterator class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyAgrum.delete_SwigPyIterator

    def value(self) -> "PyObject *":
        r"""value(SwigPyIterator self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_value(self)

    def incr(self, n: 'size_t'=1) -> "swig::SwigPyIterator *":
        r"""incr(SwigPyIterator self, size_t n=1) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_incr(self, n)

    def decr(self, n: 'size_t'=1) -> "swig::SwigPyIterator *":
        r"""decr(SwigPyIterator self, size_t n=1) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_decr(self, n)

    def distance(self, x: 'SwigPyIterator') -> "ptrdiff_t":
        r"""distance(SwigPyIterator self, SwigPyIterator x) -> ptrdiff_t"""
        return _pyAgrum.SwigPyIterator_distance(self, x)

    def equal(self, x: 'SwigPyIterator') -> "bool":
        r"""equal(SwigPyIterator self, SwigPyIterator x) -> bool"""
        return _pyAgrum.SwigPyIterator_equal(self, x)

    def copy(self) -> "swig::SwigPyIterator *":
        r"""copy(SwigPyIterator self) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_copy(self)

    def next(self) -> "PyObject *":
        r"""next(SwigPyIterator self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_next(self)

    def __next__(self) -> "PyObject *":
        r"""__next__(SwigPyIterator self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator___next__(self)

    def previous(self) -> "PyObject *":
        r"""previous(SwigPyIterator self) -> PyObject *"""
        return _pyAgrum.SwigPyIterator_previous(self)

    def advance(self, n: 'ptrdiff_t') -> "swig::SwigPyIterator *":
        r"""advance(SwigPyIterator self, ptrdiff_t n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator_advance(self, n)

    def __eq__(self, x: 'SwigPyIterator') -> "bool":
        r"""__eq__(SwigPyIterator self, SwigPyIterator x) -> bool"""
        return _pyAgrum.SwigPyIterator___eq__(self, x)

    def __ne__(self, x: 'SwigPyIterator') -> "bool":
        r"""__ne__(SwigPyIterator self, SwigPyIterator x) -> bool"""
        return _pyAgrum.SwigPyIterator___ne__(self, x)

    def __iadd__(self, n: 'ptrdiff_t') -> "swig::SwigPyIterator &":
        r"""__iadd__(SwigPyIterator self, ptrdiff_t n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___iadd__(self, n)

    def __isub__(self, n: 'ptrdiff_t') -> "swig::SwigPyIterator &":
        r"""__isub__(SwigPyIterator self, ptrdiff_t n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___isub__(self, n)

    def __add__(self, n: 'ptrdiff_t') -> "swig::SwigPyIterator *":
        r"""__add__(SwigPyIterator self, ptrdiff_t n) -> SwigPyIterator"""
        return _pyAgrum.SwigPyIterator___add__(self, n)

    def __sub__(self, *args) -> "ptrdiff_t":
        r"""
        __sub__(SwigPyIterator self, ptrdiff_t n) -> SwigPyIterator
        __sub__(SwigPyIterator self, SwigPyIterator x) -> ptrdiff_t
        """
        return _pyAgrum.SwigPyIterator___sub__(self, *args)
    def __iter__(self):
        return self

# Register SwigPyIterator in _pyAgrum:
_pyAgrum.SwigPyIterator_swigregister(SwigPyIterator)


import numpy

class JunctionTreeGenerator(object):
    r"""

    JunctionTreeGenerator is use to generate junction tree or binary junction tree from bayesian networks.

    Available constructors:
    	``JunctionTreeGenerator() -> JunctionTreeGenerator``

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def junctionTree(self, *args) -> "gum::JunctionTree":
        r"""
        junctionTree(JunctionTreeGenerator self, UndiGraph g, PyObject * partial_order=None) -> CliqueGraph
        junctionTree(JunctionTreeGenerator self, DAG dag, PyObject * partial_order=None) -> CliqueGraph
        junctionTree(JunctionTreeGenerator self, BayesNet bn, PyObject * partial_order=None) -> CliqueGraph

        Computes the junction tree for its parameters. If the first parameter is a graph, the heurisitcs assume that all the node have the same domain size (2). If given, the heuristic takes into account the partial order for its elimination order.

        Parameters
        ----------
        g : pyAgrum.UndiGraph
        	a undirected graph

        dag : pyAgrum.DAG
        	a dag

        bn : pyAgrum.BayesNet
        	a BayesianNetwork

        partial_order: List[List[int]]
        	a partial order among the nodeIDs

        Returns
        -------
        pyAgrum.CliqueGraph
        	the current junction tree. 

        """
        return _pyAgrum.JunctionTreeGenerator_junctionTree(self, *args)

    def eliminationOrder(self, *args) -> "PyObject *":
        r"""
        eliminationOrder(JunctionTreeGenerator self, UndiGraph g, PyObject * partial_order=None) -> PyObject
        eliminationOrder(JunctionTreeGenerator self, DAG dag, PyObject * partial_order=None) -> PyObject
        eliminationOrder(JunctionTreeGenerator self, BayesNet bn, PyObject * partial_order=None) -> PyObject

        Computes the elimination for its parameters. If the first parameter is a graph, the heurisitcs assume that all the node have the same domain size (2). If given, the heuristic takes into account the partial order for its elimination order.

        Parameters
        ----------
        g : pyAgrum.UndiGraph
        	a undirected graph

        dag : pyAgrum.DAG
        	a dag

        bn : pyAgrum.BayesNet
        	a BayesianNetwork

        partial_order: List[List[int]]
        	a partial order among the nodeIDs

        Returns
        -------
        pyAgrum.CliqueGraph
        	the current elimination order.

        """
        return _pyAgrum.JunctionTreeGenerator_eliminationOrder(self, *args)

    def binaryJoinTree(self, *args) -> "gum::JunctionTree":
        r"""
        binaryJoinTree(JunctionTreeGenerator self, UndiGraph g, PyObject * partial_order=None) -> CliqueGraph
        binaryJoinTree(JunctionTreeGenerator self, DAG dag, PyObject * partial_order=None) -> CliqueGraph
        binaryJoinTree(JunctionTreeGenerator self, BayesNet bn, PyObject * partial_order=None) -> CliqueGraph

        Computes the binary joint tree for its parameters. If the first parameter is a graph, the heurisitcs assume that all the node have the same domain size (2). If given, the heuristic takes into account the partial order for its elimination order.

        Parameters
        ----------
        g : pyAgrum.UndiGraph
        	a undirected graph

        dag : pyAgrum.DAG
        	a dag

        bn : pyAgrum.BayesNet
        	a BayesianNetwork

        partial_order: List[List[int]]
        	a partial order among the nodeIDs

        Returns
        -------
        pyAgrum.CliqueGraph
        	the current binary joint tree 

        """
        return _pyAgrum.JunctionTreeGenerator_binaryJoinTree(self, *args)

    def __init__(self):
        r"""
        __init__(JunctionTreeGenerator self) -> JunctionTreeGenerator

        JunctionTreeGenerator is use to generate junction tree or binary junction tree from bayesian networks.

        Available constructors:
        	``JunctionTreeGenerator() -> JunctionTreeGenerator``

        """
        _pyAgrum.JunctionTreeGenerator_swiginit(self, _pyAgrum.new_JunctionTreeGenerator())
    __swig_destroy__ = _pyAgrum.delete_JunctionTreeGenerator

# Register JunctionTreeGenerator in _pyAgrum:
_pyAgrum.JunctionTreeGenerator_swigregister(JunctionTreeGenerator)

class PythonBNListener(object):
    r"""Proxy of C++ PythonBNListener class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'BayesNet', vnm: 'VariableNodeMap'):
        r"""__init__(PythonBNListener self, BayesNet bn, VariableNodeMap vnm) -> PythonBNListener"""
        _pyAgrum.PythonBNListener_swiginit(self, _pyAgrum.new_PythonBNListener(bn, vnm))
    __swig_destroy__ = _pyAgrum.delete_PythonBNListener

    def whenNodeAdded(self, source: 'void const *', id: 'gum::NodeId') -> "void":
        r"""whenNodeAdded(PythonBNListener self, void const * source, gum::NodeId id)"""
        return _pyAgrum.PythonBNListener_whenNodeAdded(self, source, id)

    def whenNodeDeleted(self, arg2: 'void const *', id: 'gum::NodeId') -> "void":
        r"""whenNodeDeleted(PythonBNListener self, void const * arg2, gum::NodeId id)"""
        return _pyAgrum.PythonBNListener_whenNodeDeleted(self, arg2, id)

    def whenArcAdded(self, arg2: 'void const *', src: 'gum::NodeId', dst: 'gum::NodeId') -> "void":
        r"""whenArcAdded(PythonBNListener self, void const * arg2, gum::NodeId src, gum::NodeId dst)"""
        return _pyAgrum.PythonBNListener_whenArcAdded(self, arg2, src, dst)

    def whenArcDeleted(self, arg2: 'void const *', src: 'gum::NodeId', dst: 'gum::NodeId') -> "void":
        r"""whenArcDeleted(PythonBNListener self, void const * arg2, gum::NodeId src, gum::NodeId dst)"""
        return _pyAgrum.PythonBNListener_whenArcDeleted(self, arg2, src, dst)

    def setWhenArcAdded(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenArcAdded(PythonBNListener self, PyObject * pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenArcAdded(self, pyfunc)

    def setWhenArcDeleted(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenArcDeleted(PythonBNListener self, PyObject * pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenArcDeleted(self, pyfunc)

    def setWhenNodeAdded(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenNodeAdded(PythonBNListener self, PyObject * pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenNodeAdded(self, pyfunc)

    def setWhenNodeDeleted(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenNodeDeleted(PythonBNListener self, PyObject * pyfunc)



        """
        return _pyAgrum.PythonBNListener_setWhenNodeDeleted(self, pyfunc)

# Register PythonBNListener in _pyAgrum:
_pyAgrum.PythonBNListener_swigregister(PythonBNListener)

class PythonLoadListener(object):
    r"""Proxy of C++ PythonLoadListener class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def whenLoading(self, buffer: 'void const *', percent: 'int') -> "void":
        r"""whenLoading(PythonLoadListener self, void const * buffer, int percent)"""
        return _pyAgrum.PythonLoadListener_whenLoading(self, buffer, percent)

    def setPythonListener(self, l: 'PyObject *') -> "bool":
        r"""
        setPythonListener(PythonLoadListener self, PyObject * l) -> bool



        """
        return _pyAgrum.PythonLoadListener_setPythonListener(self, l)

    def __init__(self):
        r"""__init__(PythonLoadListener self) -> PythonLoadListener"""
        _pyAgrum.PythonLoadListener_swiginit(self, _pyAgrum.new_PythonLoadListener())
    __swig_destroy__ = _pyAgrum.delete_PythonLoadListener

# Register PythonLoadListener in _pyAgrum:
_pyAgrum.PythonLoadListener_swigregister(PythonLoadListener)


def __fillLoadListeners(py_listener: 'std::vector< PythonLoadListener,std::allocator< PythonLoadListener > > &', l: 'PyObject *') -> "int":
    r"""__fillLoadListeners(std::vector< PythonLoadListener,std::allocator< PythonLoadListener > > & py_listener, PyObject * l) -> int"""
    return _pyAgrum.__fillLoadListeners(py_listener, l)
class PythonApproximationListener(object):
    r"""

    Parameters
    ----------
    algo : IApproximationSchemeConfiguration
    	an approxmation scheme

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, algo: 'IApproximationSchemeConfiguration'):
        r"""
        __init__(PythonApproximationListener self, IApproximationSchemeConfiguration algo) -> PythonApproximationListener

        Parameters
        ----------
        algo : IApproximationSchemeConfiguration
        	an approxmation scheme

        """
        _pyAgrum.PythonApproximationListener_swiginit(self, _pyAgrum.new_PythonApproximationListener(algo))
    __swig_destroy__ = _pyAgrum.delete_PythonApproximationListener

    def whenProgress(self, src: 'void const *', step: 'gum::Size const', error: 'double const', duration: 'double const') -> "void":
        r"""whenProgress(PythonApproximationListener self, void const * src, gum::Size const step, double const error, double const duration)"""
        return _pyAgrum.PythonApproximationListener_whenProgress(self, src, step, error, duration)

    def whenStop(self, src: 'void const *', message: 'std::string const') -> "void":
        r"""whenStop(PythonApproximationListener self, void const * src, std::string const message)"""
        return _pyAgrum.PythonApproximationListener_whenStop(self, src, message)

    def setWhenProgress(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenProgress(PythonApproximationListener self, PyObject * pyfunc)

        Parameters
        ----------
        pyfunc
        	the function to execute

        """
        return _pyAgrum.PythonApproximationListener_setWhenProgress(self, pyfunc)

    def setWhenStop(self, pyfunc: 'PyObject *') -> "void":
        r"""
        setWhenStop(PythonApproximationListener self, PyObject * pyfunc)

        Parameters
        ----------
        pyfunc
        	the function to execute

        """
        return _pyAgrum.PythonApproximationListener_setWhenStop(self, pyfunc)

# Register PythonApproximationListener in _pyAgrum:
_pyAgrum.PythonApproximationListener_swigregister(PythonApproximationListener)

class PythonDatabaseGeneratorListener(object):
    r"""Proxy of C++ PythonDatabaseGeneratorListener class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, notif: 'BNDatabaseGenerator'):
        r"""__init__(PythonDatabaseGeneratorListener self, BNDatabaseGenerator notif) -> PythonDatabaseGeneratorListener"""
        _pyAgrum.PythonDatabaseGeneratorListener_swiginit(self, _pyAgrum.new_PythonDatabaseGeneratorListener(notif))
    __swig_destroy__ = _pyAgrum.delete_PythonDatabaseGeneratorListener

    def whenProgress(self, src: 'void const *', step: 'gum::Size const', duration: 'double const') -> "void":
        r"""whenProgress(PythonDatabaseGeneratorListener self, void const * src, gum::Size const step, double const duration)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_whenProgress(self, src, step, duration)

    def whenStop(self, src: 'void const *', message: 'std::string const &') -> "void":
        r"""whenStop(PythonDatabaseGeneratorListener self, void const * src, std::string const & message)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_whenStop(self, src, message)

    def setWhenProgress(self, pyfunc: 'PyObject *') -> "void":
        r"""setWhenProgress(PythonDatabaseGeneratorListener self, PyObject * pyfunc)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_setWhenProgress(self, pyfunc)

    def setWhenStop(self, pyfunc: 'PyObject *') -> "void":
        r"""setWhenStop(PythonDatabaseGeneratorListener self, PyObject * pyfunc)"""
        return _pyAgrum.PythonDatabaseGeneratorListener_setWhenStop(self, pyfunc)

# Register PythonDatabaseGeneratorListener in _pyAgrum:
_pyAgrum.PythonDatabaseGeneratorListener_swigregister(PythonDatabaseGeneratorListener)

class BNGenerator(object):
    r"""

    BNGenerator is used to easily generate Bayesian networks.

    Available constructors:

        ``BNGenerator() -> BNGenerator``

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def generate(self, n_nodes: 'gum::Size'=10, n_arcs: 'gum::Size'=15, n_modmax: 'gum::Size'=4) -> "gum::BayesNet< double >":
        r"""
        generate(BNGenerator self, gum::Size n_nodes=10, gum::Size n_arcs=15, gum::Size n_modmax=4) -> BayesNet

        Generate a new Bayesian network 

        Parameters
        ----------
        n_nodes : int
        	the number of nodes (default=10)
        n_arcs : int
        	the number of arcs (default=15)
        n_nodmax : int
        	the max number of modalities for a node (default=4)

        Returns
        -------
        pyAgrum.BayesNet
        	the generated Bayesian network

        Raises
        ------
        gum.OperationNotAllowed
        	If n_modmax < 2
        gum.OperationNotAllowed
        	If n_arcs is incompatible with n_nodes (not enough arcs)

        """
        return _pyAgrum.BNGenerator_generate(self, n_nodes, n_arcs, n_modmax)

    def __init__(self):
        r"""
        __init__(BNGenerator self) -> BNGenerator

        BNGenerator is used to easily generate Bayesian networks.

        Available constructors:

            ``BNGenerator() -> BNGenerator``

        """
        _pyAgrum.BNGenerator_swiginit(self, _pyAgrum.new_BNGenerator())
    __swig_destroy__ = _pyAgrum.delete_BNGenerator

# Register BNGenerator in _pyAgrum:
_pyAgrum.BNGenerator_swigregister(BNGenerator)

class IDGenerator(object):
    r"""

    IDGenerator is used to easily generate influence diagrams.

    Available constructors:

        ``IDGenerator() -> IDGenerator``

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def generate(self, nbrNodes: 'gum::Size'=10, arcDensity: 'double'=0.2, chanceNodeDensity: 'double'=0.8, utilityNodeDensity: 'double'=0.1, max_modality: 'int'=2) -> "gum::InfluenceDiagram< double >":
        r"""
        generate(IDGenerator self, gum::Size nbrNodes=10, double arcDensity=0.2, double chanceNodeDensity=0.8, double utilityNodeDensity=0.1, int max_modality=2) -> InfluenceDiagram

        Generate a new influence diagram given the parameters.

        Parameters
        ----------
        nbrNodes : int
        	the number of node
        arcDensity : double
        	the density of arc (1 for a complete graph)
        chanceNodeDensity : double
        	the density of chance node
        utilityNodeDensity : double
        	the density of utility node
        max_modality : int
        	the maximum value for modalities

        Returns
        -------
        pyAgrum.InfluenceDiagram
        	the generated influence diagram

        """
        return _pyAgrum.IDGenerator_generate(self, nbrNodes, arcDensity, chanceNodeDensity, utilityNodeDensity, max_modality)

    def __init__(self):
        r"""
        __init__(IDGenerator self) -> IDGenerator

        IDGenerator is used to easily generate influence diagrams.

        Available constructors:

            ``IDGenerator() -> IDGenerator``

        """
        _pyAgrum.IDGenerator_swiginit(self, _pyAgrum.new_IDGenerator())
    __swig_destroy__ = _pyAgrum.delete_IDGenerator

# Register IDGenerator in _pyAgrum:
_pyAgrum.IDGenerator_swigregister(IDGenerator)

class PRMexplorer(object):
    r"""

    PRMexplorer helps navigate through probabilistic relational models.

    Available constructors:
    	``PRMexplorer() -> PRMexplorer``

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self):
        r"""
        __init__(PRMexplorer self) -> PRMexplorer

        PRMexplorer helps navigate through probabilistic relational models.

        Available constructors:
        	``PRMexplorer() -> PRMexplorer``

        """
        _pyAgrum.PRMexplorer_swiginit(self, _pyAgrum.new_PRMexplorer())
    __swig_destroy__ = _pyAgrum.delete_PRMexplorer

    def load(self, *args) -> "void":
        r"""
        load(PRMexplorer self, std::string filename, std::string classpath="", bool verbose=False)

        Load a PRM into the explorer.

        Parameters
        ----------
        filename : str
        	the name of the o3prm file
        classpath : str
        	the classpath of the PRM

        Raises
        ------
        gum.FatalError
        	If file not found

        """
        return _pyAgrum.PRMexplorer_load(self, *args)

    def isType(self, name: 'std::string') -> "PyObject *":
        r"""
        isType(PRMexplorer self, std::string name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to a type in the PRM

        """
        return _pyAgrum.PRMexplorer_isType(self, name)

    def isClass(self, name: 'std::string') -> "PyObject *":
        r"""
        isClass(PRMexplorer self, std::string name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to a class in the PRM

        """
        return _pyAgrum.PRMexplorer_isClass(self, name)

    def isInterface(self, name: 'std::string') -> "PyObject *":
        r"""
        isInterface(PRMexplorer self, std::string name) -> PyObject *

        Parameters
        ----------
        name : str
        	an element name

        Returns
        -------
        bool
        	True if the parameter correspond to an interface in the PRM

        """
        return _pyAgrum.PRMexplorer_isInterface(self, name)

    def classes(self) -> "PyObject *":
        r"""
        classes(PRMexplorer self) -> PyObject *

        Returns
        -------
        list
        	the list of classes

        """
        return _pyAgrum.PRMexplorer_classes(self)

    def classAttributes(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classAttributes(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of attributes

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classAttributes(self, class_name)

    def isAttribute(self, class_name: 'std::string', att_name: 'std::string') -> "PyObject *":
        r"""
        isAttribute(PRMexplorer self, std::string class_name, std::string att_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name
        att_name : str
        	the name of the attribute to be tested

        Returns
        -------
        bool
        	True if att_name is an attribute of class_name

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM
        gum.IndexError
        	If att_name is not an element of class_name

        """
        return _pyAgrum.PRMexplorer_isAttribute(self, class_name, att_name)

    def classReferences(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classReferences(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of references

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classReferences(self, class_name)

    def classParameters(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classParameters(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of parameters

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classParameters(self, class_name)

    def classImplements(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classImplements(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of interfaces implemented by the class

        """
        return _pyAgrum.PRMexplorer_classImplements(self, class_name)
    aggType = property(_pyAgrum.PRMexplorer_aggType_get, _pyAgrum.PRMexplorer_aggType_set, doc=r"""
    aggType : a(9).std::string

    min/max/count/exists/forall/or/and/amplitude/median

    """)

    def classAggregates(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classAggregates(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of aggregates in the class

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classAggregates(self, class_name)

    def classSlotChains(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classSlotChains(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of class slot chains

        Raises
        ------
        gum.IndexError 
        	if the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classSlotChains(self, class_name)

    def classDag(self, class_name: 'std::string') -> "PyObject *":
        r"""
        classDag(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        tuple
        	a description of the DAG

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_classDag(self, class_name)

    def getalltheSystems(self) -> "PyObject *":
        r"""
        getalltheSystems(PRMexplorer self) -> PyObject *

        Returns
        -------
        list
        	the list of all the systems and their components

        """
        return _pyAgrum.PRMexplorer_getalltheSystems(self)

    def getSuperClass(self, class_name: 'std::string') -> "PyObject *":
        r"""
        getSuperClass(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        str
        	the class extended by class_name

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperClass(self, class_name)

    def getDirectSubClass(self, class_name: 'std::string') -> "PyObject *":
        r"""
        getDirectSubClass(PRMexplorer self, std::string class_name) -> PyObject *

        Parameters
        ----------
        class_name : str
        	a class name

        Returns
        -------
        list
        	the list of direct subclasses

        Raises
        ------
        gum.IndexError
        	If the class is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubClass(self, class_name)

    def cpf(self, class_name: 'std::string', attribute: 'std::string') -> "gum::Potential< double > const &":
        r"""
        cpf(PRMexplorer self, std::string class_name, std::string attribute) -> Potential

        Parameters
        ----------
        class_name : str
        	a class name

        attribute : str
        	an attribute

        Returns
        -------
        pyAgrum.Potential
        	the potential of the attribute

        Raises
        ------
        gum.OperationNotAllowed
        	If the class element doesn't have any gum::Potential (like a gum::PRMReferenceSlot). 
        gum.IndexError
        	If the class is not in the PRM
        gum.IndexError
        	If the attribute in parameters does not exist 

        """
        return _pyAgrum.PRMexplorer_cpf(self, class_name, attribute)

    def types(self) -> "PyObject *":
        r"""
        types(PRMexplorer self) -> PyObject *

        Returns
        -------
        list
        	the list of the custom types in the PRM 

        """
        return _pyAgrum.PRMexplorer_types(self)

    def getSuperType(self, type_name: 'std::string') -> "PyObject *":
        r"""
        getSuperType(PRMexplorer self, std::string type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        str
        	the type extended by type_name

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperType(self, type_name)

    def getDirectSubTypes(self, type_name: 'std::string') -> "PyObject *":
        r"""
        getDirectSubTypes(PRMexplorer self, std::string type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        list
        	the list of direct subtypes

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubTypes(self, type_name)

    def getLabels(self, type_name: 'std::string') -> "PyObject *":
        r"""
        getLabels(PRMexplorer self, std::string type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        list
        	the list of type labels

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getLabels(self, type_name)

    def getLabelMap(self, type_name: 'std::string') -> "PyObject *":
        r"""
        getLabelMap(PRMexplorer self, std::string type_name) -> PyObject *

        Parameters
        ----------
        type_name : str
        	a type name

        Returns
        -------
        dict
        	a dict containing pairs of label and their values 

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getLabelMap(self, type_name)

    def interfaces(self) -> "PyObject *":
        r"""
        interfaces(PRMexplorer self) -> PyObject *

        Returns
        -------
        list
        	the list of interfaces in the PRM 

        """
        return _pyAgrum.PRMexplorer_interfaces(self)

    def interAttributes(self, interface_name: 'std::string', allAttributes: 'bool'=False) -> "PyObject *":
        r"""
        interAttributes(PRMexplorer self, std::string interface_name, bool allAttributes=False) -> PyObject

        Parameters
        ----------
        interface_name : str
        	an interface

        allAttributes : bool
        	True if supertypes of a custom type should be indicated

        Returns
        -------
        list
        	the list of (<type>,<attribute_name>) for the given interface

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_interAttributes(self, interface_name, allAttributes)

    def interReferences(self, interface_name: 'std::string') -> "PyObject *":
        r"""
        interReferences(PRMexplorer self, std::string interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface

        Returns
        -------
        list
        	the list of (<reference_type>,<reference_name>,<True if the reference is an array>) for the given interface

        Raises
        ------
        gum.IndexError
        	If the type is not in the PRM

        """
        return _pyAgrum.PRMexplorer_interReferences(self, interface_name)

    def getSuperInterface(self, interface_name: 'std::string') -> "PyObject *":
        r"""
        getSuperInterface(PRMexplorer self, std::string interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        str
        	the interace extended by interface_name

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getSuperInterface(self, interface_name)

    def getDirectSubInterfaces(self, interface_name: 'std::string') -> "PyObject *":
        r"""
        getDirectSubInterfaces(PRMexplorer self, std::string interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        list
        	the list of direct subinterfaces

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getDirectSubInterfaces(self, interface_name)

    def getImplementations(self, interface_name: 'std::string') -> "PyObject *":
        r"""
        getImplementations(PRMexplorer self, std::string interface_name) -> PyObject *

        Parameters
        ----------
        interface_name : str
        	an interface name

        Returns
        -------
        str
        	the list of classes implementing the interface 

        Raises
        ------
        gum.IndexError
        	If the interface is not in the PRM

        """
        return _pyAgrum.PRMexplorer_getImplementations(self, interface_name)

# Register PRMexplorer in _pyAgrum:
_pyAgrum.PRMexplorer_swigregister(PRMexplorer)

class Vector(object):
    r"""Proxy of C++ std::vector< double > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def iterator(self) -> "swig::SwigPyIterator *":
        r"""iterator(Vector self) -> SwigPyIterator"""
        return _pyAgrum.Vector_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self) -> "bool":
        r"""__nonzero__(Vector self) -> bool"""
        return _pyAgrum.Vector___nonzero__(self)

    def __bool__(self) -> "bool":
        r"""__bool__(Vector self) -> bool"""
        return _pyAgrum.Vector___bool__(self)

    def __len__(self) -> "std::vector< double >::size_type":
        r"""__len__(Vector self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector___len__(self)

    def __getslice__(self, i: 'std::vector< double >::difference_type', j: 'std::vector< double >::difference_type') -> "std::vector< double,std::allocator< double > > *":
        r"""__getslice__(Vector self, std::vector< double >::difference_type i, std::vector< double >::difference_type j) -> Vector"""
        return _pyAgrum.Vector___getslice__(self, i, j)

    def __setslice__(self, *args) -> "void":
        r"""
        __setslice__(Vector self, std::vector< double >::difference_type i, std::vector< double >::difference_type j)
        __setslice__(Vector self, std::vector< double >::difference_type i, std::vector< double >::difference_type j, Vector v)
        """
        return _pyAgrum.Vector___setslice__(self, *args)

    def __delslice__(self, i: 'std::vector< double >::difference_type', j: 'std::vector< double >::difference_type') -> "void":
        r"""__delslice__(Vector self, std::vector< double >::difference_type i, std::vector< double >::difference_type j)"""
        return _pyAgrum.Vector___delslice__(self, i, j)

    def __delitem__(self, *args) -> "void":
        r"""
        __delitem__(Vector self, std::vector< double >::difference_type i)
        __delitem__(Vector self, PySliceObject * slice)
        """
        return _pyAgrum.Vector___delitem__(self, *args)

    def __getitem__(self, *args) -> "std::vector< double >::value_type const &":
        r"""
        __getitem__(Vector self, PySliceObject * slice) -> Vector
        __getitem__(Vector self, std::vector< double >::difference_type i) -> std::vector< double >::value_type const &
        """
        return _pyAgrum.Vector___getitem__(self, *args)

    def __setitem__(self, *args) -> "void":
        r"""
        __setitem__(Vector self, PySliceObject * slice, Vector v)
        __setitem__(Vector self, PySliceObject * slice)
        __setitem__(Vector self, std::vector< double >::difference_type i, std::vector< double >::value_type const & x)
        """
        return _pyAgrum.Vector___setitem__(self, *args)

    def pop(self) -> "std::vector< double >::value_type":
        r"""pop(Vector self) -> std::vector< double >::value_type"""
        return _pyAgrum.Vector_pop(self)

    def append(self, x: 'std::vector< double >::value_type const &') -> "void":
        r"""append(Vector self, std::vector< double >::value_type const & x)"""
        return _pyAgrum.Vector_append(self, x)

    def empty(self) -> "bool":
        r"""empty(Vector self) -> bool"""
        return _pyAgrum.Vector_empty(self)

    def size(self) -> "std::vector< double >::size_type":
        r"""size(Vector self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector_size(self)

    def swap(self, v: 'Vector') -> "void":
        r"""swap(Vector self, Vector v)"""
        return _pyAgrum.Vector_swap(self, v)

    def begin(self) -> "std::vector< double >::iterator":
        r"""begin(Vector self) -> std::vector< double >::iterator"""
        return _pyAgrum.Vector_begin(self)

    def end(self) -> "std::vector< double >::iterator":
        r"""end(Vector self) -> std::vector< double >::iterator"""
        return _pyAgrum.Vector_end(self)

    def rbegin(self) -> "std::vector< double >::reverse_iterator":
        r"""rbegin(Vector self) -> std::vector< double >::reverse_iterator"""
        return _pyAgrum.Vector_rbegin(self)

    def rend(self) -> "std::vector< double >::reverse_iterator":
        r"""rend(Vector self) -> std::vector< double >::reverse_iterator"""
        return _pyAgrum.Vector_rend(self)

    def clear(self) -> "void":
        r"""clear(Vector self)"""
        return _pyAgrum.Vector_clear(self)

    def get_allocator(self) -> "std::vector< double >::allocator_type":
        r"""get_allocator(Vector self) -> std::vector< double >::allocator_type"""
        return _pyAgrum.Vector_get_allocator(self)

    def pop_back(self) -> "void":
        r"""pop_back(Vector self)"""
        return _pyAgrum.Vector_pop_back(self)

    def erase(self, *args) -> "std::vector< double >::iterator":
        r"""
        erase(Vector self, std::vector< double >::iterator pos) -> std::vector< double >::iterator
        erase(Vector self, std::vector< double >::iterator first, std::vector< double >::iterator last) -> std::vector< double >::iterator
        """
        return _pyAgrum.Vector_erase(self, *args)

    def __init__(self, *args):
        r"""
        __init__(Vector self) -> Vector
        __init__(Vector self, Vector other) -> Vector
        __init__(Vector self, std::vector< double >::size_type size) -> Vector
        __init__(Vector self, std::vector< double >::size_type size, std::vector< double >::value_type const & value) -> Vector
        """
        _pyAgrum.Vector_swiginit(self, _pyAgrum.new_Vector(*args))

    def push_back(self, x: 'std::vector< double >::value_type const &') -> "void":
        r"""push_back(Vector self, std::vector< double >::value_type const & x)"""
        return _pyAgrum.Vector_push_back(self, x)

    def front(self) -> "std::vector< double >::value_type const &":
        r"""front(Vector self) -> std::vector< double >::value_type const &"""
        return _pyAgrum.Vector_front(self)

    def back(self) -> "std::vector< double >::value_type const &":
        r"""back(Vector self) -> std::vector< double >::value_type const &"""
        return _pyAgrum.Vector_back(self)

    def assign(self, n: 'std::vector< double >::size_type', x: 'std::vector< double >::value_type const &') -> "void":
        r"""assign(Vector self, std::vector< double >::size_type n, std::vector< double >::value_type const & x)"""
        return _pyAgrum.Vector_assign(self, n, x)

    def resize(self, *args) -> "void":
        r"""
        resize(Vector self, std::vector< double >::size_type new_size)
        resize(Vector self, std::vector< double >::size_type new_size, std::vector< double >::value_type const & x)
        """
        return _pyAgrum.Vector_resize(self, *args)

    def insert(self, *args) -> "void":
        r"""
        insert(Vector self, std::vector< double >::iterator pos, std::vector< double >::value_type const & x) -> std::vector< double >::iterator
        insert(Vector self, std::vector< double >::iterator pos, std::vector< double >::size_type n, std::vector< double >::value_type const & x)
        """
        return _pyAgrum.Vector_insert(self, *args)

    def reserve(self, n: 'std::vector< double >::size_type') -> "void":
        r"""reserve(Vector self, std::vector< double >::size_type n)"""
        return _pyAgrum.Vector_reserve(self, n)

    def capacity(self) -> "std::vector< double >::size_type":
        r"""capacity(Vector self) -> std::vector< double >::size_type"""
        return _pyAgrum.Vector_capacity(self)
    __swig_destroy__ = _pyAgrum.delete_Vector

# Register Vector in _pyAgrum:
_pyAgrum.Vector_swigregister(Vector)

class Vector_int(object):
    r"""Proxy of C++ std::vector< unsigned int > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def iterator(self) -> "swig::SwigPyIterator *":
        r"""iterator(Vector_int self) -> SwigPyIterator"""
        return _pyAgrum.Vector_int_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self) -> "bool":
        r"""__nonzero__(Vector_int self) -> bool"""
        return _pyAgrum.Vector_int___nonzero__(self)

    def __bool__(self) -> "bool":
        r"""__bool__(Vector_int self) -> bool"""
        return _pyAgrum.Vector_int___bool__(self)

    def __len__(self) -> "std::vector< unsigned int >::size_type":
        r"""__len__(Vector_int self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int___len__(self)

    def __getslice__(self, i: 'std::vector< unsigned int >::difference_type', j: 'std::vector< unsigned int >::difference_type') -> "std::vector< unsigned int,std::allocator< unsigned int > > *":
        r"""__getslice__(Vector_int self, std::vector< unsigned int >::difference_type i, std::vector< unsigned int >::difference_type j) -> Vector_int"""
        return _pyAgrum.Vector_int___getslice__(self, i, j)

    def __setslice__(self, *args) -> "void":
        r"""
        __setslice__(Vector_int self, std::vector< unsigned int >::difference_type i, std::vector< unsigned int >::difference_type j)
        __setslice__(Vector_int self, std::vector< unsigned int >::difference_type i, std::vector< unsigned int >::difference_type j, Vector_int v)
        """
        return _pyAgrum.Vector_int___setslice__(self, *args)

    def __delslice__(self, i: 'std::vector< unsigned int >::difference_type', j: 'std::vector< unsigned int >::difference_type') -> "void":
        r"""__delslice__(Vector_int self, std::vector< unsigned int >::difference_type i, std::vector< unsigned int >::difference_type j)"""
        return _pyAgrum.Vector_int___delslice__(self, i, j)

    def __delitem__(self, *args) -> "void":
        r"""
        __delitem__(Vector_int self, std::vector< unsigned int >::difference_type i)
        __delitem__(Vector_int self, PySliceObject * slice)
        """
        return _pyAgrum.Vector_int___delitem__(self, *args)

    def __getitem__(self, *args) -> "std::vector< unsigned int >::value_type const &":
        r"""
        __getitem__(Vector_int self, PySliceObject * slice) -> Vector_int
        __getitem__(Vector_int self, std::vector< unsigned int >::difference_type i) -> std::vector< unsigned int >::value_type const &
        """
        return _pyAgrum.Vector_int___getitem__(self, *args)

    def __setitem__(self, *args) -> "void":
        r"""
        __setitem__(Vector_int self, PySliceObject * slice, Vector_int v)
        __setitem__(Vector_int self, PySliceObject * slice)
        __setitem__(Vector_int self, std::vector< unsigned int >::difference_type i, std::vector< unsigned int >::value_type const & x)
        """
        return _pyAgrum.Vector_int___setitem__(self, *args)

    def pop(self) -> "std::vector< unsigned int >::value_type":
        r"""pop(Vector_int self) -> std::vector< unsigned int >::value_type"""
        return _pyAgrum.Vector_int_pop(self)

    def append(self, x: 'std::vector< unsigned int >::value_type const &') -> "void":
        r"""append(Vector_int self, std::vector< unsigned int >::value_type const & x)"""
        return _pyAgrum.Vector_int_append(self, x)

    def empty(self) -> "bool":
        r"""empty(Vector_int self) -> bool"""
        return _pyAgrum.Vector_int_empty(self)

    def size(self) -> "std::vector< unsigned int >::size_type":
        r"""size(Vector_int self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int_size(self)

    def swap(self, v: 'Vector_int') -> "void":
        r"""swap(Vector_int self, Vector_int v)"""
        return _pyAgrum.Vector_int_swap(self, v)

    def begin(self) -> "std::vector< unsigned int >::iterator":
        r"""begin(Vector_int self) -> std::vector< unsigned int >::iterator"""
        return _pyAgrum.Vector_int_begin(self)

    def end(self) -> "std::vector< unsigned int >::iterator":
        r"""end(Vector_int self) -> std::vector< unsigned int >::iterator"""
        return _pyAgrum.Vector_int_end(self)

    def rbegin(self) -> "std::vector< unsigned int >::reverse_iterator":
        r"""rbegin(Vector_int self) -> std::vector< unsigned int >::reverse_iterator"""
        return _pyAgrum.Vector_int_rbegin(self)

    def rend(self) -> "std::vector< unsigned int >::reverse_iterator":
        r"""rend(Vector_int self) -> std::vector< unsigned int >::reverse_iterator"""
        return _pyAgrum.Vector_int_rend(self)

    def clear(self) -> "void":
        r"""clear(Vector_int self)"""
        return _pyAgrum.Vector_int_clear(self)

    def get_allocator(self) -> "std::vector< unsigned int >::allocator_type":
        r"""get_allocator(Vector_int self) -> std::vector< unsigned int >::allocator_type"""
        return _pyAgrum.Vector_int_get_allocator(self)

    def pop_back(self) -> "void":
        r"""pop_back(Vector_int self)"""
        return _pyAgrum.Vector_int_pop_back(self)

    def erase(self, *args) -> "std::vector< unsigned int >::iterator":
        r"""
        erase(Vector_int self, std::vector< unsigned int >::iterator pos) -> std::vector< unsigned int >::iterator
        erase(Vector_int self, std::vector< unsigned int >::iterator first, std::vector< unsigned int >::iterator last) -> std::vector< unsigned int >::iterator
        """
        return _pyAgrum.Vector_int_erase(self, *args)

    def __init__(self, *args):
        r"""
        __init__(Vector_int self) -> Vector_int
        __init__(Vector_int self, Vector_int other) -> Vector_int
        __init__(Vector_int self, std::vector< unsigned int >::size_type size) -> Vector_int
        __init__(Vector_int self, std::vector< unsigned int >::size_type size, std::vector< unsigned int >::value_type const & value) -> Vector_int
        """
        _pyAgrum.Vector_int_swiginit(self, _pyAgrum.new_Vector_int(*args))

    def push_back(self, x: 'std::vector< unsigned int >::value_type const &') -> "void":
        r"""push_back(Vector_int self, std::vector< unsigned int >::value_type const & x)"""
        return _pyAgrum.Vector_int_push_back(self, x)

    def front(self) -> "std::vector< unsigned int >::value_type const &":
        r"""front(Vector_int self) -> std::vector< unsigned int >::value_type const &"""
        return _pyAgrum.Vector_int_front(self)

    def back(self) -> "std::vector< unsigned int >::value_type const &":
        r"""back(Vector_int self) -> std::vector< unsigned int >::value_type const &"""
        return _pyAgrum.Vector_int_back(self)

    def assign(self, n: 'std::vector< unsigned int >::size_type', x: 'std::vector< unsigned int >::value_type const &') -> "void":
        r"""assign(Vector_int self, std::vector< unsigned int >::size_type n, std::vector< unsigned int >::value_type const & x)"""
        return _pyAgrum.Vector_int_assign(self, n, x)

    def resize(self, *args) -> "void":
        r"""
        resize(Vector_int self, std::vector< unsigned int >::size_type new_size)
        resize(Vector_int self, std::vector< unsigned int >::size_type new_size, std::vector< unsigned int >::value_type const & x)
        """
        return _pyAgrum.Vector_int_resize(self, *args)

    def insert(self, *args) -> "void":
        r"""
        insert(Vector_int self, std::vector< unsigned int >::iterator pos, std::vector< unsigned int >::value_type const & x) -> std::vector< unsigned int >::iterator
        insert(Vector_int self, std::vector< unsigned int >::iterator pos, std::vector< unsigned int >::size_type n, std::vector< unsigned int >::value_type const & x)
        """
        return _pyAgrum.Vector_int_insert(self, *args)

    def reserve(self, n: 'std::vector< unsigned int >::size_type') -> "void":
        r"""reserve(Vector_int self, std::vector< unsigned int >::size_type n)"""
        return _pyAgrum.Vector_int_reserve(self, n)

    def capacity(self) -> "std::vector< unsigned int >::size_type":
        r"""capacity(Vector_int self) -> std::vector< unsigned int >::size_type"""
        return _pyAgrum.Vector_int_capacity(self)
    __swig_destroy__ = _pyAgrum.delete_Vector_int

# Register Vector_int in _pyAgrum:
_pyAgrum.Vector_int_swigregister(Vector_int)

class Vector_string(object):
    r"""Proxy of C++ std::vector< std::string > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def iterator(self) -> "swig::SwigPyIterator *":
        r"""iterator(Vector_string self) -> SwigPyIterator"""
        return _pyAgrum.Vector_string_iterator(self)
    def __iter__(self):
        return self.iterator()

    def __nonzero__(self) -> "bool":
        r"""__nonzero__(Vector_string self) -> bool"""
        return _pyAgrum.Vector_string___nonzero__(self)

    def __bool__(self) -> "bool":
        r"""__bool__(Vector_string self) -> bool"""
        return _pyAgrum.Vector_string___bool__(self)

    def __len__(self) -> "std::vector< std::string >::size_type":
        r"""__len__(Vector_string self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string___len__(self)

    def __getslice__(self, i: 'std::vector< std::string >::difference_type', j: 'std::vector< std::string >::difference_type') -> "std::vector< std::string,std::allocator< std::string > > *":
        r"""__getslice__(Vector_string self, std::vector< std::string >::difference_type i, std::vector< std::string >::difference_type j) -> Vector_string"""
        return _pyAgrum.Vector_string___getslice__(self, i, j)

    def __setslice__(self, *args) -> "void":
        r"""
        __setslice__(Vector_string self, std::vector< std::string >::difference_type i, std::vector< std::string >::difference_type j)
        __setslice__(Vector_string self, std::vector< std::string >::difference_type i, std::vector< std::string >::difference_type j, Vector_string v)
        """
        return _pyAgrum.Vector_string___setslice__(self, *args)

    def __delslice__(self, i: 'std::vector< std::string >::difference_type', j: 'std::vector< std::string >::difference_type') -> "void":
        r"""__delslice__(Vector_string self, std::vector< std::string >::difference_type i, std::vector< std::string >::difference_type j)"""
        return _pyAgrum.Vector_string___delslice__(self, i, j)

    def __delitem__(self, *args) -> "void":
        r"""
        __delitem__(Vector_string self, std::vector< std::string >::difference_type i)
        __delitem__(Vector_string self, PySliceObject * slice)
        """
        return _pyAgrum.Vector_string___delitem__(self, *args)

    def __getitem__(self, *args) -> "std::vector< std::string >::value_type const &":
        r"""
        __getitem__(Vector_string self, PySliceObject * slice) -> Vector_string
        __getitem__(Vector_string self, std::vector< std::string >::difference_type i) -> std::vector< std::string >::value_type const &
        """
        return _pyAgrum.Vector_string___getitem__(self, *args)

    def __setitem__(self, *args) -> "void":
        r"""
        __setitem__(Vector_string self, PySliceObject * slice, Vector_string v)
        __setitem__(Vector_string self, PySliceObject * slice)
        __setitem__(Vector_string self, std::vector< std::string >::difference_type i, std::vector< std::string >::value_type const & x)
        """
        return _pyAgrum.Vector_string___setitem__(self, *args)

    def pop(self) -> "std::vector< std::string >::value_type":
        r"""pop(Vector_string self) -> std::vector< std::string >::value_type"""
        return _pyAgrum.Vector_string_pop(self)

    def append(self, x: 'std::vector< std::string >::value_type const &') -> "void":
        r"""append(Vector_string self, std::vector< std::string >::value_type const & x)"""
        return _pyAgrum.Vector_string_append(self, x)

    def empty(self) -> "bool":
        r"""empty(Vector_string self) -> bool"""
        return _pyAgrum.Vector_string_empty(self)

    def size(self) -> "std::vector< std::string >::size_type":
        r"""size(Vector_string self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string_size(self)

    def swap(self, v: 'Vector_string') -> "void":
        r"""swap(Vector_string self, Vector_string v)"""
        return _pyAgrum.Vector_string_swap(self, v)

    def begin(self) -> "std::vector< std::string >::iterator":
        r"""begin(Vector_string self) -> std::vector< std::string >::iterator"""
        return _pyAgrum.Vector_string_begin(self)

    def end(self) -> "std::vector< std::string >::iterator":
        r"""end(Vector_string self) -> std::vector< std::string >::iterator"""
        return _pyAgrum.Vector_string_end(self)

    def rbegin(self) -> "std::vector< std::string >::reverse_iterator":
        r"""rbegin(Vector_string self) -> std::vector< std::string >::reverse_iterator"""
        return _pyAgrum.Vector_string_rbegin(self)

    def rend(self) -> "std::vector< std::string >::reverse_iterator":
        r"""rend(Vector_string self) -> std::vector< std::string >::reverse_iterator"""
        return _pyAgrum.Vector_string_rend(self)

    def clear(self) -> "void":
        r"""clear(Vector_string self)"""
        return _pyAgrum.Vector_string_clear(self)

    def get_allocator(self) -> "std::vector< std::string >::allocator_type":
        r"""get_allocator(Vector_string self) -> std::vector< std::string >::allocator_type"""
        return _pyAgrum.Vector_string_get_allocator(self)

    def pop_back(self) -> "void":
        r"""pop_back(Vector_string self)"""
        return _pyAgrum.Vector_string_pop_back(self)

    def erase(self, *args) -> "std::vector< std::string >::iterator":
        r"""
        erase(Vector_string self, std::vector< std::string >::iterator pos) -> std::vector< std::string >::iterator
        erase(Vector_string self, std::vector< std::string >::iterator first, std::vector< std::string >::iterator last) -> std::vector< std::string >::iterator
        """
        return _pyAgrum.Vector_string_erase(self, *args)

    def __init__(self, *args):
        r"""
        __init__(Vector_string self) -> Vector_string
        __init__(Vector_string self, Vector_string other) -> Vector_string
        __init__(Vector_string self, std::vector< std::string >::size_type size) -> Vector_string
        __init__(Vector_string self, std::vector< std::string >::size_type size, std::vector< std::string >::value_type const & value) -> Vector_string
        """
        _pyAgrum.Vector_string_swiginit(self, _pyAgrum.new_Vector_string(*args))

    def push_back(self, x: 'std::vector< std::string >::value_type const &') -> "void":
        r"""push_back(Vector_string self, std::vector< std::string >::value_type const & x)"""
        return _pyAgrum.Vector_string_push_back(self, x)

    def front(self) -> "std::vector< std::string >::value_type const &":
        r"""front(Vector_string self) -> std::vector< std::string >::value_type const &"""
        return _pyAgrum.Vector_string_front(self)

    def back(self) -> "std::vector< std::string >::value_type const &":
        r"""back(Vector_string self) -> std::vector< std::string >::value_type const &"""
        return _pyAgrum.Vector_string_back(self)

    def assign(self, n: 'std::vector< std::string >::size_type', x: 'std::vector< std::string >::value_type const &') -> "void":
        r"""assign(Vector_string self, std::vector< std::string >::size_type n, std::vector< std::string >::value_type const & x)"""
        return _pyAgrum.Vector_string_assign(self, n, x)

    def resize(self, *args) -> "void":
        r"""
        resize(Vector_string self, std::vector< std::string >::size_type new_size)
        resize(Vector_string self, std::vector< std::string >::size_type new_size, std::vector< std::string >::value_type const & x)
        """
        return _pyAgrum.Vector_string_resize(self, *args)

    def insert(self, *args) -> "void":
        r"""
        insert(Vector_string self, std::vector< std::string >::iterator pos, std::vector< std::string >::value_type const & x) -> std::vector< std::string >::iterator
        insert(Vector_string self, std::vector< std::string >::iterator pos, std::vector< std::string >::size_type n, std::vector< std::string >::value_type const & x)
        """
        return _pyAgrum.Vector_string_insert(self, *args)

    def reserve(self, n: 'std::vector< std::string >::size_type') -> "void":
        r"""reserve(Vector_string self, std::vector< std::string >::size_type n)"""
        return _pyAgrum.Vector_string_reserve(self, n)

    def capacity(self) -> "std::vector< std::string >::size_type":
        r"""capacity(Vector_string self) -> std::vector< std::string >::size_type"""
        return _pyAgrum.Vector_string_capacity(self)
    __swig_destroy__ = _pyAgrum.delete_Vector_string

# Register Vector_string in _pyAgrum:
_pyAgrum.Vector_string_swigregister(Vector_string)

class SetIteratorStaticEnd(object):
    r"""Proxy of C++ gum::SetIteratorStaticEnd class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self):
        r"""__init__(SetIteratorStaticEnd self) -> SetIteratorStaticEnd"""
        _pyAgrum.SetIteratorStaticEnd_swiginit(self, _pyAgrum.new_SetIteratorStaticEnd())
    __swig_destroy__ = _pyAgrum.delete_SetIteratorStaticEnd

# Register SetIteratorStaticEnd in _pyAgrum:
_pyAgrum.SetIteratorStaticEnd_swigregister(SetIteratorStaticEnd)

class GumException(Exception):
    r"""Proxy of C++ gum::Exception class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        Exception(std::string const aMsg="", std::string const aType="Generic error") -> GumException
        __init__(GumException self, GumException e) -> GumException
        """
        _pyAgrum.GumException_swiginit(self, _pyAgrum.new_GumException(*args))
    __swig_destroy__ = _pyAgrum.delete_GumException

    def what(self) -> "std::string const":
        r"""what(GumException self) -> std::string const"""
        return _pyAgrum.GumException_what(self)

    def errorContent(self) -> "std::string const":
        r"""
        errorContent(GumException self) -> std::string const

        Returns
        -------
        str
        	the error content

        """
        return _pyAgrum.GumException_errorContent(self)

    def errorType(self) -> "std::string const":
        r"""
        errorType(GumException self) -> std::string const

        Returns
        -------
        str
        	the error type

        """
        return _pyAgrum.GumException_errorType(self)

    def errorCallStack(self) -> "std::string const":
        r"""
        errorCallStack(GumException self) -> std::string const

        Returns
        -------
        str
        	the error call stack

        """
        return _pyAgrum.GumException_errorCallStack(self)

# Register GumException in _pyAgrum:
_pyAgrum.GumException_swigregister(GumException)


def __createMsg(filename: 'std::string const &', function: 'std::string const &', line: 'int const', msg: 'std::string const &') -> "std::string const":
    r"""__createMsg(std::string const & filename, std::string const & function, int const line, std::string const & msg) -> std::string const"""
    return _pyAgrum.__createMsg(filename, function, line, msg)
class IdError(GumException):
    r"""Proxy of C++ gum::IdError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(IdError self, std::string aMsg, std::string aType="ID error") -> IdError
        __init__(IdError self, IdError src) -> IdError
        """
        _pyAgrum.IdError_swiginit(self, _pyAgrum.new_IdError(*args))
    __swig_destroy__ = _pyAgrum.delete_IdError

# Register IdError in _pyAgrum:
_pyAgrum.IdError_swigregister(IdError)

class FatalError(GumException):
    r"""Proxy of C++ gum::FatalError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(FatalError self, std::string aMsg, std::string aType="Fatal error") -> FatalError
        __init__(FatalError self, FatalError src) -> FatalError
        """
        _pyAgrum.FatalError_swiginit(self, _pyAgrum.new_FatalError(*args))
    __swig_destroy__ = _pyAgrum.delete_FatalError

# Register FatalError in _pyAgrum:
_pyAgrum.FatalError_swigregister(FatalError)

class NotImplementedYet(GumException):
    r"""Proxy of C++ gum::NotImplementedYet class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NotImplementedYet self, std::string aMsg, std::string aType="Not implemented yet") -> NotImplementedYet
        __init__(NotImplementedYet self, NotImplementedYet src) -> NotImplementedYet
        """
        _pyAgrum.NotImplementedYet_swiginit(self, _pyAgrum.new_NotImplementedYet(*args))
    __swig_destroy__ = _pyAgrum.delete_NotImplementedYet

# Register NotImplementedYet in _pyAgrum:
_pyAgrum.NotImplementedYet_swigregister(NotImplementedYet)

class UndefinedIteratorValue(GumException):
    r"""Proxy of C++ gum::UndefinedIteratorValue class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(UndefinedIteratorValue self, std::string aMsg, std::string aType="Undefined iterator") -> UndefinedIteratorValue
        __init__(UndefinedIteratorValue self, UndefinedIteratorValue src) -> UndefinedIteratorValue
        """
        _pyAgrum.UndefinedIteratorValue_swiginit(self, _pyAgrum.new_UndefinedIteratorValue(*args))
    __swig_destroy__ = _pyAgrum.delete_UndefinedIteratorValue

# Register UndefinedIteratorValue in _pyAgrum:
_pyAgrum.UndefinedIteratorValue_swigregister(UndefinedIteratorValue)

class UndefinedIteratorKey(GumException):
    r"""Proxy of C++ gum::UndefinedIteratorKey class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(UndefinedIteratorKey self, std::string aMsg, std::string aType="Undefined iterator\'s key") -> UndefinedIteratorKey
        __init__(UndefinedIteratorKey self, UndefinedIteratorKey src) -> UndefinedIteratorKey
        """
        _pyAgrum.UndefinedIteratorKey_swiginit(self, _pyAgrum.new_UndefinedIteratorKey(*args))
    __swig_destroy__ = _pyAgrum.delete_UndefinedIteratorKey

# Register UndefinedIteratorKey in _pyAgrum:
_pyAgrum.UndefinedIteratorKey_swigregister(UndefinedIteratorKey)

class NullElement(GumException):
    r"""Proxy of C++ gum::NullElement class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NullElement self, std::string aMsg, std::string aType="Null element") -> NullElement
        __init__(NullElement self, NullElement src) -> NullElement
        """
        _pyAgrum.NullElement_swiginit(self, _pyAgrum.new_NullElement(*args))
    __swig_destroy__ = _pyAgrum.delete_NullElement

# Register NullElement in _pyAgrum:
_pyAgrum.NullElement_swigregister(NullElement)

class UndefinedElement(GumException):
    r"""Proxy of C++ gum::UndefinedElement class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(UndefinedElement self, std::string aMsg, std::string aType="Undefined element") -> UndefinedElement
        __init__(UndefinedElement self, UndefinedElement src) -> UndefinedElement
        """
        _pyAgrum.UndefinedElement_swiginit(self, _pyAgrum.new_UndefinedElement(*args))
    __swig_destroy__ = _pyAgrum.delete_UndefinedElement

# Register UndefinedElement in _pyAgrum:
_pyAgrum.UndefinedElement_swigregister(UndefinedElement)

class SizeError(GumException):
    r"""Proxy of C++ gum::SizeError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(SizeError self, std::string aMsg, std::string aType="incorrect size") -> SizeError
        __init__(SizeError self, SizeError src) -> SizeError
        """
        _pyAgrum.SizeError_swiginit(self, _pyAgrum.new_SizeError(*args))
    __swig_destroy__ = _pyAgrum.delete_SizeError

# Register SizeError in _pyAgrum:
_pyAgrum.SizeError_swigregister(SizeError)

class EmptySet(GumException):
    r"""Proxy of C++ gum::EmptySet class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(EmptySet self, std::string aMsg, std::string aType="Empty set") -> EmptySet
        __init__(EmptySet self, EmptySet src) -> EmptySet
        """
        _pyAgrum.EmptySet_swiginit(self, _pyAgrum.new_EmptySet(*args))
    __swig_destroy__ = _pyAgrum.delete_EmptySet

# Register EmptySet in _pyAgrum:
_pyAgrum.EmptySet_swigregister(EmptySet)

class InvalidArgumentsNumber(GumException):
    r"""Proxy of C++ gum::InvalidArgumentsNumber class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidArgumentsNumber self, std::string aMsg, std::string aType="Invalid argument number") -> InvalidArgumentsNumber
        __init__(InvalidArgumentsNumber self, InvalidArgumentsNumber src) -> InvalidArgumentsNumber
        """
        _pyAgrum.InvalidArgumentsNumber_swiginit(self, _pyAgrum.new_InvalidArgumentsNumber(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidArgumentsNumber

# Register InvalidArgumentsNumber in _pyAgrum:
_pyAgrum.InvalidArgumentsNumber_swigregister(InvalidArgumentsNumber)

class InvalidArgument(GumException):
    r"""Proxy of C++ gum::InvalidArgument class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidArgument self, std::string aMsg, std::string aType="Invalid argument") -> InvalidArgument
        __init__(InvalidArgument self, InvalidArgument src) -> InvalidArgument
        """
        _pyAgrum.InvalidArgument_swiginit(self, _pyAgrum.new_InvalidArgument(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidArgument

# Register InvalidArgument in _pyAgrum:
_pyAgrum.InvalidArgument_swigregister(InvalidArgument)

class IOError(GumException):
    r"""Proxy of C++ gum::IOError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(IOError self, std::string aMsg, std::string aType="I/O Error") -> IOError
        __init__(IOError self, IOError src) -> IOError
        """
        _pyAgrum.IOError_swiginit(self, _pyAgrum.new_IOError(*args))
    __swig_destroy__ = _pyAgrum.delete_IOError

# Register IOError in _pyAgrum:
_pyAgrum.IOError_swigregister(IOError)

class FormatNotFound(IOError):
    r"""Proxy of C++ gum::FormatNotFound class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(FormatNotFound self, std::string aMsg, std::string aType="Format not found") -> FormatNotFound
        __init__(FormatNotFound self, FormatNotFound src) -> FormatNotFound
        """
        _pyAgrum.FormatNotFound_swiginit(self, _pyAgrum.new_FormatNotFound(*args))
    __swig_destroy__ = _pyAgrum.delete_FormatNotFound

# Register FormatNotFound in _pyAgrum:
_pyAgrum.FormatNotFound_swigregister(FormatNotFound)

class OperationNotAllowed(GumException):
    r"""Proxy of C++ gum::OperationNotAllowed class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(OperationNotAllowed self, std::string aMsg, std::string aType="Operation not allowed") -> OperationNotAllowed
        __init__(OperationNotAllowed self, OperationNotAllowed src) -> OperationNotAllowed
        """
        _pyAgrum.OperationNotAllowed_swiginit(self, _pyAgrum.new_OperationNotAllowed(*args))
    __swig_destroy__ = _pyAgrum.delete_OperationNotAllowed

# Register OperationNotAllowed in _pyAgrum:
_pyAgrum.OperationNotAllowed_swigregister(OperationNotAllowed)

class NotFound(GumException):
    r"""Proxy of C++ gum::NotFound class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NotFound self, std::string aMsg, std::string aType="Object not found") -> NotFound
        __init__(NotFound self, NotFound src) -> NotFound
        """
        _pyAgrum.NotFound_swiginit(self, _pyAgrum.new_NotFound(*args))
    __swig_destroy__ = _pyAgrum.delete_NotFound

# Register NotFound in _pyAgrum:
_pyAgrum.NotFound_swigregister(NotFound)

class ReferenceError(GumException):
    r"""Proxy of C++ gum::ReferenceError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(ReferenceError self, std::string aMsg, std::string aType="Reference error") -> ReferenceError
        __init__(ReferenceError self, ReferenceError src) -> ReferenceError
        """
        _pyAgrum.ReferenceError_swiginit(self, _pyAgrum.new_ReferenceError(*args))
    __swig_destroy__ = _pyAgrum.delete_ReferenceError

# Register ReferenceError in _pyAgrum:
_pyAgrum.ReferenceError_swigregister(ReferenceError)

class OutOfBounds(ReferenceError):
    r"""Proxy of C++ gum::OutOfBounds class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(OutOfBounds self, std::string aMsg, std::string aType="Out of bound error") -> OutOfBounds
        __init__(OutOfBounds self, OutOfBounds src) -> OutOfBounds
        """
        _pyAgrum.OutOfBounds_swiginit(self, _pyAgrum.new_OutOfBounds(*args))
    __swig_destroy__ = _pyAgrum.delete_OutOfBounds

# Register OutOfBounds in _pyAgrum:
_pyAgrum.OutOfBounds_swigregister(OutOfBounds)

class OutOfLowerBound(OutOfBounds):
    r"""Proxy of C++ gum::OutOfLowerBound class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(OutOfLowerBound self, std::string aMsg, std::string aType="Out of lower bound error") -> OutOfLowerBound
        __init__(OutOfLowerBound self, OutOfLowerBound src) -> OutOfLowerBound
        """
        _pyAgrum.OutOfLowerBound_swiginit(self, _pyAgrum.new_OutOfLowerBound(*args))
    __swig_destroy__ = _pyAgrum.delete_OutOfLowerBound

# Register OutOfLowerBound in _pyAgrum:
_pyAgrum.OutOfLowerBound_swigregister(OutOfLowerBound)

class OutOfUpperBound(OutOfBounds):
    r"""Proxy of C++ gum::OutOfUpperBound class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(OutOfUpperBound self, std::string aMsg, std::string aType="Out of upper bound error") -> OutOfUpperBound
        __init__(OutOfUpperBound self, OutOfUpperBound src) -> OutOfUpperBound
        """
        _pyAgrum.OutOfUpperBound_swiginit(self, _pyAgrum.new_OutOfUpperBound(*args))
    __swig_destroy__ = _pyAgrum.delete_OutOfUpperBound

# Register OutOfUpperBound in _pyAgrum:
_pyAgrum.OutOfUpperBound_swigregister(OutOfUpperBound)

class DuplicateElement(ReferenceError):
    r"""Proxy of C++ gum::DuplicateElement class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(DuplicateElement self, std::string aMsg, std::string aType="Duplicate element") -> DuplicateElement
        __init__(DuplicateElement self, DuplicateElement src) -> DuplicateElement
        """
        _pyAgrum.DuplicateElement_swiginit(self, _pyAgrum.new_DuplicateElement(*args))
    __swig_destroy__ = _pyAgrum.delete_DuplicateElement

# Register DuplicateElement in _pyAgrum:
_pyAgrum.DuplicateElement_swigregister(DuplicateElement)

class DuplicateLabel(ReferenceError):
    r"""Proxy of C++ gum::DuplicateLabel class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(DuplicateLabel self, std::string aMsg, std::string aType="Duplicate label") -> DuplicateLabel
        __init__(DuplicateLabel self, DuplicateLabel src) -> DuplicateLabel
        """
        _pyAgrum.DuplicateLabel_swiginit(self, _pyAgrum.new_DuplicateLabel(*args))
    __swig_destroy__ = _pyAgrum.delete_DuplicateLabel

# Register DuplicateLabel in _pyAgrum:
_pyAgrum.DuplicateLabel_swigregister(DuplicateLabel)

class GraphError(GumException):
    r"""Proxy of C++ gum::GraphError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(GraphError self, std::string aMsg, std::string aType="Graph error") -> GraphError
        __init__(GraphError self, GraphError src) -> GraphError
        """
        _pyAgrum.GraphError_swiginit(self, _pyAgrum.new_GraphError(*args))
    __swig_destroy__ = _pyAgrum.delete_GraphError

# Register GraphError in _pyAgrum:
_pyAgrum.GraphError_swigregister(GraphError)

class NoNeighbour(GraphError):
    r"""Proxy of C++ gum::NoNeighbour class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NoNeighbour self, std::string aMsg, std::string aType="No neighbour found") -> NoNeighbour
        __init__(NoNeighbour self, NoNeighbour src) -> NoNeighbour
        """
        _pyAgrum.NoNeighbour_swiginit(self, _pyAgrum.new_NoNeighbour(*args))
    __swig_destroy__ = _pyAgrum.delete_NoNeighbour

# Register NoNeighbour in _pyAgrum:
_pyAgrum.NoNeighbour_swigregister(NoNeighbour)

class NoParent(GraphError):
    r"""Proxy of C++ gum::NoParent class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NoParent self, std::string aMsg, std::string aType="No parent found") -> NoParent
        __init__(NoParent self, NoParent src) -> NoParent
        """
        _pyAgrum.NoParent_swiginit(self, _pyAgrum.new_NoParent(*args))
    __swig_destroy__ = _pyAgrum.delete_NoParent

# Register NoParent in _pyAgrum:
_pyAgrum.NoParent_swigregister(NoParent)

class NoChild(GraphError):
    r"""Proxy of C++ gum::NoChild class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(NoChild self, std::string aMsg, std::string aType="No child found") -> NoChild
        __init__(NoChild self, NoChild src) -> NoChild
        """
        _pyAgrum.NoChild_swiginit(self, _pyAgrum.new_NoChild(*args))
    __swig_destroy__ = _pyAgrum.delete_NoChild

# Register NoChild in _pyAgrum:
_pyAgrum.NoChild_swigregister(NoChild)

class InvalidEdge(GraphError):
    r"""Proxy of C++ gum::InvalidEdge class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidEdge self, std::string aMsg, std::string aType="Edge invalid") -> InvalidEdge
        __init__(InvalidEdge self, InvalidEdge src) -> InvalidEdge
        """
        _pyAgrum.InvalidEdge_swiginit(self, _pyAgrum.new_InvalidEdge(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidEdge

# Register InvalidEdge in _pyAgrum:
_pyAgrum.InvalidEdge_swigregister(InvalidEdge)

class InvalidArc(GraphError):
    r"""Proxy of C++ gum::InvalidArc class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidArc self, std::string aMsg, std::string aType="Arc invalid") -> InvalidArc
        __init__(InvalidArc self, InvalidArc src) -> InvalidArc
        """
        _pyAgrum.InvalidArc_swiginit(self, _pyAgrum.new_InvalidArc(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidArc

# Register InvalidArc in _pyAgrum:
_pyAgrum.InvalidArc_swigregister(InvalidArc)

class InvalidNode(GraphError):
    r"""Proxy of C++ gum::InvalidNode class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidNode self, std::string aMsg, std::string aType="Node invalid") -> InvalidNode
        __init__(InvalidNode self, InvalidNode src) -> InvalidNode
        """
        _pyAgrum.InvalidNode_swiginit(self, _pyAgrum.new_InvalidNode(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidNode

# Register InvalidNode in _pyAgrum:
_pyAgrum.InvalidNode_swigregister(InvalidNode)

class EmptyBSTree(GraphError):
    r"""Proxy of C++ gum::EmptyBSTree class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(EmptyBSTree self, std::string aMsg, std::string aType="Empty binary search tree") -> EmptyBSTree
        __init__(EmptyBSTree self, EmptyBSTree src) -> EmptyBSTree
        """
        _pyAgrum.EmptyBSTree_swiginit(self, _pyAgrum.new_EmptyBSTree(*args))
    __swig_destroy__ = _pyAgrum.delete_EmptyBSTree

# Register EmptyBSTree in _pyAgrum:
_pyAgrum.EmptyBSTree_swigregister(EmptyBSTree)

class DefaultInLabel(GraphError):
    r"""Proxy of C++ gum::DefaultInLabel class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(DefaultInLabel self, std::string aMsg, std::string aType="Error on label") -> DefaultInLabel
        __init__(DefaultInLabel self, DefaultInLabel src) -> DefaultInLabel
        """
        _pyAgrum.DefaultInLabel_swiginit(self, _pyAgrum.new_DefaultInLabel(*args))
    __swig_destroy__ = _pyAgrum.delete_DefaultInLabel

# Register DefaultInLabel in _pyAgrum:
_pyAgrum.DefaultInLabel_swigregister(DefaultInLabel)

class InvalidDirectedCycle(GraphError):
    r"""Proxy of C++ gum::InvalidDirectedCycle class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(InvalidDirectedCycle self, std::string aMsg, std::string aType="Directed cycle detected") -> InvalidDirectedCycle
        __init__(InvalidDirectedCycle self, InvalidDirectedCycle src) -> InvalidDirectedCycle
        """
        _pyAgrum.InvalidDirectedCycle_swiginit(self, _pyAgrum.new_InvalidDirectedCycle(*args))
    __swig_destroy__ = _pyAgrum.delete_InvalidDirectedCycle

# Register InvalidDirectedCycle in _pyAgrum:
_pyAgrum.InvalidDirectedCycle_swigregister(InvalidDirectedCycle)

class CPTError(GumException):
    r"""Proxy of C++ gum::CPTError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(CPTError self, std::string aMsg, std::string aType="CPT error") -> CPTError
        __init__(CPTError self, CPTError src) -> CPTError
        """
        _pyAgrum.CPTError_swiginit(self, _pyAgrum.new_CPTError(*args))
    __swig_destroy__ = _pyAgrum.delete_CPTError

# Register CPTError in _pyAgrum:
_pyAgrum.CPTError_swigregister(CPTError)

class CPTNoSumTo1(CPTError):
    r"""Proxy of C++ gum::CPTNoSumTo1 class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(CPTNoSumTo1 self, std::string aMsg, std::string aType="CPT does not sum to 1") -> CPTNoSumTo1
        __init__(CPTNoSumTo1 self, CPTNoSumTo1 src) -> CPTNoSumTo1
        """
        _pyAgrum.CPTNoSumTo1_swiginit(self, _pyAgrum.new_CPTNoSumTo1(*args))
    __swig_destroy__ = _pyAgrum.delete_CPTNoSumTo1

# Register CPTNoSumTo1 in _pyAgrum:
_pyAgrum.CPTNoSumTo1_swigregister(CPTNoSumTo1)

class IncompatibleEvidence(GumException):
    r"""Proxy of C++ gum::IncompatibleEvidence class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(IncompatibleEvidence self, std::string aMsg, std::string aType="several evidence/CPT are incompatible together (proba=0)") -> IncompatibleEvidence
        __init__(IncompatibleEvidence self, IncompatibleEvidence src) -> IncompatibleEvidence
        """
        _pyAgrum.IncompatibleEvidence_swiginit(self, _pyAgrum.new_IncompatibleEvidence(*args))
    __swig_destroy__ = _pyAgrum.delete_IncompatibleEvidence

# Register IncompatibleEvidence in _pyAgrum:
_pyAgrum.IncompatibleEvidence_swigregister(IncompatibleEvidence)

class FactoryError(GumException):
    r"""Proxy of C++ gum::FactoryError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(FactoryError self, std::string aMsg, std::string aType="factory error") -> FactoryError
        __init__(FactoryError self, FactoryError src) -> FactoryError
        """
        _pyAgrum.FactoryError_swiginit(self, _pyAgrum.new_FactoryError(*args))
    __swig_destroy__ = _pyAgrum.delete_FactoryError

# Register FactoryError in _pyAgrum:
_pyAgrum.FactoryError_swigregister(FactoryError)

class FactoryInvalidState(FactoryError):
    r"""Proxy of C++ gum::FactoryInvalidState class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(FactoryInvalidState self, std::string aMsg, std::string aType="invalid state error") -> FactoryInvalidState
        __init__(FactoryInvalidState self, FactoryInvalidState src) -> FactoryInvalidState
        """
        _pyAgrum.FactoryInvalidState_swiginit(self, _pyAgrum.new_FactoryInvalidState(*args))
    __swig_destroy__ = _pyAgrum.delete_FactoryInvalidState

# Register FactoryInvalidState in _pyAgrum:
_pyAgrum.FactoryInvalidState_swigregister(FactoryInvalidState)

class WrongType(FactoryError):
    r"""Proxy of C++ gum::WrongType class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(WrongType self, std::string aMsg, std::string aType="wrong type for this operation") -> WrongType
        __init__(WrongType self, WrongType src) -> WrongType
        """
        _pyAgrum.WrongType_swiginit(self, _pyAgrum.new_WrongType(*args))
    __swig_destroy__ = _pyAgrum.delete_WrongType

# Register WrongType in _pyAgrum:
_pyAgrum.WrongType_swigregister(WrongType)

class WrongClassElement(FactoryError):
    r"""Proxy of C++ gum::WrongClassElement class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(WrongClassElement self, std::string aMsg, std::string aType="Wrong ClassElement") -> WrongClassElement
        __init__(WrongClassElement self, WrongClassElement src) -> WrongClassElement
        """
        _pyAgrum.WrongClassElement_swiginit(self, _pyAgrum.new_WrongClassElement(*args))
    __swig_destroy__ = _pyAgrum.delete_WrongClassElement

# Register WrongClassElement in _pyAgrum:
_pyAgrum.WrongClassElement_swigregister(WrongClassElement)

class TypeError(FactoryError):
    r"""Proxy of C++ gum::TypeError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(TypeError self, std::string aMsg, std::string aType="Wrong subtype or subclass") -> TypeError
        __init__(TypeError self, TypeError src) -> TypeError
        """
        _pyAgrum.TypeError_swiginit(self, _pyAgrum.new_TypeError(*args))
    __swig_destroy__ = _pyAgrum.delete_TypeError

# Register TypeError in _pyAgrum:
_pyAgrum.TypeError_swigregister(TypeError)

class LearningError(GumException):
    r"""Proxy of C++ gum::LearningError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(LearningError self, std::string aMsg, std::string aType="Factory error") -> LearningError
        __init__(LearningError self, LearningError src) -> LearningError
        """
        _pyAgrum.LearningError_swiginit(self, _pyAgrum.new_LearningError(*args))
    __swig_destroy__ = _pyAgrum.delete_LearningError

# Register LearningError in _pyAgrum:
_pyAgrum.LearningError_swigregister(LearningError)

class IncompatibleScoreApriori(LearningError):
    r"""Proxy of C++ gum::IncompatibleScoreApriori class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(IncompatibleScoreApriori self, std::string aMsg, std::string aType="Incompatbile (maybe implicit) priors") -> IncompatibleScoreApriori
        __init__(IncompatibleScoreApriori self, IncompatibleScoreApriori src) -> IncompatibleScoreApriori
        """
        _pyAgrum.IncompatibleScoreApriori_swiginit(self, _pyAgrum.new_IncompatibleScoreApriori(*args))
    __swig_destroy__ = _pyAgrum.delete_IncompatibleScoreApriori

# Register IncompatibleScoreApriori in _pyAgrum:
_pyAgrum.IncompatibleScoreApriori_swigregister(IncompatibleScoreApriori)

class PossiblyIncompatibleScoreApriori(LearningError):
    r"""Proxy of C++ gum::PossiblyIncompatibleScoreApriori class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(PossiblyIncompatibleScoreApriori self, std::string aMsg, std::string aType="Possible incompatibilty between score and prior") -> PossiblyIncompatibleScoreApriori
        __init__(PossiblyIncompatibleScoreApriori self, PossiblyIncompatibleScoreApriori src) -> PossiblyIncompatibleScoreApriori
        """
        _pyAgrum.PossiblyIncompatibleScoreApriori_swiginit(self, _pyAgrum.new_PossiblyIncompatibleScoreApriori(*args))
    __swig_destroy__ = _pyAgrum.delete_PossiblyIncompatibleScoreApriori

# Register PossiblyIncompatibleScoreApriori in _pyAgrum:
_pyAgrum.PossiblyIncompatibleScoreApriori_swigregister(PossiblyIncompatibleScoreApriori)

class DatabaseError(LearningError):
    r"""Proxy of C++ gum::DatabaseError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(DatabaseError self, std::string aMsg, std::string aType="Database error") -> DatabaseError
        __init__(DatabaseError self, DatabaseError src) -> DatabaseError
        """
        _pyAgrum.DatabaseError_swiginit(self, _pyAgrum.new_DatabaseError(*args))
    __swig_destroy__ = _pyAgrum.delete_DatabaseError

# Register DatabaseError in _pyAgrum:
_pyAgrum.DatabaseError_swigregister(DatabaseError)

class MissingVariableInDatabase(LearningError):
    r"""Proxy of C++ gum::MissingVariableInDatabase class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(MissingVariableInDatabase self, std::string aMsg, std::string aType="Missing variable name in database") -> MissingVariableInDatabase
        __init__(MissingVariableInDatabase self, MissingVariableInDatabase src) -> MissingVariableInDatabase
        """
        _pyAgrum.MissingVariableInDatabase_swiginit(self, _pyAgrum.new_MissingVariableInDatabase(*args))
    __swig_destroy__ = _pyAgrum.delete_MissingVariableInDatabase

# Register MissingVariableInDatabase in _pyAgrum:
_pyAgrum.MissingVariableInDatabase_swigregister(MissingVariableInDatabase)

class MissingValueInDatabase(LearningError):
    r"""Proxy of C++ gum::MissingValueInDatabase class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(MissingValueInDatabase self, std::string aMsg, std::string aType="The database contains some missing values") -> MissingValueInDatabase
        __init__(MissingValueInDatabase self, MissingValueInDatabase src) -> MissingValueInDatabase
        """
        _pyAgrum.MissingValueInDatabase_swiginit(self, _pyAgrum.new_MissingValueInDatabase(*args))
    __swig_destroy__ = _pyAgrum.delete_MissingValueInDatabase

# Register MissingValueInDatabase in _pyAgrum:
_pyAgrum.MissingValueInDatabase_swigregister(MissingValueInDatabase)

class UnknownLabelInDatabase(LearningError):
    r"""Proxy of C++ gum::UnknownLabelInDatabase class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(UnknownLabelInDatabase self, std::string aMsg, std::string aType="Unknown label found in database") -> UnknownLabelInDatabase
        __init__(UnknownLabelInDatabase self, UnknownLabelInDatabase src) -> UnknownLabelInDatabase
        """
        _pyAgrum.UnknownLabelInDatabase_swiginit(self, _pyAgrum.new_UnknownLabelInDatabase(*args))
    __swig_destroy__ = _pyAgrum.delete_UnknownLabelInDatabase

# Register UnknownLabelInDatabase in _pyAgrum:
_pyAgrum.UnknownLabelInDatabase_swigregister(UnknownLabelInDatabase)

class SyntaxError(IOError):
    r"""Proxy of C++ gum::SyntaxError class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""__init__(SyntaxError self, std::string const & aMsg, gum::Size nol, gum::Size noc, std::string aType="Syntax Error") -> SyntaxError"""
        _pyAgrum.SyntaxError_swiginit(self, _pyAgrum.new_SyntaxError(*args))

    def col(self) -> "gum::Size":
        r"""
        col(SyntaxError self) -> gum::Size

        Returns
        -------
        int
        	the indice of the colonne of the error

        """
        return _pyAgrum.SyntaxError_col(self)

    def line(self) -> "gum::Size":
        r"""
        line(SyntaxError self) -> gum::Size

        Returns
        -------
        int
        	the indice of the line of the error

        """
        return _pyAgrum.SyntaxError_line(self)
    __swig_destroy__ = _pyAgrum.delete_SyntaxError

# Register SyntaxError in _pyAgrum:
_pyAgrum.SyntaxError_swigregister(SyntaxError)


def randomValue(max: 'gum::Size const'=2) -> "gum::Idx":
    r"""
    randomValue(gum::Size const max=2) -> gum::Idx

    Returns
    -------
    int
      a value randomly drawn (0 or 1)

    """
    return _pyAgrum.randomValue(max)

def randomProba() -> "double":
    r"""
    randomProba() -> double

    Returns
    -------
    double
        a random number between 0 and 1 included (i.e. a proba). 

    """
    return _pyAgrum.randomProba()

def randomGeneratorSeed() -> "unsigned int":
    r"""
    randomGeneratorSeed() -> unsigned int

    Returns
    -------
    int
      a randomly generated seed

    """
    return _pyAgrum.randomGeneratorSeed()

def initRandom(seed: 'unsigned int'=0) -> "void":
    r"""
    initRandom(unsigned int seed=0)

    Initialize random generator seed.

    Parameters
    ----------
    seed : int
      the seed used to initialize the random generator

    """
    return _pyAgrum.initRandom(seed)

def getRandomGenerator(seed: 'unsigned int'=0) -> "std::default_random_engine":
    r"""
    getRandomGenerator(unsigned int seed=0) -> std::default_random_engine

    Returns
    -------
    tbw
      the random generator

    """
    return _pyAgrum.getRandomGenerator(seed)

def isOMP() -> "bool":
    r"""
    isOMP() -> bool

    Returns
    -------
    bool
      True if OMP has been set at compilation, False otherwise

    """
    return _pyAgrum.isOMP()

def setNumberOfThreads(number: 'unsigned int') -> "void":
    r"""
    setNumberOfThreads(unsigned int number)

    To avoid spare cycles (less then 100% CPU occupied), use more threads than logical processors (x2 is a good all-around value). 

    Returns
    -------
    number : int
      the number of threads to be used

    """
    return _pyAgrum.setNumberOfThreads(number)

def getMaxNumberOfThreads() -> "unsigned int":
    r"""
    getMaxNumberOfThreads() -> unsigned int

    Returns
    -------
    int
      the max number of threads

    """
    return _pyAgrum.getMaxNumberOfThreads()

def getThreadNumber() -> "unsigned int":
    r"""
    getThreadNumber() -> unsigned int

    Returns
    -------
    int
      the number of thread

    """
    return _pyAgrum.getThreadNumber()

def getNumberOfRunningThreads() -> "unsigned int":
    r"""
    getNumberOfRunningThreads() -> unsigned int

    Returns
    -------
    int
      the number of running threads

    """
    return _pyAgrum.getNumberOfRunningThreads()

def getNumberOfLogicalProcessors() -> "unsigned int":
    r"""
    getNumberOfLogicalProcessors() -> unsigned int

    Returns
    -------
    int
      the number of logical processors

    """
    return _pyAgrum.getNumberOfLogicalProcessors()

def setNestedParallelism(value: 'bool') -> "void":
    r"""
    setNestedParallelism(bool value)

    Parameters
    ----------
    value : bool
      True if nested parallelism should be activated

    """
    return _pyAgrum.setNestedParallelism(value)

def getNestedParallelism() -> "bool":
    r"""
    getNestedParallelism() -> bool

    Returns
    -------
    bool
      True if nested parallelism is enabled

    """
    return _pyAgrum.getNestedParallelism()

def setDynamicThreadsNumber(value: 'bool') -> "void":
    r"""
    setDynamicThreadsNumber(bool value)

    Parameters
    ----------
    value : bool
      True if the number of threads should be dynamic

    """
    return _pyAgrum.setDynamicThreadsNumber(value)

def getDynamicThreadsNumber() -> "bool":
    r"""
    getDynamicThreadsNumber() -> bool

    Returns
    -------
    bool
      True if dynamic threads number is enabled

    """
    return _pyAgrum.getDynamicThreadsNumber()
VarType_Discretized = _pyAgrum.VarType_Discretized

VarType_Labelized = _pyAgrum.VarType_Labelized

VarType_Range = _pyAgrum.VarType_Range

VarType_Continuous = _pyAgrum.VarType_Continuous

class Variable(object):
    r"""

    Abstract class used by DiscreteVariable.

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyAgrum.delete_Variable

    def clone(self) -> "gum::Variable *":
        r"""
        clone(Variable self) -> Variable

        Copy factory

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a pointer on a new copy of this

        """
        return _pyAgrum.Variable_clone(self)

    def __eq__(self, aRV: 'Variable') -> "bool":
        r"""__eq__(Variable self, Variable aRV) -> bool"""
        return _pyAgrum.Variable___eq__(self, aRV)

    def __ne__(self, aRV: 'Variable') -> "bool":
        r"""__ne__(Variable self, Variable aRV) -> bool"""
        return _pyAgrum.Variable___ne__(self, aRV)

    def setName(self, theValue: 'std::string const &') -> "void":
        r"""
        setName(Variable self, std::string const & theValue)

        sets the name of the variable.

        Parameters
        ----------
        theValue : str
        	the new description of the variable

        """
        return _pyAgrum.Variable_setName(self, theValue)

    def name(self) -> "std::string const &":
        r"""
        name(Variable self) -> std::string const &

        Returns
        -------
        str
        	the name of the variable

        """
        return _pyAgrum.Variable_name(self)

    def setDescription(self, theValue: 'std::string const &') -> "void":
        r"""
        setDescription(Variable self, std::string const & theValue)

        set the description of the variable.

        Parameters
        ----------
        theValue : str
        	the new description of the variable

        """
        return _pyAgrum.Variable_setDescription(self, theValue)

    def description(self) -> "std::string const &":
        r"""
        description(Variable self) -> std::string const &

        Returns
        -------
        str
        	the description of the variable

        """
        return _pyAgrum.Variable_description(self)

    def varType(self) -> "gum::VarType":
        r"""varType(Variable self) -> gum::VarType"""
        return _pyAgrum.Variable_varType(self)

    def domain(self) -> "std::string const":
        r"""domain(Variable self) -> std::string const"""
        return _pyAgrum.Variable_domain(self)

# Register Variable in _pyAgrum:
_pyAgrum.Variable_swigregister(Variable)

class DiscreteVariable(Variable):
    r"""

    DiscreteVariable is the base class for discrete random variable.

    Available constructors:

        ``DiscreteVariable(aName, aDesc='') -> DiscreteVariable``

        ``DiscreteVariable(aDRV) -> DiscreteVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    aDRV: pyAgrum.DiscreteVariable
      Another `DiscreteVariable` that will be copied

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __swig_destroy__ = _pyAgrum.delete_DiscreteVariable

    def clone(self) -> "gum::DiscreteVariable *":
        r"""
        clone(DiscreteVariable self) -> DiscreteVariable

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a copy of the DiscreteVariable

        """
        return _pyAgrum.DiscreteVariable_clone(self)

    def empty(self) -> "bool":
        r"""
        empty(DiscreteVariable self) -> bool

        Returns
        -------
        bool
        	True if the domain size < 2

        """
        return _pyAgrum.DiscreteVariable_empty(self)

    def domainSize(self) -> "gum::Size":
        r"""
        domainSize(DiscreteVariable self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.DiscreteVariable_domainSize(self)

    def labels(self) -> "std::vector< std::string,std::allocator< std::string > >":
        r"""
        labels(DiscreteVariable self) -> Vector_string

        Returns
        -------
        tuple
        	a tuple containing the labels

        """
        return _pyAgrum.DiscreteVariable_labels(self)

    def numerical(self, indice: 'gum::Idx') -> "double":
        r"""
        numerical(DiscreteVariable self, gum::Idx indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.DiscreteVariable_numerical(self, indice)

    def varType(self) -> "gum::VarType":
        r"""
        varType(DiscreteVariable self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.DiscreteVariable_varType(self)

    def __eq__(self, aRV: 'DiscreteVariable') -> "bool":
        r"""__eq__(DiscreteVariable self, DiscreteVariable aRV) -> bool"""
        return _pyAgrum.DiscreteVariable___eq__(self, aRV)

    def __ne__(self, aRV: 'DiscreteVariable') -> "bool":
        r"""__ne__(DiscreteVariable self, DiscreteVariable aRV) -> bool"""
        return _pyAgrum.DiscreteVariable___ne__(self, aRV)

    def index(self, label: 'std::string const &') -> "gum::Idx":
        r"""
        index(DiscreteVariable self, std::string const & label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.DiscreteVariable_index(self, label)

    def label(self, i: 'gum::Idx') -> "std::string":
        r"""
        label(DiscreteVariable self, gum::Idx i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.DiscreteVariable_label(self, i)

    def toStringWithDescription(self) -> "std::string const":
        r"""
        toStringWithDescription(DiscreteVariable self) -> std::string const

        Returns
        -------
        str
        	a description of the variable

        """
        return _pyAgrum.DiscreteVariable_toStringWithDescription(self)

    def domain(self) -> "std::string const":
        r"""
        domain(DiscreteVariable self) -> std::string const

        Returns
        -------
        str
        	the domain of the variable

        """
        return _pyAgrum.DiscreteVariable_domain(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(DiscreteVariable self) -> std::string"""
        return _pyAgrum.DiscreteVariable___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(DiscreteVariable self) -> std::string"""
        return _pyAgrum.DiscreteVariable___str__(self)

    def __getitem__(self,label):   # adding the y() function here
        return self.index(label)


    def toLabelizedVar(self) -> "gum::LabelizedVariable":
        r"""
        toLabelizedVar(DiscreteVariable self) -> LabelizedVariable

        Returns
        -------
        pyAgrum.LabelizedVariable
        	the labelized variable

        Raises
        ------
        gum.RuntimeError
        	If the variable is not a LabelizedVariable

        """
        return _pyAgrum.DiscreteVariable_toLabelizedVar(self)

    def toRangeVar(self) -> "gum::RangeVariable":
        r"""
        toRangeVar(DiscreteVariable self) -> RangeVariable

        Returns
        -------
        pyAgrum.RangeVariable
        	the range variable

        Raises
        ------
        gum.RuntimeError
        	If the variable is not a RangeVariable

        """
        return _pyAgrum.DiscreteVariable_toRangeVar(self)

    def toDiscretizedVar(self) -> "gum::DiscretizedVariable< double >":
        r"""
        toDiscretizedVar(DiscreteVariable self) -> DiscretizedVariable

        Returns
        -------
        pyAgrum.DiscretizedVariable
        	the discretized variable

        Raises
        ------
        gum.RuntimeError 
        	If the variable is not a DiscretizedVariable

        """
        return _pyAgrum.DiscreteVariable_toDiscretizedVar(self)

# Register DiscreteVariable in _pyAgrum:
_pyAgrum.DiscreteVariable_swigregister(DiscreteVariable)

class LabelizedVariable(DiscreteVariable):
    r"""

    LabelizedVariable is a discrete random variable with a customizable sequence of labels.

    Available constructors:

        ``LabelizedVariable(aName, aDesc='', nbrLabel=2) -> LabelizedVariable``

        ``LabelizedVariable(aName, aDesc='') -> LabelizedVariable``

        ``LabelizedVariable(aLDRV) -> LabelizedVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    nbrLabel: int
      The number of labels to create (2 by default)
    aLDRV: pyAgrum.LabelizedVariable
      Another `LabelizedVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> # creating a variable with 3 labels : '0', '1' and '2'
    >>> va=gum.LabelizedVariable('a','a labelized variable',3)
    >>> print(va)
    >>> ## a<0,1,2>
    >>>
    >>> va.addLabel('foo')
    >>> print(va)
    >>> ## a<0,1,2,foo>
    >>>
    >>> va.chgLabel(1,'bar')
    >>> print(va)
    >>> a<0,bar,2,foo>
    >>>
    >>> vb=gum.LabelizedVariable('b','b',0).addLabel('A').addLabel('B').addLabel('C')
    >>> print(vb)
    >>> ## b<A,B,C>
    >>> 
    >>> vb.labels()
    >>> ## ('A', 'B', 'C')
    >>> 
    >>> vb.isLabel('E')
    >>> ## False
    >>> 
    >>> vb.label(2)
    >>> ## 'B'

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(LabelizedVariable self, std::string const & aName, std::string const & aDesc="", gum::Size const nbrLabel=2) -> LabelizedVariable
        __init__(LabelizedVariable self, std::string const & aName, std::string const & aDesc, Vector_string labels) -> LabelizedVariable
        __init__(LabelizedVariable self, LabelizedVariable aLDRV) -> LabelizedVariable
        """
        _pyAgrum.LabelizedVariable_swiginit(self, _pyAgrum.new_LabelizedVariable(*args))
    __swig_destroy__ = _pyAgrum.delete_LabelizedVariable

    def clone(self) -> "gum::LabelizedVariable *":
        r"""
        clone(LabelizedVariable self) -> LabelizedVariable

        Returns
        -------
        pyAgrum.LabelizedVariable
        	a copy of the LabelizedVariable

        """
        return _pyAgrum.LabelizedVariable_clone(self)

    def index(self, label: 'std::string const &') -> "gum::Idx":
        r"""
        index(LabelizedVariable self, std::string const & label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.LabelizedVariable_index(self, label)

    def isLabel(self, aLabel: 'std::string const &') -> "bool":
        r"""
        isLabel(LabelizedVariable self, std::string const & aLabel) -> bool

        Indicates whether the variable already has the label passed in argument

        Parameters
        ----------
        aLabel : str
        	the label to be tested

        Returns
        -------
        bool
        	True if the label already exists

        """
        return _pyAgrum.LabelizedVariable_isLabel(self, aLabel)

    def addLabel(self,*args):
        """
        Add a label with a new index (we assume that we will NEVER remove a label).

        Parameters
        ----------
        aLabel : str
            the label to be added to the labelized variable

        Returns
        -------
        pyAgrum.LabelizedVariable
            the labelized variable

        Raises
        ------
        gum.DuplicateElement
            If the variable already contains the label
        """
        _pyAgrum.LabelizedVariable_addLabel(self,*args)
        return self



    def changeLabel(self, pos: 'gum::Idx', aLabel: 'std::string const &') -> "void":
        r"""
        changeLabel(LabelizedVariable self, gum::Idx pos, std::string const & aLabel)

        Change the label at the specified index

        Parameters
        ----------
        pos : int
        	the index of the label to be changed
        aLabel : str
        	the label to be added to the labelized variable

        Raises
        ------
        gum.DuplicatedElement
          If the variable already contains the new label
        gum.OutOfBounds
          If the index is greater than the size of the variable

        """
        return _pyAgrum.LabelizedVariable_changeLabel(self, pos, aLabel)

    def eraseLabels(self) -> "void":
        r"""
        eraseLabels(LabelizedVariable self)

        Erase all the labels from the variable.

        """
        return _pyAgrum.LabelizedVariable_eraseLabels(self)

    def label(self, i: 'gum::Idx') -> "std::string":
        r"""
        label(LabelizedVariable self, gum::Idx i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.LabelizedVariable_label(self, i)

    def posLabel(self, label: 'std::string const &') -> "gum::Idx":
        r"""posLabel(LabelizedVariable self, std::string const & label) -> gum::Idx"""
        return _pyAgrum.LabelizedVariable_posLabel(self, label)

    def numerical(self, indice: 'gum::Idx') -> "double":
        r"""
        numerical(LabelizedVariable self, gum::Idx indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.LabelizedVariable_numerical(self, indice)

    def domainSize(self) -> "gum::Size":
        r"""
        domainSize(LabelizedVariable self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.LabelizedVariable_domainSize(self)

    def varType(self) -> "gum::VarType":
        r"""
        varType(LabelizedVariable self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.LabelizedVariable_varType(self)

    def domain(self) -> "std::string const":
        r"""
        domain(LabelizedVariable self) -> std::string const

        Returns
        -------
        str
            the domain of the variable as a string

        """
        return _pyAgrum.LabelizedVariable_domain(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(LabelizedVariable self) -> std::string"""
        return _pyAgrum.LabelizedVariable___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(LabelizedVariable self) -> std::string"""
        return _pyAgrum.LabelizedVariable___str__(self)

# Register LabelizedVariable in _pyAgrum:
_pyAgrum.LabelizedVariable_swigregister(LabelizedVariable)

class RangeVariable(DiscreteVariable):
    r"""

    RangeVariable represents a variable with a range of integers as domain.

    Available constructors:

    	``RangeVariable(aName, aDesc='',minVal, maxVal) -> RangeVariable``

    	``RangeVariable(aName, aDesc='',minVal) -> RangeVariable``

      ``RangeVariable(aName, aDesc='') -> RangeVariable``

      ``RangeVariable(aRV) -> RangeVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    minVal : int
      The minimal integer of the interval
    maxVal : int
      The maximal integer of the interval
    aDV: pyAgrum.RangeVariable
      Another `RangeVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> vI=gum.gum.RangeVariable('I','I in [4,10]',4,10)
    >>> print(vI)
    >>> ## I[4-10]
    >>> 
    >>> vX.maxVal()
    >>> ## 10
    >>> 
    >>> vX.belongs(1)
    >>> ## False
    >>> 
    >>> # where is the value 5 ?
    >>> vX.index('5')
    >>> ## 1
    >>> 
    >>> vi.labels()
    >>> ## ('4', '5', '6', '7', '8', '9', '10')

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(RangeVariable self, std::string const & aName, std::string const & aDesc, long minVal=0, long maxVal=1) -> RangeVariable
        __init__(RangeVariable self, RangeVariable aDRV) -> RangeVariable
        """
        _pyAgrum.RangeVariable_swiginit(self, _pyAgrum.new_RangeVariable(*args))
    __swig_destroy__ = _pyAgrum.delete_RangeVariable

    def clone(self) -> "gum::DiscreteVariable *":
        r"""
        clone(RangeVariable self) -> DiscreteVariable

        Returns
        -------
        pyAgrum.RangeVariable
        	a copy of the RangeVariable

        """
        return _pyAgrum.RangeVariable_clone(self)

    def domainSize(self) -> "gum::Size":
        r"""
        domainSize(RangeVariable self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.RangeVariable_domainSize(self)

    def varType(self) -> "gum::VarType":
        r"""
        varType(RangeVariable self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.RangeVariable_varType(self)

    def label(self, indice: 'gum::Idx') -> "std::string":
        r"""
        label(RangeVariable self, gum::Idx indice) -> std::string

        Parameters
        ----------
        indice : int
          the index of the label we wish to return

        Returns
        -------
        str
          the indice-th label

        Raises
        ------
        gum.OutOfBound
          If the variable does not contain the label

        """
        return _pyAgrum.RangeVariable_label(self, indice)

    def numerical(self, indice: 'gum::Idx') -> "double":
        r"""
        numerical(RangeVariable self, gum::Idx indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.RangeVariable_numerical(self, indice)

    def minVal(self) -> "long":
        r"""
        minVal(RangeVariable self) -> long

        Returns
        -------
        long :
          the lower bound of the variable

        """
        return _pyAgrum.RangeVariable_minVal(self)

    def setMinVal(self, minVal: 'long') -> "void":
        r"""
        setMinVal(RangeVariable self, long minVal)

        Set a new value of the lower bound

        Parameters
        ----------
        minVal : long
          The new value of the lower bound

        Warnings
        --------
        An error should be raised if the value is higher than the upper bound.

        """
        return _pyAgrum.RangeVariable_setMinVal(self, minVal)

    def maxVal(self) -> "long":
        r"""
        maxVal(RangeVariable self) -> long

        Returns
        -------
        long :
          the upper bound of the variable.

        """
        return _pyAgrum.RangeVariable_maxVal(self)

    def setMaxVal(self, maxVal: 'long') -> "void":
        r"""
        setMaxVal(RangeVariable self, long maxVal)

        Set a new value of the upper bound

        Parameters
        ----------
        maxVal : long
          The new value of the upper bound

        Warnings
        --------
        An error should be raised if the value is lower than the lower bound.

        """
        return _pyAgrum.RangeVariable_setMaxVal(self, maxVal)

    def belongs(self, val: 'long') -> "bool":
        r"""
        belongs(RangeVariable self, long val) -> bool

        Parameters
        ----------
        val : long
          the value to be tested

        Returns
        -------
        bool:
          True if the value in parameters belongs to the variable's interval.

        """
        return _pyAgrum.RangeVariable_belongs(self, val)

    def index(self, arg2: 'std::string const &') -> "gum::Idx":
        r"""
        index(RangeVariable self, std::string const & arg2) -> gum::Idx

        Parameters
        ----------
        arg2 : str
          a label

        Returns
        -------
        int
          the indice of the label

        """
        return _pyAgrum.RangeVariable_index(self, arg2)

    def domain(self) -> "std::string const":
        r"""
        domain(RangeVariable self) -> std::string const

        Returns
        -------
        str
        	the domain of the variable

        """
        return _pyAgrum.RangeVariable_domain(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(RangeVariable self) -> std::string"""
        return _pyAgrum.RangeVariable___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(RangeVariable self) -> std::string"""
        return _pyAgrum.RangeVariable___str__(self)

# Register RangeVariable in _pyAgrum:
_pyAgrum.RangeVariable_swigregister(RangeVariable)

class IDiscretizedVariable(DiscreteVariable):
    r"""Proxy of C++ gum::IDiscretizedVariable class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyAgrum.delete_IDiscretizedVariable

    def clone(self) -> "gum::IDiscretizedVariable *":
        r"""
        clone(IDiscretizedVariable self) -> IDiscretizedVariable

        Returns
        -------
        pyAgrum.DiscreteVariable
        	a copy of the DiscreteVariable

        """
        return _pyAgrum.IDiscretizedVariable_clone(self)

# Register IDiscretizedVariable in _pyAgrum:
_pyAgrum.IDiscretizedVariable_swigregister(IDiscretizedVariable)

class Edge(object):
    r"""

    pyAgrum.Edge is the representation of an arc between two nodes represented by int : the first and the second.

    Available constructors :
        ``Edge(aN1,aN2) -> Edge``

        ``Edge(src) -> Edge``

    Parameters
    ----------
    aN1 : int
      the nodeId of the first node
    aN2 : int
      the nodeId of the secondnode
    src: pyAgrum.Edge
      the Edge to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(Edge self, gum::NodeId aN1, gum::NodeId aN2) -> Edge
        __init__(Edge self, Edge src) -> Edge
        """
        _pyAgrum.Edge_swiginit(self, _pyAgrum.new_Edge(*args))
    __swig_destroy__ = _pyAgrum.delete_Edge

    def other(self, id: 'gum::NodeId') -> "gum::NodeId":
        r"""
        other(Edge self, gum::NodeId id) -> gum::NodeId

        Parameters
        ----------
        id : int
          the nodeId of one of the nodes of the Edge


        Returns
        ------
        int
          the nodeId of the other node

        """
        return _pyAgrum.Edge_other(self, id)

    def first(self) -> "gum::NodeId":
        r"""
        first(Edge self) -> gum::NodeId

        Returns
        ------
        int
          the nodeId of the first node of the arc (the tail)

        """
        return _pyAgrum.Edge_first(self)

    def second(self) -> "gum::NodeId":
        r"""
        second(Edge self) -> gum::NodeId

        Returns
        ------
        int
          the nodeId of the second node of the arc (the head)

        """
        return _pyAgrum.Edge_second(self)

    def __eq__(self, src: 'Edge') -> "bool":
        r"""__eq__(Edge self, Edge src) -> bool"""
        return _pyAgrum.Edge___eq__(self, src)

    def __ne__(self, src: 'Edge') -> "bool":
        r"""__ne__(Edge self, Edge src) -> bool"""
        return _pyAgrum.Edge___ne__(self, src)

# Register Edge in _pyAgrum:
_pyAgrum.Edge_swigregister(Edge)

class Arc(object):
    r"""

    pyAgrum.Arc is the representation of an arc between two nodes represented by int : the head and the tail.

    Available constructors:
        ``Arc(tail, head) -> Arc``

        ``Arc(src) -> Arc``

    Parameters
    ----------
    tail : int
      the tail
    head : int
      the head
    src : :class: Arc
      the Arc to copy


    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(Arc self, gum::NodeId tail, gum::NodeId head) -> Arc
        __init__(Arc self, Arc src) -> Arc
        """
        _pyAgrum.Arc_swiginit(self, _pyAgrum.new_Arc(*args))
    __swig_destroy__ = _pyAgrum.delete_Arc

    def tail(self) -> "gum::NodeId":
        r"""
        tail(Arc self) -> gum::NodeId

        Returns
        -------
        int
          the id of the tail node

        """
        return _pyAgrum.Arc_tail(self)

    def head(self) -> "gum::NodeId":
        r"""
        head(Arc self) -> gum::NodeId

        Returns
        ------
        int
          the id of the head node

        """
        return _pyAgrum.Arc_head(self)

    def other(self, id: 'gum::NodeId') -> "gum::NodeId":
        r"""
        other(Arc self, gum::NodeId id) -> gum::NodeId

        Parameters
        ----------
        id : int
          the nodeId of the head or the tail


        Returns
        -------
        int
          the nodeId of the other node

        """
        return _pyAgrum.Arc_other(self, id)

    def first(self) -> "gum::NodeId":
        r"""
        first(Arc self) -> gum::NodeId

        Returns
        -------
        int
          the nodeId of the first node of the arc (the tail)

        """
        return _pyAgrum.Arc_first(self)

    def second(self) -> "gum::NodeId":
        r"""
        second(Arc self) -> gum::NodeId

        Returns
        -------
        int
          the nodeId of the second node of the arc (the head)

        """
        return _pyAgrum.Arc_second(self)

    def __eq__(self, src: 'Arc') -> "bool":
        r"""__eq__(Arc self, Arc src) -> bool"""
        return _pyAgrum.Arc___eq__(self, src)

    def __ne__(self, src: 'Arc') -> "bool":
        r"""__ne__(Arc self, Arc src) -> bool"""
        return _pyAgrum.Arc___ne__(self, src)

# Register Arc in _pyAgrum:
_pyAgrum.Arc_swigregister(Arc)

class UndiGraph(object):
    r"""

    UndiGraph represents an Undirected Graph.

    Available constructors:
        ``UndiGraph() -> UndiGraph``

        ``UndiGraph(src) -> UndiGraph``

    Parameters
    ----------
    src : :class: UndiGraph
      the UndiGraph to copy


    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(UndiGraph self, gum::Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=True, gum::Size edges_size=HashTableConst::default_size, bool edges_resize_policy=True) -> UndiGraph
        __init__(UndiGraph self, UndiGraph g) -> UndiGraph
        """
        _pyAgrum.UndiGraph_swiginit(self, _pyAgrum.new_UndiGraph(*args))
    __swig_destroy__ = _pyAgrum.delete_UndiGraph

    def __eq__(self, g: 'UndiGraph') -> "bool":
        r"""__eq__(UndiGraph self, UndiGraph g) -> bool"""
        return _pyAgrum.UndiGraph___eq__(self, g)

    def __ne__(self, g: 'UndiGraph') -> "bool":
        r"""__ne__(UndiGraph self, UndiGraph g) -> bool"""
        return _pyAgrum.UndiGraph___ne__(self, g)

    def eraseNode(self, id: 'gum::NodeId const') -> "void":
        r"""
        eraseNode(UndiGraph self, gum::NodeId const id)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.UndiGraph_eraseNode(self, id)

    def clear(self) -> "void":
        r"""
        clear(UndiGraph self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.UndiGraph_clear(self)

    def toDot(self) -> "std::string const":
        r"""
        toDot(UndiGraph self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.UndiGraph_toDot(self)

    def hasUndirectedCycle(self) -> "bool":
        r"""
        hasUndirectedCycle(UndiGraph self) -> bool

        Checks whether the graph contains cycles.

        Returns
        -------
        bool
            True if the graph contains a cycle

        """
        return _pyAgrum.UndiGraph_hasUndirectedCycle(self)

    def partialUndiGraph(self, nodesSet: 'gum::NodeSet') -> "gum::UndiGraph":
        r"""
        partialUndiGraph(UndiGraph self, gum::NodeSet nodesSet) -> UndiGraph

        Parameters
        ----------
        nodesSet : Set
            The set of nodes composing the partial graph

        Returns
        -------
        pyAgrum.UndiGraph
            The partial graph formed by the nodes given in parameter

        """
        return _pyAgrum.UndiGraph_partialUndiGraph(self, nodesSet)

    def __repr__(self) -> "std::string":
        r"""__repr__(UndiGraph self) -> std::string"""
        return _pyAgrum.UndiGraph___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(UndiGraph self) -> std::string"""
        return _pyAgrum.UndiGraph___str__(self)

    def nodes(self) -> "PyObject *":
        r"""
        nodes(UndiGraph self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.UndiGraph_nodes(self)

    def addNodes(self, n: 'gum::Size') -> "PyObject *":
        r"""
        addNodes(UndiGraph self, gum::Size n) -> PyObject *

        Add n nodes.

        Parameters
        ----------
        n : int
          the number of nodes to add.

        Returns
        -------
        Set of int
          the new ids

        """
        return _pyAgrum.UndiGraph_addNodes(self, n)

    def edges(self) -> "PyObject *":
        r"""
        edges(UndiGraph self) -> PyObject *

        Returns
        -------
        List
          the list of the edges

        """
        return _pyAgrum.UndiGraph_edges(self)

    def neighbours(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        neighbours(UndiGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
            the id of the checked node

        Returns
        -------
        Set
            The set of edges adjacent to the given node

        """
        return _pyAgrum.UndiGraph_neighbours(self, id)

    def addNode(self) -> "gum::NodeId":
        r"""
        addNode(UndiGraph self) -> gum::NodeId

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.UndiGraph_addNode(self)

    def addNodeWithId(self, id: 'gum::NodeId const') -> "void":
        r"""
        addNodeWithId(UndiGraph self, gum::NodeId const id)

        Add a node by choosing a new NodeId.

        Parameters
        ----------
        id : int
          The id of the new node

        Raises
        ------
        gum.DuplicateElement
          If the given id is already used

        """
        return _pyAgrum.UndiGraph_addNodeWithId(self, id)

    def existsNode(self, id: 'gum::NodeId const') -> "bool":
        r"""
        existsNode(UndiGraph self, gum::NodeId const id) -> bool

        Check if a node with a certain id exists in the graph.

        Parameters
        ----------
        id : int
            the checked id

        Returns
        -------
        bool
            True if the node exists

        """
        return _pyAgrum.UndiGraph_existsNode(self, id)

    def size(self) -> "gum::Size":
        r"""
        size(UndiGraph self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.UndiGraph_size(self)

    def empty(self) -> "bool":
        r"""
        empty(UndiGraph self) -> bool

        Check if the graph is empty.

        Returns
        -------
        bool
            True if the graph is empty

        """
        return _pyAgrum.UndiGraph_empty(self)

    def addEdge(self, n1: 'gum::NodeId const', n2: 'gum::NodeId const') -> "void":
        r"""
        addEdge(UndiGraph self, gum::NodeId const n1, gum::NodeId const n2)

        Insert a new edge into the graph.

        Parameters
        ----------
        n1 : int
          the id of one node of the new inserted edge
        n2 : int
          the id of the other node of the new inserted edge

        Raises
        ------
        gum.InvalidNode
          If n1 or n2 does not belong to the graph nodes.

        """
        return _pyAgrum.UndiGraph_addEdge(self, n1, n2)

    def eraseEdge(self, n1: 'gum::NodeId const', n2: 'gum::NodeId const') -> "void":
        r"""
        eraseEdge(UndiGraph self, gum::NodeId const n1, gum::NodeId const n2)

        Erase the edge between n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of the tail node
        n2 : int
          the id of the head node

        """
        return _pyAgrum.UndiGraph_eraseEdge(self, n1, n2)

    def existsEdge(self, n1: 'gum::NodeId const', n2: 'gum::NodeId const') -> "bool":
        r"""
        existsEdge(UndiGraph self, gum::NodeId const n1, gum::NodeId const n2) -> bool

        Check if an edge exists bewteen n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of one extremity of the edge
        n2 : int
          the id of the other extremity if tge edge

        Returns
        -------
        bool
            True if the arc exists

        """
        return _pyAgrum.UndiGraph_existsEdge(self, n1, n2)

    def sizeEdges(self) -> "gum::Size":
        r"""
        sizeEdges(UndiGraph self) -> gum::Size

        Returns
        -------
        int
            the number of edges in the graph

        """
        return _pyAgrum.UndiGraph_sizeEdges(self)

    def emptyEdges(self) -> "bool":
        r"""
        emptyEdges(UndiGraph self) -> bool

        Check if the graph doesn't contains edges.

        Returns
        -------
        bool
            True if the graph doesn't contains edges

        """
        return _pyAgrum.UndiGraph_emptyEdges(self)

    def eraseNeighbours(self, n: 'gum::NodeId const') -> "void":
        r"""
        eraseNeighbours(UndiGraph self, gum::NodeId const n)

        Erase all the edges adjacent to a given node.

        Parameters
        ----------
        n : int
          the id of the node

        """
        return _pyAgrum.UndiGraph_eraseNeighbours(self, n)

# Register UndiGraph in _pyAgrum:
_pyAgrum.UndiGraph_swigregister(UndiGraph)

class DiGraph(object):
    r"""

    DiGraph represents a Directed Graph.

    Available constructors:
        ``DiGraph() -> DiGraph``

        ``DiGraph(src) -> DiGraph``

    Parameters
    ----------
    src : pyAgrum.DiGraph
      the digraph to copy


    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(DiGraph self, gum::Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=True, gum::Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=True) -> DiGraph
        __init__(DiGraph self, DiGraph g) -> DiGraph
        """
        _pyAgrum.DiGraph_swiginit(self, _pyAgrum.new_DiGraph(*args))
    __swig_destroy__ = _pyAgrum.delete_DiGraph

    def __eq__(self, g: 'DiGraph') -> "bool":
        r"""__eq__(DiGraph self, DiGraph g) -> bool"""
        return _pyAgrum.DiGraph___eq__(self, g)

    def __ne__(self, g: 'DiGraph') -> "bool":
        r"""__ne__(DiGraph self, DiGraph g) -> bool"""
        return _pyAgrum.DiGraph___ne__(self, g)

    def eraseNode(self, id: 'gum::NodeId const') -> "void":
        r"""
        eraseNode(DiGraph self, gum::NodeId const id)

        Erase the node and all the related arcs.

        Parameters
        ----------
        id : int
        	the id of the node

        """
        return _pyAgrum.DiGraph_eraseNode(self, id)

    def clear(self) -> "void":
        r"""
        clear(DiGraph self)

        Remove all the nodes and arcs from the graph.

        """
        return _pyAgrum.DiGraph_clear(self)

    def toDot(self) -> "std::string const":
        r"""
        toDot(DiGraph self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.DiGraph_toDot(self)

    def topologicalOrder(self, clear: 'bool'=True) -> "gum::Sequence< gum::NodeId > const &":
        r"""
        topologicalOrder(DiGraph self, bool clear=True) -> gum::Sequence< gum::NodeId > const

        Returns
        -------
        List
            the list of the nodes Ids in a topological order

        Raises
        ------
        gum.InvalidDirectedCycle
          If this graph contains cycles

        """
        return _pyAgrum.DiGraph_topologicalOrder(self, clear)

    def __repr__(self) -> "std::string":
        r"""__repr__(DiGraph self) -> std::string"""
        return _pyAgrum.DiGraph___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(DiGraph self) -> std::string"""
        return _pyAgrum.DiGraph___str__(self)

    def nodes(self) -> "PyObject *":
        r"""
        nodes(DiGraph self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.DiGraph_nodes(self)

    def addNodes(self, n: 'gum::Size') -> "PyObject *":
        r"""
        addNodes(DiGraph self, gum::Size n) -> PyObject *

        Add n nodes.

        Parameters
        ----------
        n : int
          the number of nodes to add.

        Returns
        -------
        Set of int
          the new ids

        """
        return _pyAgrum.DiGraph_addNodes(self, n)

    def arcs(self) -> "PyObject *":
        r"""
        arcs(DiGraph self) -> PyObject *

        Returns
        -------
        List
        	the list of the arcs

        """
        return _pyAgrum.DiGraph_arcs(self)

    def parents(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        parents(DiGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.DiGraph_parents(self, id)

    def children(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        children(DiGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.DiGraph_children(self, id)

    def addNode(self) -> "gum::NodeId":
        r"""
        addNode(DiGraph self) -> gum::NodeId

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.DiGraph_addNode(self)

    def addNodeWithId(self, id: 'gum::NodeId const') -> "void":
        r"""
        addNodeWithId(DiGraph self, gum::NodeId const id)

        Add a node by choosing a new NodeId.

        Parameters
        ----------
        id : int
          The id of the new node

        Raises
        ------
        gum.DuplicateElement
          If the given id is already used

        """
        return _pyAgrum.DiGraph_addNodeWithId(self, id)

    def existsNode(self, id: 'gum::NodeId const') -> "bool":
        r"""
        existsNode(DiGraph self, gum::NodeId const id) -> bool

        Check if a node with a certain id exists in the graph.

        Parameters
        ----------
        id : int
            the checked id

        Returns
        -------
        bool
            True if the node exists

        """
        return _pyAgrum.DiGraph_existsNode(self, id)

    def size(self) -> "gum::Size":
        r"""
        size(DiGraph self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.DiGraph_size(self)

    def empty(self) -> "bool":
        r"""
        empty(DiGraph self) -> bool

        Check if the graph is empty.

        Returns
        -------
        bool
            True if the graph is empty

        """
        return _pyAgrum.DiGraph_empty(self)

    def addArc(self, *args) -> "void":
        r"""
        addArc(DiGraph self, gum::NodeId const tail, gum::NodeId const head)
        addArc(DiGraph self, gum::NodeId const n1, gum::NodeId const n2)

        Add an arc from tail to head.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidNode
          If head or tail does not belong to the graph nodes.

        """
        return _pyAgrum.DiGraph_addArc(self, *args)

    def eraseArc(self, n1: 'gum::NodeId const', n2: 'gum::NodeId const') -> "void":
        r"""
        eraseArc(DiGraph self, gum::NodeId const n1, gum::NodeId const n2)

        Erase the arc between n1 and n2.

        Parameters
        ----------
        n1 : int
        	the id of the tail node
        n2 : int
        	the id of the head node

        """
        return _pyAgrum.DiGraph_eraseArc(self, n1, n2)

    def existsArc(self, n1: 'gum::NodeId const', n2: 'gum::NodeId const') -> "bool":
        r"""
        existsArc(DiGraph self, gum::NodeId const n1, gum::NodeId const n2) -> bool

        Check if an arc exists bewteen n1 and n2.

        Parameters
        ----------
        n1 : int
        	the id of the tail node
        n2 : int
        	the id of the head node

        Returns
        -------
        bool
            True if the arc exists

        """
        return _pyAgrum.DiGraph_existsArc(self, n1, n2)

    def eraseParents(self, n: 'gum::NodeId const') -> "void":
        r"""
        eraseParents(DiGraph self, gum::NodeId const n)

        Erase the arcs coming to the node.

        Parameters
        ----------
        n : int
        	the id of the child node

        """
        return _pyAgrum.DiGraph_eraseParents(self, n)

    def eraseChildren(self, n: 'gum::NodeId const') -> "void":
        r"""
        eraseChildren(DiGraph self, gum::NodeId const n)

        Erase the arcs heading through the node's children.

        Parameters
        ----------
        n : int
        	the id of the parent node

        """
        return _pyAgrum.DiGraph_eraseChildren(self, n)

    def sizeArcs(self) -> "gum::Size":
        r"""
        sizeArcs(DiGraph self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.DiGraph_sizeArcs(self)

    def emptyArcs(self) -> "bool":
        r"""
        emptyArcs(DiGraph self) -> bool

        Check if the graph doesn't contains arcs.

        Returns
        -------
        bool
            True if the graph doesn't contains arcs

        """
        return _pyAgrum.DiGraph_emptyArcs(self)

# Register DiGraph in _pyAgrum:
_pyAgrum.DiGraph_swigregister(DiGraph)

class DAG(DiGraph):
    r"""

    DAG represents a Directed Acyclic Graph.

    Available constructors:
        ``DAG() -> DAG``

        ``DAG(src) -> DAG``

    Parameters
    ----------
    src : :class: DAG
      the DAG to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(DAG self, gum::Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=True, gum::Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=True) -> DAG
        __init__(DAG self, DAG g) -> DAG
        """
        _pyAgrum.DAG_swiginit(self, _pyAgrum.new_DAG(*args))
    __swig_destroy__ = _pyAgrum.delete_DAG

    def moralGraph(self) -> "gum::UndiGraph":
        r"""moralGraph(DAG self) -> UndiGraph"""
        return _pyAgrum.DAG_moralGraph(self)

    def addNodes(self, n: 'gum::Size') -> "PyObject *":
        r"""addNodes(DAG self, gum::Size n) -> PyObject *"""
        return _pyAgrum.DAG_addNodes(self, n)

    def addArc(self, *args) -> "void":
        r"""
        addArc(DAG self, gum::NodeId const tail, gum::NodeId const head)
        addArc(DAG self, gum::NodeId const n1, gum::NodeId const n2)

        Add an arc from tail to head.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidDirectedCircle
        	If any (directed) cycle is created by this arc
        gum.InvalidNode
        	If head or tail does not belong to the graph nodes

        """
        return _pyAgrum.DAG_addArc(self, *args)

# Register DAG in _pyAgrum:
_pyAgrum.DAG_swigregister(DAG)

class MixedGraph(UndiGraph, DiGraph):
    r"""

    MixedGraph represents a Clique Graph.

    Available constructors:
        ``MixedGraph() -> MixedGraph``

        ``MixedGraph(src) -> MixedGraph``

    Parameters
    ----------
    src : pyAgrum.MixedGraph
      the MixedGraph to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(MixedGraph self, gum::Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=True, gum::Size arcs_size=HashTableConst::default_size, bool arcs_resize_policy=True, gum::Size edges_size=HashTableConst::default_size, bool edges_resize_policy=True) -> MixedGraph
        __init__(MixedGraph self, MixedGraph g) -> MixedGraph
        """
        _pyAgrum.MixedGraph_swiginit(self, _pyAgrum.new_MixedGraph(*args))
    __swig_destroy__ = _pyAgrum.delete_MixedGraph

    def __eq__(self, g: 'MixedGraph') -> "bool":
        r"""__eq__(MixedGraph self, MixedGraph g) -> bool"""
        return _pyAgrum.MixedGraph___eq__(self, g)

    def __ne__(self, g: 'MixedGraph') -> "bool":
        r"""__ne__(MixedGraph self, MixedGraph g) -> bool"""
        return _pyAgrum.MixedGraph___ne__(self, g)

    def eraseNode(self, id: 'gum::NodeId const') -> "void":
        r"""
        eraseNode(MixedGraph self, gum::NodeId const id)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.MixedGraph_eraseNode(self, id)

    def clear(self) -> "void":
        r"""
        clear(MixedGraph self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.MixedGraph_clear(self)

    def mixedOrientedPath(self, node1: 'gum::NodeId const', node2: 'gum::NodeId const') -> "std::vector< gum::NodeId,std::allocator< gum::NodeId > > const":
        r"""
        mixedOrientedPath(MixedGraph self, gum::NodeId const node1, gum::NodeId const node2) -> std::vector< gum::NodeId,std::allocator< gum::NodeId > > const

        Parameters
        ----------
        node1 : int
        	the id form which the path begins
        node2 : int
        	the id to witch the path ends

        Returns
        -------
        List
        	 a path from node1 to node2, using edges and/or arcs (following the direction of the arcs)

        Raises
        ------
        gum.NotFound
        	If no path can be found between the two nodes

        """
        return _pyAgrum.MixedGraph_mixedOrientedPath(self, node1, node2)

    def mixedUnorientedPath(self, node1: 'gum::NodeId const', node2: 'gum::NodeId const') -> "std::vector< gum::NodeId,std::allocator< gum::NodeId > > const":
        r"""
        mixedUnorientedPath(MixedGraph self, gum::NodeId const node1, gum::NodeId const node2) -> std::vector< gum::NodeId,std::allocator< gum::NodeId > > const

        Parameters
        ----------
        node1 : int
        	the id from which the path begins
        node2 : int
        	the id to which the path ends

        Returns
        -------
        List
        	 a path from node1 to node2, using edges and/or arcs (not necessarily following the direction of the arcs)

        Raises
        ------
        gum.NotFound
        	If no path can be found between the two nodes

        """
        return _pyAgrum.MixedGraph_mixedUnorientedPath(self, node1, node2)

    def toDot(self) -> "std::string const":
        r"""
        toDot(MixedGraph self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.MixedGraph_toDot(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(MixedGraph self) -> std::string"""
        return _pyAgrum.MixedGraph___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(MixedGraph self) -> std::string"""
        return _pyAgrum.MixedGraph___str__(self)

# Register MixedGraph in _pyAgrum:
_pyAgrum.MixedGraph_swigregister(MixedGraph)

class CliqueGraph(UndiGraph):
    r"""

    CliqueGraph represents a Clique Graph.

    Available constructors:
        ``CliqueGraph() -> CliqueGraph``

        ``CliqueGraph(src) -> CliqueGraph``

    Parameters
    ----------
    src : pyAgrum.CliqueGraph
      the CliqueGraph to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(CliqueGraph self, gum::Size nodes_size=HashTableConst::default_size, bool nodes_resize_policy=True, gum::Size edges_size=HashTableConst::default_size, bool edges_resize_policy=True) -> CliqueGraph
        __init__(CliqueGraph self, CliqueGraph _from) -> CliqueGraph
        """
        _pyAgrum.CliqueGraph_swiginit(self, _pyAgrum.new_CliqueGraph(*args))
    __swig_destroy__ = _pyAgrum.delete_CliqueGraph

    def addEdge(self, first: 'gum::NodeId const', second: 'gum::NodeId const') -> "void":
        r"""
        addEdge(CliqueGraph self, gum::NodeId const first, gum::NodeId const second)

        Insert a new edge into the graph.

        Parameters
        ----------
        n1 : int
          the id of one node of the new inserted edge
        n2 : int
          the id of the other node of the new inserted edge

        Raises
        ------
        gum.InvalidNode
          If n1 or n2 does not belong to the graph nodes.

        """
        return _pyAgrum.CliqueGraph_addEdge(self, first, second)

    def eraseEdge(self, edge: 'Edge') -> "void":
        r"""
        eraseEdge(CliqueGraph self, Edge edge)

        Erase the edge between n1 and n2.

        Parameters
        ----------
        n1 : int
          the id of the tail node
        n2 : int
          the id of the head node

        """
        return _pyAgrum.CliqueGraph_eraseEdge(self, edge)

    def clearEdges(self) -> "void":
        r"""
        clearEdges(CliqueGraph self)

        Remove all edges and their separators 

        """
        return _pyAgrum.CliqueGraph_clearEdges(self)

    def addNode(self, *args) -> "void":
        r"""
        addNode(CliqueGraph self, gum::NodeSet const & clique) -> gum::NodeId
        addNode(CliqueGraph self) -> gum::NodeId
        addNode(CliqueGraph self, gum::NodeId const id, gum::NodeSet const & clique)
        addNode(CliqueGraph self, gum::NodeId const id)

        Returns
        -------
        int
          the new NodeId

        """
        return _pyAgrum.CliqueGraph_addNode(self, *args)

    def eraseNode(self, node: 'gum::NodeId const') -> "void":
        r"""
        eraseNode(CliqueGraph self, gum::NodeId const node)

        Erase the node and all the adjacent edges.

        Parameters
        ----------
        id : int
          the id of the node

        """
        return _pyAgrum.CliqueGraph_eraseNode(self, node)

    def clear(self) -> "void":
        r"""
        clear(CliqueGraph self)

        Remove all the nodes and edges from the graph.

        """
        return _pyAgrum.CliqueGraph_clear(self)

    def container(self, idNode: 'gum::NodeId const') -> "gum::NodeId":
        r"""
        container(CliqueGraph self, gum::NodeId const idNode) -> gum::NodeId

        Parameters
        ----------
        idNode : int
          the id of the node

        Returns
        -------
        int
          the id of a clique containing the node

        Raises
        ------
        gum.NotFound
          If no clique contains idNode  

        """
        return _pyAgrum.CliqueGraph_container(self, idNode)

    def setClique(self, idClique: 'gum::NodeId const', new_clique: 'gum::NodeSet const &') -> "void":
        r"""
        setClique(CliqueGraph self, gum::NodeId const idClique, gum::NodeSet const & new_clique)

        changes the set of nodes included into a given clique

        Parameters
        ----------
        idClique : int
          the id of the clique
        new_clique : Set
          the new set of nodes to be included in the clique

        Raises
        ------
        gum.NotFound
          If idClique is not a clique of the graph

        """
        return _pyAgrum.CliqueGraph_setClique(self, idClique, new_clique)

    def addToClique(self, clique_id: 'gum::NodeId const', node_id: 'gum::NodeId const') -> "void":
        r"""
        addToClique(CliqueGraph self, gum::NodeId const clique_id, gum::NodeId const node_id)

        Change the set of nodes included into a given clique and returns the new set 

        Parameters
        ----------
        clique_id : int
          the id of the clique
        node_id : int
          the id of the node

        Raises
        ------
        gum.NotFound
          If clique_id does not exist
        gum.DuplicateElement
          If clique_id set already contains the ndoe

        """
        return _pyAgrum.CliqueGraph_addToClique(self, clique_id, node_id)

    def eraseFromClique(self, clique_id: 'gum::NodeId const', node_id: 'gum::NodeId const') -> "void":
        r"""
        eraseFromClique(CliqueGraph self, gum::NodeId const clique_id, gum::NodeId const node_id)

        Remove a node from a clique

        Parameters
        ----------
        clique_id : int
          the id of the clique
        node_id : int
          the id of the node

        Raises
        ------
        gum.NotFound
          If clique_id does not exist

        """
        return _pyAgrum.CliqueGraph_eraseFromClique(self, clique_id, node_id)

    def containerPath(self, node1: 'gum::NodeId const', node2: 'gum::NodeId const') -> "std::vector< gum::NodeId,std::allocator< gum::NodeId > >":
        r"""
        containerPath(CliqueGraph self, gum::NodeId const node1, gum::NodeId const node2) -> std::vector< gum::NodeId,std::allocator< gum::NodeId > >

        Parameters
        ----------
        node1 : int
          the id of one node
        node2 : int
          the id of the other node

        Returns
        -------
        List
          a path from a clique containing node1 to a clique containing node2

        Raises
        ------
        gum.NotFound 
          If such path cannot be found

        """
        return _pyAgrum.CliqueGraph_containerPath(self, node1, node2)

    def hasRunningIntersection(self) -> "bool":
        r"""
        hasRunningIntersection(CliqueGraph self) -> bool

        Returns
        -------
        bool
          True if the running intersection property holds 

        """
        return _pyAgrum.CliqueGraph_hasRunningIntersection(self)

    def isJoinTree(self) -> "bool":
        r"""
        isJoinTree(CliqueGraph self) -> bool

        Returns
        -------
        bool
          True if the graph is a join tree 

        """
        return _pyAgrum.CliqueGraph_isJoinTree(self)

    def toDot(self) -> "std::string const":
        r"""
        toDot(CliqueGraph self) -> std::string const

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.CliqueGraph_toDot(self)

    def __ne__(self, _from: 'CliqueGraph') -> "bool":
        r"""__ne__(CliqueGraph self, CliqueGraph _from) -> bool"""
        return _pyAgrum.CliqueGraph___ne__(self, _from)

    def __eq__(self, _from: 'CliqueGraph') -> "bool":
        r"""__eq__(CliqueGraph self, CliqueGraph _from) -> bool"""
        return _pyAgrum.CliqueGraph___eq__(self, _from)

    def clique(self, clique: 'gum::NodeId const') -> "PyObject *":
        r"""
        clique(CliqueGraph self, gum::NodeId const clique) -> PyObject *

        Parameters
        ----------
        idClique : int
          the id of the clique

        Returns
        -------
        Set
          The set of nodes included in the clique

        Raises
        ------
        gum.NotFound
          If the clique does not belong to the clique graph

        """
        return _pyAgrum.CliqueGraph_clique(self, clique)

    def separator(self, cliq1: 'gum::NodeId const', cliq2: 'gum::NodeId const') -> "PyObject *":
        r"""
        separator(CliqueGraph self, gum::NodeId const cliq1, gum::NodeId const cliq2) -> PyObject *

        Parameters
        ----------
        edge : pyAgrum.Edge
          the edge to be checked
        clique1 : int 
          one extremity of the edge
        clique : int 
          the other extremity of the edge

        Returns
        -------
        Set
          the separator included in a given edge

        Raises
        ------
        gum.NotFound
          If the edge does not belong to the clique graph

        """
        return _pyAgrum.CliqueGraph_separator(self, cliq1, cliq2)

    def toDotWithNames(self,bn):
        """
        Parameters
        ----------
        bn : pyAgrum.BayesNet
        a Bayesian network

        Returns
        -------
        str
          a friendly display of the graph in DOT format where ids have been changed according to their correspondance in the BN
        """
        def nameFromId(m):
          return " ".join([bn.variable(int(n)).name()
                           for n in m.group().split("-")])
        import re
        m = re.compile('(?<=label=\")\d+[\-\d+]*')
        return m.sub(nameFromId,self.toDot())


# Register CliqueGraph in _pyAgrum:
_pyAgrum.CliqueGraph_swigregister(CliqueGraph)

class Instantiation(object):
    r"""

    Class for assigning/browsing values to tuples of discrete variables.

    Instantiation is designed to assign values to tuples of variables and to efficiently loop over values of subsets of variables.

    Available constructors:

    	``Instantiation() -> Instantiation``

    	``Instantiation(aI) -> Instantiation``

    Parameters
    ----------
    aI: pyAgrum.Instantiation
      The Instantiation we copy

    Returns
    -------
    pyAgrum.Instantiation
    	An empty tuple or a copy of the one in parameters

    Instantiation is subscriptable therefore values can be easily accessed/modified.

    Examples
    --------
    >>> ## Access the value of A in an instantiation aI
    >>> valueOfA = aI['A']
    >>> ## Modify the value
    >>> aI['A'] = newValueOfA

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(Instantiation self) -> Instantiation
        __init__(Instantiation self, Instantiation aI, bool const notifyMaster=True) -> Instantiation
        __init__(Instantiation self, MultiDimAdressable aMD) -> Instantiation
        __init__(Instantiation self, MultiDimAdressable aMD) -> Instantiation
        __init__(Instantiation self, MultiDimAdressable aMD) -> Instantiation
        __init__(Instantiation self, MultiDimAdressable aMD) -> Instantiation
        """
        _pyAgrum.Instantiation_swiginit(self, _pyAgrum.new_Instantiation(*args))
    __swig_destroy__ = _pyAgrum.delete_Instantiation

    def nbrDim(self) -> "gum::Idx":
        r"""
        nbrDim(Instantiation self) -> gum::Idx

        Returns
        -------
        int
            The number of variables in the Instantiation.

        """
        return _pyAgrum.Instantiation_nbrDim(self)

    def add(self, v: 'DiscreteVariable') -> "void":
        r"""
        add(Instantiation self, DiscreteVariable v)

        Adds a new variable in the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The new variable added to the Instantiation

        Raises
        ------
        DuplicateElement
          If the variable is already in this Instantiation


        """
        return _pyAgrum.Instantiation_add(self, v)

    def erase(self, v: 'DiscreteVariable') -> "void":
        r"""
        erase(Instantiation self, DiscreteVariable v)

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable to be removed from this Instantiation.

        Raises
        ------
        NotFound
          If v does not belong to this Instantiation.

        """
        return _pyAgrum.Instantiation_erase(self, v)

    def clear(self) -> "void":
        r"""
        clear(Instantiation self)

        Erase all variables from an Instantiation.

        """
        return _pyAgrum.Instantiation_clear(self)

    def domainSize(self) -> "gum::Size":
        r"""
        domainSize(Instantiation self) -> gum::Size

        Returns
        -------
        int
            The product of the variable's domain size in the Instantiation.

        """
        return _pyAgrum.Instantiation_domainSize(self)

    def pos(self, v: 'DiscreteVariable') -> "gum::Idx":
        r"""
        pos(Instantiation self, DiscreteVariable v) -> gum::Idx

        Returns
        -------
        int
           the position of the variable v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            the variable for which its position is return.

        Raises
        ------
        NotFound
          If v does not belong to the instantiation.

        """
        return _pyAgrum.Instantiation_pos(self, v)

    def val(self, *args) -> "gum::Idx":
        r"""
        val(Instantiation self, gum::Idx i) -> gum::Idx
        val(Instantiation self, DiscreteVariable var) -> gum::Idx

        Parameters
        ----------
        i : int
        	The index of the variable.
        var : pyAgrum.DiscreteVariable
        	The variable the value of which we wish to know

        Returns
        -------
        int
        	the current value of the variable.

        Raises
        ------
        NotFound
          If the element cannot be found.

        """
        return _pyAgrum.Instantiation_val(self, *args)

    def variable(self, *args) -> "gum::DiscreteVariable const &":
        r"""
        variable(Instantiation self, gum::Idx i) -> DiscreteVariable
        variable(Instantiation self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        i : int
          The index of the variable

        Returns
        -------
        pyAgrum.DiscreteVariable
          the variable at position i in the tuple.

        Raises
        ------
        NotFound
          If the element cannot be found.

        """
        return _pyAgrum.Instantiation_variable(self, *args)

    def chgVal(self, *args) -> "gum::Instantiation &":
        r"""
        chgVal(Instantiation self, DiscreteVariable v, gum::Idx newval) -> Instantiation
        chgVal(Instantiation self, DiscreteVariable v, gum::Idx newval) -> Instantiation
        chgVal(Instantiation self, gum::Idx varPos, gum::Idx newval) -> Instantiation
        chgVal(Instantiation self, std::string const & var, gum::Idx newval) -> Instantiation
        chgVal(Instantiation self, std::string const & var, std::string const & newval) -> Instantiation

        Assign newval to v (or to the variable at position varPos) in the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable or string
          The variable whose value is assigned (or its name)
        varPos : int
          The index of the variable whose value is assigned in the tuple of variables of the Instantiation
        newval : int or string
          The index of the value assigned (or its name)

        Returns
        -------
        pyAgrum.Instantiation
            The modified instantiation

        Raises
        ------
        NotFound
          If variable v does not belong to the instantiation.
        OutOfBound
          If newval is not a possible value for the variable.

        """
        return _pyAgrum.Instantiation_chgVal(self, *args)

    def setVals(self, i: 'Instantiation') -> "gum::Instantiation &":
        r"""
        setVals(Instantiation self, Instantiation i) -> Instantiation

        Assign the values from i in the Instantiation.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          An Instantiation in which the new values are searched

        Returns
        -------
        pyAgrum.Instantiation
          a reference to the instantiation

        """
        return _pyAgrum.Instantiation_setVals(self, i)

    def contains(self, *args) -> "bool":
        r"""
        contains(Instantiation self, DiscreteVariable v) -> bool
        contains(Instantiation self, DiscreteVariable v) -> bool

        Indicates whether a given variable belongs to the Instantiation.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the test is made.

        Returns
        -------
        bool :
            True if the variable is in the Instantiation.

        """
        return _pyAgrum.Instantiation_contains(self, *args)

    def variablesSequence(self) -> "gum::Sequence< gum::DiscreteVariable const * > const &":
        r"""
        variablesSequence(Instantiation self) -> gum::Sequence< gum::DiscreteVariable const * > const &

        Returns
        -------
        List
            the sequence of DiscreteVariable of this instantiation.

        """
        return _pyAgrum.Instantiation_variablesSequence(self)

    def empty(self) -> "bool":
        r"""
        empty(Instantiation self) -> bool

        Returns
        -------
        bool
            True if the instantiation is empty.

        """
        return _pyAgrum.Instantiation_empty(self)

    def inOverflow(self) -> "bool":
        r"""
        inOverflow(Instantiation self) -> bool

        Returns
        -------
        bool
          True if the current value of the tuple is correct

        """
        return _pyAgrum.Instantiation_inOverflow(self)

    def unsetOverflow(self) -> "void":
        r"""
        unsetOverflow(Instantiation self)

        Removes the flag overflow.

        """
        return _pyAgrum.Instantiation_unsetOverflow(self)

    def unsetEnd(self) -> "void":
        r"""
        unsetEnd(Instantiation self)

        Alias for unsetOverflow().

        """
        return _pyAgrum.Instantiation_unsetEnd(self)

    def end(self) -> "bool":
        r"""
        end(Instantiation self) -> bool

        Returns
        -------
        bool
            True if the Instantiation reached the end.

        """
        return _pyAgrum.Instantiation_end(self)

    def rend(self) -> "bool":
        r"""
        rend(Instantiation self) -> bool

        Returns
        -------
        bool:
          True if the Instantiation reached the rend.

        """
        return _pyAgrum.Instantiation_rend(self)

    def inc(self) -> "void":
        r"""
        inc(Instantiation self)

        Operator ++.

        """
        return _pyAgrum.Instantiation_inc(self)

    def dec(self) -> "void":
        r"""
        dec(Instantiation self)

        Operator --.

        """
        return _pyAgrum.Instantiation_dec(self)

    def incIn(self, i: 'Instantiation') -> "void":
        r"""
        incIn(Instantiation self, Instantiation i)

        Operator ++ for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The set of variables to increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incIn(self, i)

    def decIn(self, i: 'Instantiation') -> "void":
        r"""
        decIn(Instantiation self, Instantiation i)

        Operator -- for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The set of variables to decrement in this Instantiation

        """
        return _pyAgrum.Instantiation_decIn(self, i)

    def incOut(self, i: 'Instantiation') -> "void":
        r"""
        incOut(Instantiation self, Instantiation i)

        Operator ++ for the variables not in i.

        Parameters
        ----------
        i : Instantiation
            The set of variable to not increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incOut(self, i)

    def decOut(self, i: 'Instantiation') -> "void":
        r"""
        decOut(Instantiation self, Instantiation i)

        Operator -- for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The set of variables to not decrement in this Instantiation.

        """
        return _pyAgrum.Instantiation_decOut(self, i)

    def incNotVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        incNotVar(Instantiation self, DiscreteVariable v)

        Operator ++ for vars which are not v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable not to increment in this Instantiation.

        """
        return _pyAgrum.Instantiation_incNotVar(self, v)

    def decNotVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        decNotVar(Instantiation self, DiscreteVariable v)

        Operator -- for vars which are not v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable not to decrement in this Instantiation.

        """
        return _pyAgrum.Instantiation_decNotVar(self, v)

    def incVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        incVar(Instantiation self, DiscreteVariable v)

        Operator ++ for variable v only.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable to increment in this Instantiation.

        Raises
        ------
        NotFound
          If variable v does not belong to the Instantiation.

        """
        return _pyAgrum.Instantiation_incVar(self, v)

    def decVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        decVar(Instantiation self, DiscreteVariable v)

        Operator -- for variable v only.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
         The variable to decrement in this Instantiation.

        Raises
        ------
        NotFound
          If variable v does not belong to the Instantiation.

        """
        return _pyAgrum.Instantiation_decVar(self, v)

    def setFirst(self) -> "void":
        r"""
        setFirst(Instantiation self)

        Assign the first values to the tuple of the Instantiation.

        """
        return _pyAgrum.Instantiation_setFirst(self)

    def setLast(self) -> "void":
        r"""
        setLast(Instantiation self)

        Assign the last values in the Instantiation.

        """
        return _pyAgrum.Instantiation_setLast(self)

    def setFirstIn(self, i: 'Instantiation') -> "void":
        r"""
        setFirstIn(Instantiation self, Instantiation i)

        Assign the first values in the Instantiation for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The variables to which their first value is assigned in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstIn(self, i)

    def setLastIn(self, i: 'Instantiation') -> "void":
        r"""
        setLastIn(Instantiation self, Instantiation i)

        Assign the last values in the Instantiation for the variables in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variables to which their last value is assigned in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastIn(self, i)

    def setFirstOut(self, i: 'Instantiation') -> "void":
        r"""
        setFirstOut(Instantiation self, Instantiation i)

        Assign the first values in the Instantiation for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variable that will not be set to their first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstOut(self, i)

    def setLastOut(self, i: 'Instantiation') -> "void":
        r"""
        setLastOut(Instantiation self, Instantiation i)

        Assign the last values in the Instantiation for the variables not in i.

        Parameters
        ----------
        i : pyAgrum.Instantiation
            The variables that will not be set to their last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastOut(self, i)

    def setFirstNotVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        setFirstNotVar(Instantiation self, DiscreteVariable v)

        Assign the first values to variables different of v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable that will not be set to its first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstNotVar(self, v)

    def setLastNotVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        setLastNotVar(Instantiation self, DiscreteVariable v)

        Assign the last values to variables different of v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable that will not be set to its last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastNotVar(self, v)

    def setFirstVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        setFirstVar(Instantiation self, DiscreteVariable v)

        Assign the first value in the Instantiation for var v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable that will be set to its first value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setFirstVar(self, v)

    def setLastVar(self, v: 'DiscreteVariable') -> "void":
        r"""
        setLastVar(Instantiation self, DiscreteVariable v)

        Assign the last value in the Instantiation for var v.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          The variable that will be set to its last value in this Instantiation.

        """
        return _pyAgrum.Instantiation_setLastVar(self, v)

    def __eq__(self, other: 'Instantiation') -> "bool":
        r"""__eq__(Instantiation self, Instantiation other) -> bool"""
        return _pyAgrum.Instantiation___eq__(self, other)

    def __iadd__(self, depl: 'gum::Size') -> "gum::Instantiation &":
        r"""__iadd__(Instantiation self, gum::Size depl) -> Instantiation"""
        return _pyAgrum.Instantiation___iadd__(self, depl)

    def __isub__(self, depl: 'gum::Size') -> "gum::Instantiation &":
        r"""__isub__(Instantiation self, gum::Size depl) -> Instantiation"""
        return _pyAgrum.Instantiation___isub__(self, depl)

    def hamming(self) -> "gum::Idx":
        r"""
        hamming(Instantiation self) -> gum::Idx

        Returns
        -------
        int
          the hamming distance of this instantiation.

        """
        return _pyAgrum.Instantiation_hamming(self)

    def reorder(self, *args) -> "void":
        r"""
        reorder(Instantiation self, gum::Sequence< gum::DiscreteVariable const * > const & v)
        reorder(Instantiation self, Instantiation i)

        Reorder vars of this instantiation giving the order in v (or i).

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The sequence of variables with which to reorder this Instantiation.
        v : list
            The new order of variables for this Instantiation.

        """
        return _pyAgrum.Instantiation_reorder(self, *args)

    def __repr__(self) -> "std::string":
        r"""__repr__(Instantiation self) -> std::string"""
        return _pyAgrum.Instantiation___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(Instantiation self) -> std::string"""
        return _pyAgrum.Instantiation___str__(self)

    def todict(self, withLabels: 'bool'=False) -> "PyObject *":
        r"""
        todict(Instantiation self, bool withLabels=False) -> PyObject

        Create a dict (variable_name:value) from an instantiation

        Parameters
        ----------
        withLabels : boolean
        	The value will be a label (string) if True. It will be a position (int) if False.

        Returns
        -------
        Dict
            The dictionary

        """
        return _pyAgrum.Instantiation_todict(self, withLabels)

    def fromdict(self, dict: 'PyObject *') -> "void":
        r"""
        fromdict(Instantiation self, PyObject * dict)

        Change the values in an instantiation from a dict (variable_name:value) where value can be a position (int) or a label (string).

        If a variable_name does not occur in the instantiation, nothing is done.

        Warnings
        --------
            OutOfBounds raised if a value cannot be found.

        """
        return _pyAgrum.Instantiation_fromdict(self, dict)

    def __setitem__(self,key,item):
      self.chgVal(key,item)

    def __getitem__(self,key):
      return self.val(self.variable(key))


# Register Instantiation in _pyAgrum:
_pyAgrum.Instantiation_swigregister(Instantiation)

GUM_DEFAULT_ITERATOR_NUMBER = _pyAgrum.GUM_DEFAULT_ITERATOR_NUMBER

class DAGmodel(object):
    r"""

    Abstract class used by IBayesNet and InfluenceDiagram.

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyAgrum.delete_DAGmodel

    def property(self, name: 'std::string const &') -> "std::string const &":
        r"""
        property(DAGmodel self, std::string const & name) -> std::string const &

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_property(self, name)

    def propertyWithDefault(self, name: 'std::string const &', byDefault: 'std::string const &') -> "std::string const &":
        r"""
        propertyWithDefault(DAGmodel self, std::string const & name, std::string const & byDefault) -> std::string const &

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_propertyWithDefault(self, name, byDefault)

    def setProperty(self, name: 'std::string const &', value: 'std::string const &') -> "void":
        r"""
        setProperty(DAGmodel self, std::string const & name, std::string const & value)

        Warnings
        --------
        Unreferenced function

        """
        return _pyAgrum.DAGmodel_setProperty(self, name, value)

    def dag(self) -> "gum::DAG const &":
        r"""
        dag(DAGmodel self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	a constant reference to the dag of this BayesNet.

        """
        val = _pyAgrum.DAGmodel_dag(self)

        val = DAG(val) # copying the DAG


        return val


    def variableNodeMap(self) -> "gum::VariableNodeMap const &":
        r"""
        variableNodeMap(DAGmodel self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.DAGmodel_variableNodeMap(self)

    def size(self) -> "gum::Size":
        r"""
        size(DAGmodel self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.DAGmodel_size(self)

    def sizeArcs(self) -> "gum::Size":
        r"""
        sizeArcs(DAGmodel self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.DAGmodel_sizeArcs(self)

    def empty(self) -> "bool":
        r"""
        empty(DAGmodel self) -> bool

        Returns
        -------
        bool
        	True if the model is empty

        """
        return _pyAgrum.DAGmodel_empty(self)

    def nodes(self) -> "gum::NodeGraphPart const &":
        r"""
        nodes(DAGmodel self) -> NodeGraphPart

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.DAGmodel_nodes(self)

    def variable(self, id: 'gum::NodeId') -> "gum::DiscreteVariable const &":
        r"""
        variable(DAGmodel self, gum::NodeId id) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_variable(self, id)

    def nodeId(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        nodeId(DAGmodel self, DiscreteVariable var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_nodeId(self, var)

    def idFromName(self, name: 'std::string const &') -> "gum::NodeId":
        r"""
        idFromName(DAGmodel self, std::string const & name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.DAGmodel_idFromName(self, name)

    def variableFromName(self, name: 'std::string const &') -> "gum::DiscreteVariable const &":
        r"""
        variableFromName(DAGmodel self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.DAGmodel_variableFromName(self, name)

    def completeInstantiation(self) -> "gum::Instantiation":
        r"""
        completeInstantiation(DAGmodel self) -> Instantiation

        Get an instantiation over all the variables of the model.

        Returns
        ----------
        pyAgrum.instantiation
        	the complete instantiation

        """
        return _pyAgrum.DAGmodel_completeInstantiation(self)

    def arcs(self) -> "gum::ArcSet const &":
        r"""
        arcs(DAGmodel self) -> gum::ArcSet const &

        Returns
        -------
        list
        	The lisf of arcs in the graph

        """
        return _pyAgrum.DAGmodel_arcs(self)

    def parents(self, *args) -> "gum::NodeSet const &":
        r"""
        parents(DAGmodel self, gum::NodeId const id) -> gum::NodeSet const
        parents(DAGmodel self, std::string const & name) -> gum::NodeSet const &
        """
        return _pyAgrum.DAGmodel_parents(self, *args)

    def children(self, *args) -> "gum::NodeSet const &":
        r"""
        children(DAGmodel self, gum::NodeId const id) -> gum::NodeSet const
        children(DAGmodel self, std::string const & name) -> gum::NodeSet const &
        """
        return _pyAgrum.DAGmodel_children(self, *args)

    def moralGraph(self, clear: 'bool'=True) -> "gum::UndiGraph const &":
        r"""
        moralGraph(DAGmodel self, bool clear=True) -> UndiGraph

        Returns the moral graph of the BayesNet, formed by adding edges between all pairs of nodes that have a common child, and then making all edges in the graph undirected.

        Returns
        -------
        pyAgrum.UndiGraph
        	The moral graph

        """
        return _pyAgrum.DAGmodel_moralGraph(self, clear)

    def topologicalOrder(self, clear: 'bool'=True) -> "gum::Sequence< gum::NodeId > const &":
        r"""
        topologicalOrder(DAGmodel self, bool clear=True) -> gum::Sequence< gum::NodeId > const

        Returns
        -------
        List
            the list of the nodes Ids in a topological order

        Raises
        ------
        gum.InvalidDirectedCycle
        	If this graph contains cycles

        """
        return _pyAgrum.DAGmodel_topologicalOrder(self, clear)

    def log10DomainSize(self) -> "double":
        r"""
        log10DomainSize(DAGmodel self) -> double

        Returns
        -------
        double
        	The log10 domain size of the joint probability for the model.

        """
        return _pyAgrum.DAGmodel_log10DomainSize(self)

    def hasSameStructure(self, other: 'DAGmodel') -> "bool":
        r"""
        hasSameStructure(DAGmodel self, DAGmodel other) -> bool

        Parameters
        ----------
        pyAgrum.DAGmodel
        	a direct acyclic model

        Returns
        -------
        bool
            True if all the named node are the same and all the named arcs are the same

        """
        return _pyAgrum.DAGmodel_hasSameStructure(self, other)

# Register DAGmodel in _pyAgrum:
_pyAgrum.DAGmodel_swigregister(DAGmodel)
cvar = _pyAgrum.cvar
__list_end_safe = cvar.__list_end_safe
__list_end = cvar.__list_end

class EssentialGraph(object):
    r"""Proxy of C++ gum::EssentialGraph class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(EssentialGraph self) -> EssentialGraph
        __init__(EssentialGraph self, DAGmodel m) -> EssentialGraph
        __init__(EssentialGraph self, DAGmodel m, MixedGraph mg) -> EssentialGraph
        __init__(EssentialGraph self, EssentialGraph g) -> EssentialGraph
        """
        _pyAgrum.EssentialGraph_swiginit(self, _pyAgrum.new_EssentialGraph(*args))
    __swig_destroy__ = _pyAgrum.delete_EssentialGraph

    def mixedGraph(self) -> "gum::MixedGraph":
        r"""
        mixedGraph(EssentialGraph self) -> MixedGraph

        Returns
        -------
        pyAgrum.MixedGraph
        	the mixed graph

        """
        return _pyAgrum.EssentialGraph_mixedGraph(self)

    def toDot(self) -> "std::string":
        r"""
        toDot(EssentialGraph self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.EssentialGraph_toDot(self)

    def sizeArcs(self) -> "gum::Size":
        r"""
        sizeArcs(EssentialGraph self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.EssentialGraph_sizeArcs(self)

    def sizeEdges(self) -> "gum::Size":
        r"""
        sizeEdges(EssentialGraph self) -> gum::Size

        Returns
        -------
        int
            the number of edges in the graph

        """
        return _pyAgrum.EssentialGraph_sizeEdges(self)

    def sizeNodes(self) -> "gum::Size":
        r"""
        sizeNodes(EssentialGraph self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.EssentialGraph_sizeNodes(self)

    def size(self) -> "gum::Size":
        r"""
        size(EssentialGraph self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.EssentialGraph_size(self)

    def skeleton(self) -> "gum::UndiGraph":
        r"""skeleton(EssentialGraph self) -> UndiGraph"""
        return _pyAgrum.EssentialGraph_skeleton(self)

    def nodes(self) -> "PyObject *":
        r"""nodes(EssentialGraph self) -> PyObject *"""
        return _pyAgrum.EssentialGraph_nodes(self)

    def arcs(self) -> "PyObject *":
        r"""
        arcs(EssentialGraph self) -> PyObject *

        Returns
        -------
        list
        	The lisf of arcs in the EssentialGraph

        """
        return _pyAgrum.EssentialGraph_arcs(self)

    def parents(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        parents(EssentialGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.EssentialGraph_parents(self, id)

    def children(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        children(EssentialGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.EssentialGraph_children(self, id)

    def edges(self) -> "PyObject *":
        r"""
        edges(EssentialGraph self) -> PyObject *

        Returns
        -------
        List
          the list of the edges

        """
        return _pyAgrum.EssentialGraph_edges(self)

    def neighbours(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        neighbours(EssentialGraph self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
            the id of the checked node

        Returns
        -------
        Set
            The set of edges adjacent to the given node 

        """
        return _pyAgrum.EssentialGraph_neighbours(self, id)

# Register EssentialGraph in _pyAgrum:
_pyAgrum.EssentialGraph_swigregister(EssentialGraph)

class MarkovBlanket(object):
    r"""Proxy of C++ gum::MarkovBlanket class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(MarkovBlanket self, DAGmodel m, gum::NodeId n) -> MarkovBlanket
        __init__(MarkovBlanket self, DAGmodel m, std::string const & name) -> MarkovBlanket
        """
        _pyAgrum.MarkovBlanket_swiginit(self, _pyAgrum.new_MarkovBlanket(*args))
    __swig_destroy__ = _pyAgrum.delete_MarkovBlanket

    def mb(self) -> "gum::DiGraph":
        r"""
        mb(MarkovBlanket self) -> DiGraph

        Returns
        -------
        pyAgrum.DiGraph
          a copy of the directed graph

        """
        return _pyAgrum.MarkovBlanket_mb(self)

    def toDot(self) -> "std::string":
        r"""
        toDot(MarkovBlanket self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format 

        """
        return _pyAgrum.MarkovBlanket_toDot(self)

    def sizeArcs(self) -> "gum::Size":
        r"""
        sizeArcs(MarkovBlanket self) -> gum::Size

        Returns
        -------
        int
            the number of arcs in the graph

        """
        return _pyAgrum.MarkovBlanket_sizeArcs(self)

    def sizeNodes(self) -> "gum::Size":
        r"""
        sizeNodes(MarkovBlanket self) -> gum::Size

        Returns
        -------
        int
        	the number of nodes in the graph

        """
        return _pyAgrum.MarkovBlanket_sizeNodes(self)

    def size(self) -> "gum::Size":
        r"""
        size(MarkovBlanket self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.MarkovBlanket_size(self)

    def hasSameStructure(self, other: 'DAGmodel') -> "bool":
        r"""
        hasSameStructure(MarkovBlanket self, DAGmodel other) -> bool

        Parameters
        ----------
        pyAgrum.DAGmodel
        	a direct acyclic model

        Returns
        -------
        bool
            True if all the named node are the same and all the named arcs are the same 

        """
        return _pyAgrum.MarkovBlanket_hasSameStructure(self, other)

    def nodes(self) -> "PyObject *":
        r"""
        nodes(MarkovBlanket self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.MarkovBlanket_nodes(self)

    def arcs(self) -> "PyObject *":
        r"""
        arcs(MarkovBlanket self) -> PyObject *

        Returns
        -------
        List
        	the list of the arcs

        """
        return _pyAgrum.MarkovBlanket_arcs(self)

    def parents(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        parents(MarkovBlanket self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.MarkovBlanket_parents(self, id)

    def children(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        children(MarkovBlanket self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.MarkovBlanket_children(self, id)

# Register MarkovBlanket in _pyAgrum:
_pyAgrum.MarkovBlanket_swigregister(MarkovBlanket)

class StructuralComparator(object):
    r"""Proxy of C++ gum::StructuralComparator class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self):
        r"""__init__(StructuralComparator self) -> StructuralComparator"""
        _pyAgrum.StructuralComparator_swiginit(self, _pyAgrum.new_StructuralComparator())
    __swig_destroy__ = _pyAgrum.delete_StructuralComparator

    def compare(self, *args) -> "void":
        r"""
        compare(StructuralComparator self, DiGraph ref, DiGraph test)
        compare(StructuralComparator self, UndiGraph ref, UndiGraph test)
        compare(StructuralComparator self, MixedGraph ref, MixedGraph test)

        Use to compare the edges/arcs of two structure of the same type and same sizes (either DiGraph, UndiGraph or MixedGraph).

        Could be use to compare a BN and its learned version.

        Parameters
        ----------
        ref :
        	the structure of reference
        test :
        	the structure we want to test

        """
        return _pyAgrum.StructuralComparator_compare(self, *args)

    def precision_skeleton(self) -> "double":
        r"""
        precision_skeleton(StructuralComparator self) -> double

        Rate of true postive over labelized edges.

        Returns
        -------
        double
        	the precision of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_precision_skeleton(self)

    def recall_skeleton(self) -> "double":
        r"""
        recall_skeleton(StructuralComparator self) -> double

        Rate of true postive over labelized edges.

        Returns
        -------
        double
        	the recall of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_recall_skeleton(self)

    def f_score_skeleton(self) -> "double":
        r"""
        f_score_skeleton(StructuralComparator self) -> double

        Harmonic mean between recall and precision.

        Returns
        -------
        double
        	the tarmonic mean of the tested graph skeleton

        """
        return _pyAgrum.StructuralComparator_f_score_skeleton(self)

    def precision(self) -> "double":
        r"""
        precision(StructuralComparator self) -> double

        Rate of true postive over postively labelized arcs/edges.

        Returns
        -------
        double
        	the precision of the tested graph

        """
        return _pyAgrum.StructuralComparator_precision(self)

    def recall(self) -> "double":
        r"""
        recall(StructuralComparator self) -> double

        Rate of true postive over labelized arcs/edges.

        Returns
        -------
        double
        	the recall of the tested graph

        """
        return _pyAgrum.StructuralComparator_recall(self)

    def f_score(self) -> "double":
        r"""
        f_score(StructuralComparator self) -> double

        Harmonic mean between recall and precision.

        Returns
        -------
        double
        	the harmonic mean of the tested graph

        """
        return _pyAgrum.StructuralComparator_f_score(self)

# Register StructuralComparator in _pyAgrum:
_pyAgrum.StructuralComparator_swigregister(StructuralComparator)

class ApproximationScheme(object):
    r"""

    Used to parametrize stopping criteria in approximate inference or learning algorithm.

    Available constructors:
    	``ApproximationScheme() -> ApproximationScheme``

    	``ApproximationScheme(v) -> ApproximationScheme``

    Parameters
    ----------
    v : bool

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, v: 'bool'=False):
        r"""__init__(ApproximationScheme self, bool v=False) -> ApproximationScheme"""
        _pyAgrum.ApproximationScheme_swiginit(self, _pyAgrum.new_ApproximationScheme(v))
    __swig_destroy__ = _pyAgrum.delete_ApproximationScheme

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(ApproximationScheme self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.ApproximationScheme_setEpsilon(self, eps)

    def epsilon(self) -> "double":
        r"""
        epsilon(ApproximationScheme self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.ApproximationScheme_epsilon(self)

    def disableEpsilon(self) -> "void":
        r"""
        disableEpsilon(ApproximationScheme self)

        Disable epsilon as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableEpsilon(self)

    def enableEpsilon(self) -> "void":
        r"""
        enableEpsilon(ApproximationScheme self)

        Enable epsilon as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableEpsilon(self)

    def isEnabledEpsilon(self) -> "bool":
        r"""
        isEnabledEpsilon(ApproximationScheme self) -> bool

        Returns
        -------
        bool
          True if epsilon is used as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_isEnabledEpsilon(self)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(ApproximationScheme self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.ApproximationScheme_setMinEpsilonRate(self, rate)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(ApproximationScheme self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.ApproximationScheme_minEpsilonRate(self)

    def disableMinEpsilonRate(self) -> "void":
        r"""
        disableMinEpsilonRate(ApproximationScheme self)

        Disable a min epsilon rate as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMinEpsilonRate(self)

    def enableMinEpsilonRate(self) -> "void":
        r"""
        enableMinEpsilonRate(ApproximationScheme self)

        Enable a min epsilon rate as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMinEpsilonRate(self)

    def isEnabledMinEpsilonRate(self) -> "bool":
        r"""
        isEnabledMinEpsilonRate(ApproximationScheme self) -> bool

        Returns
        -------
        bool
          True if epsilon rate is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMinEpsilonRate(self)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(ApproximationScheme self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.ApproximationScheme_setMaxIter(self, max)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(ApproximationScheme self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.ApproximationScheme_maxIter(self)

    def disableMaxIter(self) -> "void":
        r"""
        disableMaxIter(ApproximationScheme self)

        Disable max iterations as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMaxIter(self)

    def enableMaxIter(self) -> "void":
        r"""
        enableMaxIter(ApproximationScheme self)

        Enable max iterations as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMaxIter(self)

    def isEnabledMaxIter(self) -> "bool":
        r"""
        isEnabledMaxIter(ApproximationScheme self) -> bool

        Returns
        -------
        bool
          True if max iterations is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMaxIter(self)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(ApproximationScheme self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.ApproximationScheme_setMaxTime(self, timeout)

    def maxTime(self) -> "double":
        r"""
        maxTime(ApproximationScheme self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.ApproximationScheme_maxTime(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(ApproximationScheme self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.ApproximationScheme_currentTime(self)

    def disableMaxTime(self) -> "void":
        r"""
        disableMaxTime(ApproximationScheme self)

        Disable max time as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_disableMaxTime(self)

    def enableMaxTime(self) -> "void":
        r"""
        enableMaxTime(ApproximationScheme self)

        Enable max time as a stopping criterion.

        """
        return _pyAgrum.ApproximationScheme_enableMaxTime(self)

    def isEnabledMaxTime(self) -> "bool":
        r"""
        isEnabledMaxTime(ApproximationScheme self) -> bool

        Returns
        -------
        bool
          True if max time is used as a stopping criterion

        """
        return _pyAgrum.ApproximationScheme_isEnabledMaxTime(self)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(ApproximationScheme self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ApproximationScheme_setPeriodSize(self, p)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(ApproximationScheme self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ApproximationScheme_periodSize(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(ApproximationScheme self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.ApproximationScheme_setVerbosity(self, v)

    def verbosity(self) -> "bool":
        r"""
        verbosity(ApproximationScheme self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.ApproximationScheme_verbosity(self)

    def stateApproximationScheme(self) -> "gum::IApproximationSchemeConfiguration::ApproximationSchemeSTATE":
        r"""
        stateApproximationScheme(ApproximationScheme self) -> gum::IApproximationSchemeConfiguration::ApproximationSchemeSTATE

        Returns
        -------
        int
          the state of the approximation scheme

        """
        return _pyAgrum.ApproximationScheme_stateApproximationScheme(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(ApproximationScheme self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.ApproximationScheme_nbrIterations(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(ApproximationScheme self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.ApproximationScheme_history(self)

    def initApproximationScheme(self) -> "void":
        r"""
        initApproximationScheme(ApproximationScheme self)

        Initiate the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_initApproximationScheme(self)

    def startOfPeriod(self) -> "bool":
        r"""
        startOfPeriod(ApproximationScheme self) -> bool

        Returns
        -------
        bool
          True if it is a start of a period

        """
        return _pyAgrum.ApproximationScheme_startOfPeriod(self)

    def updateApproximationScheme(self, incr: 'unsigned int'=1) -> "void":
        r"""
        updateApproximationScheme(ApproximationScheme self, unsigned int incr=1)

        Update the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_updateApproximationScheme(self, incr)

    def remainingBurnIn(self) -> "gum::Size":
        r"""
        remainingBurnIn(ApproximationScheme self) -> gum::Size

        Returns
        -------
        int
          the number of remaining burn in

        """
        return _pyAgrum.ApproximationScheme_remainingBurnIn(self)

    def stopApproximationScheme(self) -> "void":
        r"""
        stopApproximationScheme(ApproximationScheme self)

        Stop the approximation scheme.

        """
        return _pyAgrum.ApproximationScheme_stopApproximationScheme(self)

    def continueApproximationScheme(self, error: 'double') -> "bool":
        r"""
        continueApproximationScheme(ApproximationScheme self, double error) -> bool

        Continue the approximation scheme.

        Parameters
        ----------
        error : double

        """
        return _pyAgrum.ApproximationScheme_continueApproximationScheme(self, error)

# Register ApproximationScheme in _pyAgrum:
_pyAgrum.ApproximationScheme_swigregister(ApproximationScheme)

FindBarrenNodesType_FIND_NO_BARREN_NODES = _pyAgrum.FindBarrenNodesType_FIND_NO_BARREN_NODES

FindBarrenNodesType_FIND_BARREN_NODES = _pyAgrum.FindBarrenNodesType_FIND_BARREN_NODES


def randomDistribution(n: 'gum::Size') -> "std::vector< double,std::allocator< double > >":
    r"""
    randomDistribution(gum::Size n) -> Vector

    Parameters
    ----------
    n : int
      The number of modalities for the ditribution.

    Returns
    -------
    a random discrete distribution. 

    """
    return _pyAgrum.randomDistribution(n)
class DiscretizedVariable(IDiscretizedVariable):
    r"""



    DiscretizedVariable is a discrete random variable with a set of ``ticks`` defining intervalls.

    Available constructors:

        ``DiscretizedVariable(aName, aDesc='') -> DiscretizedVariable``

        ``DiscretizedVariable(aDDRV) -> DiscretizedVariable``

    Parameters
    ----------
    aName: str
      The name of the variable
    aDesc: str
      The (optional) description of the variable
    aDDRV: pyAgrum.DiscretizedVariable
      Another `DiscretizedVariable` that will be copied

    Examples
    --------
    >>> import pyAgrum as gum
    >>>
    >>> vX=gum.DiscretizedVariable('X','X has been discretized')
    >>> vX.addTick(1).addTick(2).addTick(3).addTick(3.1415) #doctest: +ELLIPSIS
    >>> ## <pyAgrum.pyAgrum.DiscretizedVariable;...>
    >>> print(vX)
    >>> ## X<[1;2[,[2;3[,[3;3.1415]>
    >>>
    >>> vX.isTick(4)
    >>> ## False
    >>>
    >>> vX.labels()
    >>> ## ('[1;2[', '[2;3[', '[3;3.1415]')
    >>>
    >>> # where is the real value 2.5 ?
    >>> vX.index('2.5')
    >>> ## 1

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(DiscretizedVariable self, std::string const & aName, std::string const & aDesc) -> DiscretizedVariable
        __init__(DiscretizedVariable self, std::string const & aName, std::string const & aDesc, Vector ticks) -> DiscretizedVariable
        __init__(DiscretizedVariable self, DiscretizedVariable aDRV) -> DiscretizedVariable
        """
        _pyAgrum.DiscretizedVariable_swiginit(self, _pyAgrum.new_DiscretizedVariable(*args))
    __swig_destroy__ = _pyAgrum.delete_DiscretizedVariable

    def clone(self) -> "gum::DiscretizedVariable< double > *":
        r"""
        clone(DiscretizedVariable self) -> DiscretizedVariable

        Returns
        -------
        pyAgrum.DiscretizedVariable
        	a copy of the DiscretizedVariable

        """
        return _pyAgrum.DiscretizedVariable_clone(self)

    def varType(self) -> "gum::VarType":
        r"""
        varType(DiscretizedVariable self) -> gum::VarType

        returns the type of variable

        Returns
        -------
        int :
        	the type of the variable, 0: DiscretizedVariable, 1: LabelizedVariable, 2: RangeVariable

        """
        return _pyAgrum.DiscretizedVariable_varType(self)

    def isTick(self, aTick: 'double const &') -> "bool":
        r"""
        isTick(DiscretizedVariable self, double const & aTick) -> bool

        Parameters
        ----------
        aTick : double
        	the Tick to be tested

        Returns
        -------
        bool :
        	True if the Tick already exists

        """
        return _pyAgrum.DiscretizedVariable_isTick(self, aTick)

    def addTick(self,*args):
        """
        Parameters
        ----------
        aTick : double
            the Tick to be added

        Returns
        -------
        pyAgrum.DiscretizedVariable
            the discretized variable

        Raises
        ------
        gum.DefaultInLabel
            If the tick is already defined
        """
        _pyAgrum.DiscretizedVariable_addTick(self,*args)
        return self



    def eraseTicks(self) -> "void":
        r"""
        eraseTicks(DiscretizedVariable self)

        erase all the Ticks 

        """
        return _pyAgrum.DiscretizedVariable_eraseTicks(self)

    def label(self, i: 'gum::Idx') -> "std::string":
        r"""
        label(DiscretizedVariable self, gum::Idx i) -> std::string

        Parameters
        ----------
        i : int
        	the index of the label we wish to return

        Returns
        -------
        str
        	the indice-th label

        Raises
        ------
        gum.OutOfBound
        	If the variable does not contain the label

        """
        return _pyAgrum.DiscretizedVariable_label(self, i)

    def numerical(self, indice: 'gum::Idx') -> "double":
        r"""
        numerical(DiscretizedVariable self, gum::Idx indice) -> double

        Parameters
        ----------
        indice : int
        	an index

        Returns
        -------
        float
        	the numerical representation of the indice-th value

        """
        return _pyAgrum.DiscretizedVariable_numerical(self, indice)

    def index(self, label: 'std::string const &') -> "gum::Idx":
        r"""
        index(DiscretizedVariable self, std::string const & label) -> gum::Idx

        Parameters
        ----------
        label : str
        	a label

        Returns
        -------
        int
        	the indice of the label

        """
        return _pyAgrum.DiscretizedVariable_index(self, label)

    def domainSize(self) -> "gum::Size":
        r"""
        domainSize(DiscretizedVariable self) -> gum::Size

        Returns
        -------
        int
        	the number of modalities in the variable domain

        """
        return _pyAgrum.DiscretizedVariable_domainSize(self)

    def domain(self) -> "std::string const":
        r"""
        domain(DiscretizedVariable self) -> std::string const

        Returns
        -------
        str
            the domain of the variable as a string

        """
        return _pyAgrum.DiscretizedVariable_domain(self)

    def tick(self, i: 'gum::Idx') -> "double const &":
        r"""
        tick(DiscretizedVariable self, gum::Idx i) -> double const &

        Indicate the index of the Tick

        Parameters
        ----------
        i : int
        	the index of the Tick

        Returns
        -------
        aTick : double
        	the index-th Tick

        Raises
        ------
        gum.NotFound
        	If the index is greater than the number of Ticks

        """
        return _pyAgrum.DiscretizedVariable_tick(self, i)

    def ticks(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        ticks(DiscretizedVariable self) -> Vector

        Returns
        -------
        tuple :
        	a tuple containing all the Ticks

        """
        return _pyAgrum.DiscretizedVariable_ticks(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(DiscretizedVariable self) -> std::string"""
        return _pyAgrum.DiscretizedVariable___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(DiscretizedVariable self) -> std::string"""
        return _pyAgrum.DiscretizedVariable___str__(self)

# Register DiscretizedVariable in _pyAgrum:
_pyAgrum.DiscretizedVariable_swigregister(DiscretizedVariable)

class MultiDimContainer(object):
    r"""
    Proxy of C++ gum::MultiDimContainer< double > class.
    Proxy of C++ gum::MultiDimContainer< double > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    __swig_destroy__ = _pyAgrum.delete_MultiDimContainer

    def set(self, i: 'Instantiation', value: 'double const &') -> "void":
        r"""set(MultiDimContainer self, Instantiation i, double const & value)"""
        return _pyAgrum.MultiDimContainer_set(self, i, value)

    def get(self, i: 'Instantiation') -> "double":
        r"""get(MultiDimContainer self, Instantiation i) -> double"""
        return _pyAgrum.MultiDimContainer_get(self, i)

    def fill(self, d: 'double const &') -> "void":
        r"""fill(MultiDimContainer self, double const & d)"""
        return _pyAgrum.MultiDimContainer_fill(self, d)

    def populate(self, *args) -> "void":
        r"""
        populate(MultiDimContainer self, Vector v)
        populate(MultiDimContainer self, std::initializer_list< double > l)
        """
        return _pyAgrum.MultiDimContainer_populate(self, *args)

    def copyFrom(self, *args) -> "void":
        r"""
        copyFrom(MultiDimContainer self, MultiDimContainer src)
        copyFrom(MultiDimContainer self, MultiDimContainer src, Instantiation p_i)
        """
        return _pyAgrum.MultiDimContainer_copyFrom(self, *args)

    def extractFrom(self, src: 'MultiDimContainer', mask: 'Instantiation') -> "void":
        r"""extractFrom(MultiDimContainer self, MultiDimContainer src, Instantiation mask)"""
        return _pyAgrum.MultiDimContainer_extractFrom(self, src, mask)

    def content(self, *args) -> "gum::MultiDimImplementation< double > *":
        r"""
        content(MultiDimContainer self) -> gum::MultiDimImplementation< double > const
        content(MultiDimContainer self) -> gum::MultiDimImplementation< double > *
        """
        return _pyAgrum.MultiDimContainer_content(self, *args)

    def getMasterRef(self, *args) -> "gum::MultiDimAdressable const &":
        r"""
        getMasterRef(MultiDimContainer self) -> MultiDimAdressable
        getMasterRef(MultiDimContainer self) -> MultiDimAdressable
        """
        return _pyAgrum.MultiDimContainer_getMasterRef(self, *args)

    def copy(self, src: 'MultiDimContainer') -> "void":
        r"""copy(MultiDimContainer self, MultiDimContainer src)"""
        return _pyAgrum.MultiDimContainer_copy(self, src)

    def newFactory(self) -> "gum::MultiDimContainer< double > *":
        r"""newFactory(MultiDimContainer self) -> MultiDimContainer"""
        return _pyAgrum.MultiDimContainer_newFactory(self)

    def toString(self, *args) -> "std::string const":
        r"""
        toString(MultiDimContainer self) -> std::string const
        toString(MultiDimContainer self, Instantiation i) -> std::string const
        """
        return _pyAgrum.MultiDimContainer_toString(self, *args)

    def __eq__(self, p: 'MultiDimContainer') -> "bool":
        r"""__eq__(MultiDimContainer self, MultiDimContainer p) -> bool"""
        return _pyAgrum.MultiDimContainer___eq__(self, p)

    def __ne__(self, p: 'MultiDimContainer') -> "bool":
        r"""__ne__(MultiDimContainer self, MultiDimContainer p) -> bool"""
        return _pyAgrum.MultiDimContainer___ne__(self, p)

    def apply(self, f: 'std::function< double (double) >') -> "void":
        r"""apply(MultiDimContainer self, std::function< double (double) > f)"""
        return _pyAgrum.MultiDimContainer_apply(self, f)

    def reduce(self, f: 'std::function< double (double,double) >', base: 'double') -> "double":
        r"""reduce(MultiDimContainer self, std::function< double (double,double) > f, double base) -> double"""
        return _pyAgrum.MultiDimContainer_reduce(self, f, base)

    def beginMultipleChanges(self) -> "void":
        r"""beginMultipleChanges(MultiDimContainer self)"""
        return _pyAgrum.MultiDimContainer_beginMultipleChanges(self)

    def endMultipleChanges(self, *args) -> "void":
        r"""
        endMultipleChanges(MultiDimContainer self)
        endMultipleChanges(MultiDimContainer self, double const & v)
        """
        return _pyAgrum.MultiDimContainer_endMultipleChanges(self, *args)

# Register MultiDimContainer in _pyAgrum:
_pyAgrum.MultiDimContainer_swigregister(MultiDimContainer)

class Potential(object):
    r"""



    Class representing a potential.

    Available constructors:

      ``Potential() -> Potential``

      ``Potential(src) -> Potential``

    Parameters
    ----------
    src: pyAgrum.Potential
      The Potential to copy

    Returns
    -------
    pyAgrum.Potential
      The new Potential


    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args):
        r"""
        __init__(Potential self) -> Potential
        __init__(Potential self, gum::MultiDimImplementation< double > * aContent) -> Potential
        __init__(Potential self, gum::MultiDimImplementation< double > * aContent, MultiDimContainer src) -> Potential
        __init__(Potential self, Potential src) -> Potential
        __init__(Potential self, Potential _from) -> Potential
        """
        _pyAgrum.Potential_swiginit(self, _pyAgrum.new_Potential(*args))

        self._notSync=True
        self._list_vars=list()



    __swig_destroy__ = _pyAgrum.delete_Potential

    def newFactory(self) -> "gum::Potential< double > *":
        r"""
        newFactory(Potential self) -> Potential

        Erase the Potential content and create a new empty one.

        Returns
        -------
        pyAgrum.Potential
         a reference to the new Potential

        """
        return _pyAgrum.Potential_newFactory(self)

    def isNonZeroMap(self) -> "gum::Potential< double >":
        r"""
        isNonZeroMap(Potential self) -> Potential

        Returns
        -------
        pyAgrum.Potential
          a boolean-like potential using the predicate isNonZero

        """
        return _pyAgrum.Potential_isNonZeroMap(self)

    def sum(self) -> "double":
        r"""
        sum(Potential self) -> double

        Returns
        -------
        double :
          the sum of all elements in the Potential

        """
        return _pyAgrum.Potential_sum(self)

    def product(self) -> "double":
        r"""
        product(Potential self) -> double

        Returns
        -------
        double
          the product of all elements in the Potential

        """
        return _pyAgrum.Potential_product(self)

    def max(self) -> "double":
        r"""
        max(Potential self) -> double

        Returns
        -------
        double
          the maximum of all elements in the Potential

        """
        return _pyAgrum.Potential_max(self)

    def min(self) -> "double":
        r"""
        min(Potential self) -> double

        Returns
        -------
        double
          the min of all elements in the Potential

        """
        return _pyAgrum.Potential_min(self)

    def maxNonOne(self) -> "double":
        r"""
        maxNonOne(Potential self) -> double

        Returns
        -------
        double
          the maximum of non one elements in the Potential

        Raises
        ------
        gum.NotFound
          If all value == 1.0

        """
        return _pyAgrum.Potential_maxNonOne(self)

    def minNonZero(self) -> "double":
        r"""
        minNonZero(Potential self) -> double

        Returns
        -------
        double
          the min of non zero elements in the Potential

        Raises
        ------
        gum.NotFound
          If all value == 0.0

        """
        return _pyAgrum.Potential_minNonZero(self)

    def findAll(self, v: 'double') -> "gum::Set< gum::Instantiation >":
        r"""findAll(Potential self, double v) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_findAll(self, v)

    def argmax(self) -> "gum::Set< gum::Instantiation >":
        r"""argmax(Potential self) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_argmax(self)

    def argmin(self) -> "gum::Set< gum::Instantiation >":
        r"""argmin(Potential self) -> gum::Set< gum::Instantiation >"""
        return _pyAgrum.Potential_argmin(self)

    def entropy(self) -> "double":
        r"""
        entropy(Potential self) -> double

        Returns
        -------
        double
          the entropy of the potential

        """
        return _pyAgrum.Potential_entropy(self)

    def fillWith(self, *args) -> "gum::Potential< double > const &":
        r"""
        fillWith(Potential self, Potential src) -> Potential
        fillWith(Potential self, Potential src, Vector_string mapSrc) -> Potential
        fillWith(Potential self, Vector v) -> Potential
        fillWith(Potential self, double const & v) -> Potential

        Automatically fills the potential with v.

        Parameters
        ----------
        v : number or list or pyAgrum.Potential the number of parameters of the Potential
            a value or a list/pyAgrum.Potential containing the values to fill the Potential with.

        Warning
        -------
            if v is a list, the size of the list must be the
            if v is a pyAgrum.Potential. It must to contain variables with exactly the same names and labels but not necessarily the same variables.

        Returns
        -------
        pyAgrum.Potential
              a reference to the modified potentia

        Raises
        ------
        gum.SizeError
          If v size's does not matches the domain size. 

        """
        val = _pyAgrum.Potential_fillWith(self, *args)

        self._notSync=True
        return self


        return val


    def abs(self) -> "gum::Potential< double > const &":
        r"""
        abs(Potential self) -> Potential

        Apply abs on every element of the container

        Returns
        -------
        pyAgrum.Potential
            a reference to the modified potential.

        """
        val = _pyAgrum.Potential_abs(self)

        self._notSync=True
        return self


        return val


    def normalize(self) -> "gum::Potential< double > const &":
        r"""
        normalize(Potential self) -> Potential

        Normalize the Potential (do nothing if sum is 0)

        Returns
        -------
        pyAgrum.Potential
          a reference to the normalized Potential

        """
        val = _pyAgrum.Potential_normalize(self)

        self._notSync=True
        return self


        return val


    def sq(self) -> "gum::Potential< double > const &":
        r"""
        sq(Potential self) -> Potential

        Square all the values in the Potential

        """
        val = _pyAgrum.Potential_sq(self)

        self._notSync=True
        return self


        return val


    def KL(self, p: 'Potential') -> "double":
        r"""
        KL(Potential self, Potential p) -> double

        Check the compatibility and compute the Kullback-Leibler divergence between the potential and.

        Parameters
        ----------
        p : pyAgrum.Potential
          the potential from which we want to calculate the divergence.

        Returns
        -------
        float
          The value of the divergence

        Raises
        ------
        gum.InvalidArgument
          If p is not compatible with the potential (dimension, variables)
        gum.FatalError
          If a zero is found in p or the potential and not in the other. 

        """
        return _pyAgrum.Potential_KL(self, p)

    def normalizeAsCPT(self) -> "void":
        r"""
        normalizeAsCPT(Potential self)

        Normalize the Potential as a CPT

        Returns
        -------
        pyAgrum.Potential
          a reference to the normalized Potential

        Raises
        ------
        gum.FatalError
          If some distribution sums to 0

        """
        val = _pyAgrum.Potential_normalizeAsCPT(self)

        self._notSync=True
        return self


        return val


    def scale(self, v: 'double') -> "gum::Potential< double > const &":
        r"""
        scale(Potential self, double v) -> Potential

        Create a new potential multiplied by v.

        Parameters
        ----------
        v : double
          a multiplier

        Returns
        -------
          a reference to the modified potential

        """
        val = _pyAgrum.Potential_scale(self, v)

        self._notSync=True
        return self


        return val


    def translate(self, v: 'double') -> "gum::Potential< double > const &":
        r"""
        translate(Potential self, double v) -> Potential

        Create a new potential added with v.

        Parameters
        ----------
        v : double
          The value to be added

        Returns
        -------
          a reference to the modified potential

        """
        val = _pyAgrum.Potential_translate(self, v)

        self._notSync=True
        return self


        return val


    def draw(self) -> "gum::Idx":
        r"""
        draw(Potential self) -> gum::Idx

        draw a value using the potential as a probability table.

        Returns
        -------
        int
          the index of the drawn value

        """
        return _pyAgrum.Potential_draw(self)

    def __add__(self, p2: 'Potential') -> "gum::Potential< double >":
        r"""__add__(Potential self, Potential p2) -> Potential"""
        return _pyAgrum.Potential___add__(self, p2)

    def __sub__(self, p2: 'Potential') -> "gum::Potential< double >":
        r"""__sub__(Potential self, Potential p2) -> Potential"""
        return _pyAgrum.Potential___sub__(self, p2)

    def __mul__(self, p2: 'Potential') -> "gum::Potential< double >":
        r"""__mul__(Potential self, Potential p2) -> Potential"""
        return _pyAgrum.Potential___mul__(self, p2)

    def __iadd__(self, r: 'Potential') -> "gum::Potential< double > &":
        r"""__iadd__(Potential self, Potential r) -> Potential"""
        return _pyAgrum.Potential___iadd__(self, r)

    def __imul__(self, r: 'Potential') -> "gum::Potential< double > &":
        r"""__imul__(Potential self, Potential r) -> Potential"""
        return _pyAgrum.Potential___imul__(self, r)

    def __isub__(self, r: 'Potential') -> "gum::Potential< double > &":
        r"""__isub__(Potential self, Potential r) -> Potential"""
        return _pyAgrum.Potential___isub__(self, r)

    def __itruediv__(self, *args):
        return _pyAgrum.Potential___itruediv__(self, *args)
    __idiv__ = __itruediv__



    def __repr__(self) -> "std::string":
        r"""__repr__(Potential self) -> std::string"""
        return _pyAgrum.Potential___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(Potential self) -> std::string"""
        return _pyAgrum.Potential___str__(self)

    def extract(self, *args) -> "gum::Potential< double >":
        r"""
        extract(Potential self, Instantiation inst) -> Potential
        extract(Potential self, PyObject * dict) -> Potential

        create a new Potential extracted from self given a partial instantiation.

        Parameters
        ----------
        inst : pyAgrum.instantiation
          a partial instantiation
        dict : dict
          a dictionnary containing discrete variables (?)

        Returns
        -------
        pyAgrum.Potential
          the new Potential

        """
        return _pyAgrum.Potential_extract(self, *args)

    def reorganize(self, *args) -> "gum::Potential< double >":
        r"""
        reorganize(Potential self, std::vector< gum::DiscreteVariable const *,std::allocator< gum::DiscreteVariable const * > > const & vars) -> Potential
        reorganize(Potential self, PyObject * varnames) -> Potential

        Create a new Potential with another order.

        Returns
        -------
        varnames : list
          a list of the var names in the new order

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        """
        return _pyAgrum.Potential_reorganize(self, *args)

    def putFirst(self, varname: 'PyObject *') -> "gum::Potential< double >":
        r"""
        putFirst(Potential self, PyObject * varname) -> Potential

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the index should be 0.

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        Raises
        ------
        gum.InvalidArgument
          If the var is not in the potential 

        """
        return _pyAgrum.Potential_putFirst(self, varname)

    def margSumOut(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margSumOut(Potential self, PyObject * varnames) -> Potential

        Projection using sum as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument 
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margSumOut(self, varnames)

    def margProdOut(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margProdOut(Potential self, PyObject * varnames) -> Potential

        Projection using multiplication as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margProdOut(self, varnames)

    def margMaxOut(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margMaxOut(Potential self, PyObject * varnames) -> Potential

        Projection using max as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Raises
        ------
        gum.InvalidArgument
          If varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margMaxOut(self, varnames)

    def margMinOut(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margMinOut(Potential self, PyObject * varnames) -> Potential

        Projection using min as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to eliminate

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        Warnings
        --------
        InvalidArgument raised if varnames contains only one variable that does not exist in the Potential

        """
        return _pyAgrum.Potential_margMinOut(self, varnames)

    def margSumIn(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margSumIn(Potential self, PyObject * varnames) -> Potential

        Projection using sum as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margSumIn(self, varnames)

    def margProdIn(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margProdIn(Potential self, PyObject * varnames) -> Potential

        Projection using multiplication as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margProdIn(self, varnames)

    def margMaxIn(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margMaxIn(Potential self, PyObject * varnames) -> Potential

        Projection using max as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margMaxIn(self, varnames)

    def margMinIn(self, varnames: 'PyObject *') -> "gum::Potential< double >":
        r"""
        margMinIn(Potential self, PyObject * varnames) -> Potential

        Projection using min as operation.

        Parameters
        ----------
        varnames : set
          the set of vars to keep

        Returns
        -------
        pyAgrum.Potential
          the projected Potential

        """
        return _pyAgrum.Potential_margMinIn(self, varnames)

    def __truediv__(self, *args) -> "gum::Potential< double >":
        r"""
        __truediv__(Potential self, Potential p2) -> Potential
        __truediv__(Potential self, Potential b) -> Potential
        """
        return _pyAgrum.Potential___truediv__(self, *args)

    def __div__(self, b: 'Potential') -> "gum::Potential< double >":
        r"""__div__(Potential self, Potential b) -> Potential"""
        return _pyAgrum.Potential___div__(self, b)

    def __eq__(self, *args) -> "bool":
        r"""
        __eq__(Potential self, Potential r) -> bool
        __eq__(Potential self, Potential b) -> bool
        """
        return _pyAgrum.Potential___eq__(self, *args)

    def __ne__(self, *args) -> "bool":
        r"""
        __ne__(Potential self, Potential r) -> bool
        __ne__(Potential self, Potential b) -> bool
        """
        return _pyAgrum.Potential___ne__(self, *args)


    def variablesSequence(self):
        """
        Returns
        -------
        list
            a list containing the sequence of variables
        """
        varlist = []
        for i in range(0, self.nbrDim()):
            varlist.append(self.variable(i))
        return varlist


    def __fill_distrib__(self):
      if not hasattr(self,'_notSync'):
        self._notSync=True

      if self._notSync:
        self._notSync=False
        self._var_names = []
        self._var_dims = []
        if self.empty():
            i = Instantiation(self)
            content = [self.get(i)]
            self.__distrib__ = numpy.array(content, dtype=numpy.float64) #M
            return

        content = []
        i = Instantiation(self)
        i.setFirst()
        while not i.end():
            content.append(self.get(i))
            i.inc()
        self.__distrib__ = numpy.array(content, dtype=numpy.float64) #M
        for var in self.variablesSequence():
            self._var_names.append(var.name())
            self._var_dims.append(var.domainSize())
        self._var_names.reverse()
        self._var_dims.reverse()
        self.__distrib__.shape = tuple(self._var_dims)



    def __indexfromdict__(self, id_dict):
        index = []
        for name, dim in zip(self._var_names, self._var_dims):
            if name in id_dict:
                id_value = id_dict[name]
                if isinstance(id_value, str):
    # id_value is a label of a LabelizedVar
                    i = self._var_names.index(name)
                    var = self.variable(len(self._var_names) - 1 - i)
                    id_value = var[id_value]
                if id_value >= dim:
                    raise IndexError("\"%s\" size is %d !"%(name, dim))
                index.append(id_value)
            else:
                index.append(slice(None, None, None)) # equivalent to ':'
        return tuple(index)



    def tolist(self):
        """
        Returns
        -------
        list
            the potential as a list
        """
        self.__fill_distrib__()
        return self.__distrib__.tolist()



    def toarray(self):
        """
        Returns
        -------
        array
            the potential as an array
        """
        return numpy.array(self.tolist())



    def __getitem__(self, id):
        self.__fill_distrib__()
        if self.empty():
            return self.__distrib__[0]

        if isinstance(id, dict):
            id_slice = self.__indexfromdict__(id)
        else:
            id_slice = id
        return self.__distrib__[id_slice]



    def __setitem__(self, id, value):
        self.__fill_distrib__()
        if self.empty():
            self.fill(value)
            self.__distrib__= numpy.array([value], dtype=numpy.float64) #M
            return

        if isinstance(id, dict):
            id_slice = self.__indexfromdict__(id)
        else:
            id_slice = id
        self.__distrib__[id_slice] = value
        self.fillWith(self.__distrib__.reshape(self.__distrib__.size).tolist())



    @property
    def var_names(self):
        """
        Returns
        -------
        list
            a list containing the name of each variables in the potential

        Warnings
        --------
            Listed in reverse from the variable enumeration order
        """
        self.__fill_distrib__()
        return self._var_names



    @property
    def var_dims(self):
        """
        Returns
        -------
        list
            a list containing the dimensions of each variables in the potential
        """
        self.__fill_distrib__()
        return self._var_dims



    def get(self, i: 'Instantiation') -> "double":
        r"""
        get(Potential self, Instantiation i) -> double

        Parameters
        ----------
        i : pyAgrum.Instantiation
          an Instantiation

        Returns
        -------
        double
          the value in the Potential at the position given by the instantiation

        """
        return _pyAgrum.Potential_get(self, i)

    def set(self, i: 'Instantiation', value: 'double const &') -> "void":
        r"""
        set(Potential self, Instantiation i, double const & value)

        Change the value pointed by i

        Parameters
        ----------
        i : pyAgrum.Instantiation
          The Instantiation to be changed
        value : double
          The new value of the Instantiation

        """
        val = _pyAgrum.Potential_set(self, i, value)

        self._notSync=True


        return val


    def empty(self) -> "bool":
        r"""
        empty(Potential self) -> bool

        Returns
        -------
        bool
            Returns true if no variable is in the potential. 

        """
        return _pyAgrum.Potential_empty(self)

    def pos(self, v: 'DiscreteVariable') -> "gum::Idx":
        r"""
        pos(Potential self, DiscreteVariable v) -> gum::Idx

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable for which the index is returned.

        Returns
        -------
            Returns the index of a variable. 

        Raises
        ------
        gum.NotFound 
          If v is not in this multidimensional matrix. 

        """
        return _pyAgrum.Potential_pos(self, v)

    def contains(self, v: 'DiscreteVariable') -> "bool":
        r"""
        contains(Potential self, DiscreteVariable v) -> bool

        Parameters
        ----------
        v : pyAgrum.Potential
            a DiscreteVariable.

        Returns
        -------
        bool
            True if the var is in the potential

        """
        return _pyAgrum.Potential_contains(self, v)

    def nbrDim(self) -> "gum::Idx":
        r"""
        nbrDim(Potential self) -> gum::Idx

        Returns
        -------
        int
          the number of vars in the multidimensional container. 

        """
        return _pyAgrum.Potential_nbrDim(self)

    def variable(self, *args) -> "gum::DiscreteVariable const &":
        r"""
        variable(Potential self, gum::Idx i) -> DiscreteVariable
        variable(Potential self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        i : int 
          An index of this multidimensional matrix.

        Returns
        -------
          the varible at the ith index 

        Raises
        ------
        gum.NotFound
          If i does not reference a variable in this multidimensional matrix. 

        """
        return _pyAgrum.Potential_variable(self, *args)

    def remove(self, var: 'DiscreteVariable') -> "void":
        r"""
        remove(Potential self, DiscreteVariable var)

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
            The variable to be removed

        Returns
        -------
        pyAgrum.Potential
          a reference to the modified potential

        Warnings
        --------
        IndexError raised if the var is not in the potential 

        """
        val = _pyAgrum.Potential_remove(self, var)

        self._list_vars.remove(var)
        self._notSync=True


        return val


    def add(self, v: 'DiscreteVariable') -> "void":
        r"""
        add(Potential self, DiscreteVariable v)

        Add a discrete variable to the potential.

        Parameters
        ----------
        v : pyAgrum.DiscreteVariable
          the var to be added

        Raises
        ------
        DuplicateElement
          If the variable is already in this Potential.
        InvalidArgument
          If the variable is empty.

        """
        val = _pyAgrum.Potential_add(self, v)

        self._list_vars.append(v)
        self._notSync=True
        return self


        return val


# Register Potential in _pyAgrum:
_pyAgrum.Potential_swigregister(Potential)

class IBayesNet(DAGmodel):
    r"""



    Abstract class used by BayesNet.

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __swig_destroy__ = _pyAgrum.delete_IBayesNet

    def cpt(self, varId: 'gum::NodeId') -> "gum::Potential< double > const &":
        r"""
        cpt(IBayesNet self, gum::NodeId varId) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.IBayesNet.
        name : str
        	A variable's name in the pyAgrum.IBayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound 
        	If no variable's id matches varId. 

        """
        return _pyAgrum.IBayesNet_cpt(self, varId)

    def variableNodeMap(self) -> "gum::VariableNodeMap const &":
        r"""
        variableNodeMap(IBayesNet self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.IBayesNet_variableNodeMap(self)

    def variable(self, id: 'gum::NodeId') -> "gum::DiscreteVariable const &":
        r"""
        variable(IBayesNet self, gum::NodeId id) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_variable(self, id)

    def nodeId(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        nodeId(IBayesNet self, DiscreteVariable var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_nodeId(self, var)

    def idFromName(self, name: 'std::string const &') -> "gum::NodeId":
        r"""
        idFromName(IBayesNet self, std::string const & name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.IBayesNet_idFromName(self, name)

    def variableFromName(self, name: 'std::string const &') -> "gum::DiscreteVariable const &":
        r"""
        variableFromName(IBayesNet self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.IBayesNet_variableFromName(self, name)

    def jointProbability(self, i: 'Instantiation') -> "double":
        r"""
        jointProbability(IBayesNet self, Instantiation i) -> double

        Parameters
        ----------
        i : pyAgrum.instantiation
        	an instantiation of the variables

        Returns
        -------
        double
        	a parameter of the joint probability for the BayesNet

        Warnings
        --------
        a variable not present in the instantiation is assumed to be instantiated to 0

        """
        return _pyAgrum.IBayesNet_jointProbability(self, i)

    def log2JointProbability(self, i: 'Instantiation') -> "double":
        r"""
        log2JointProbability(IBayesNet self, Instantiation i) -> double

        Parameters
        ----------
        i : pyAgrum.instantiation
        	an instantiation of the variables

        Returns
        -------
        double
        	a parameter of the log joint probability for the BayesNet

        Warnings
        --------
        a variable not present in the instantiation is assumed to be instantiated to 0

        """
        return _pyAgrum.IBayesNet_log2JointProbability(self, i)

    def __eq__(self, _from: 'IBayesNet') -> "bool":
        r"""__eq__(IBayesNet self, IBayesNet _from) -> bool"""
        return _pyAgrum.IBayesNet___eq__(self, _from)

    def __ne__(self, _from: 'IBayesNet') -> "bool":
        r"""__ne__(IBayesNet self, IBayesNet _from) -> bool"""
        return _pyAgrum.IBayesNet___ne__(self, _from)

    def dim(self) -> "gum::Size":
        r"""
        dim(IBayesNet self) -> gum::Size

        Returns the dimension (the number of free parameters) in this BayesNet.

        Returns
        -------
        int
        	the dimension of the BayesNet

        """
        return _pyAgrum.IBayesNet_dim(self)

    def maxVarDomainSize(self) -> "gum::Size":
        r"""
        maxVarDomainSize(IBayesNet self) -> gum::Size

        Returns
        -------
        int
        	the biggest domain size among the variables of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxVarDomainSize(self)

    def minParam(self) -> "double":
        r"""
        minParam(IBayesNet self) -> double

        Returns
        -------
        double
            the smallest value in the CPTs of the IBayesNet

        """
        return _pyAgrum.IBayesNet_minParam(self)

    def maxParam(self) -> "double":
        r"""
        maxParam(IBayesNet self) -> double

        Returns
        -------
        double
            the biggest value in the CPTs of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxParam(self)

    def minNonZeroParam(self) -> "double":
        r"""
        minNonZeroParam(IBayesNet self) -> double

        Returns
        -------
        double
            the smallest value (not equal to 0) in the CPTs of the IBayesNet

        """
        return _pyAgrum.IBayesNet_minNonZeroParam(self)

    def maxNonOneParam(self) -> "double":
        r"""
        maxNonOneParam(IBayesNet self) -> double

        Returns
        -------
        double
        	The biggest value (not equal to 1) in the CPTs of the BayesNet

        """
        return _pyAgrum.IBayesNet_maxNonOneParam(self)

    def toDot(self) -> "std::string":
        r"""
        toDot(IBayesNet self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.IBayesNet_toDot(self)

    def nodes(self) -> "PyObject *":
        r"""
        nodes(IBayesNet self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.IBayesNet_nodes(self)

    def names(self) -> "PyObject *":
        r"""
        names(IBayesNet self) -> PyObject *

        Returns
        -------
        list
        	The names of the graph variables

        """
        return _pyAgrum.IBayesNet_names(self)

    def minimalCondSet(self, *args) -> "PyObject *":
        r"""
        minimalCondSet(IBayesNet self, gum::NodeId target, gum::NodeSet const & soids) -> gum::NodeSet
        minimalCondSet(IBayesNet self, gum::NodeSet const & targets, gum::NodeSet const & soids) -> gum::NodeSet
        minimalCondSet(IBayesNet self, gum::NodeId target, PyObject * list) -> PyObject
        minimalCondSet(IBayesNet self, PyObject * targets, PyObject * list) -> PyObject *

        Returns, given one or many targets and a list of variables, the minimal set of those needed to calculate the target/targets.

        Parameters
        ----------
        target : int
        	The id of the target
        targets : list
        	The ids of the targets
        list : list
        	The list of available variables

        Returns
        -------
        Set
        	The minimal set of variables

        """
        return _pyAgrum.IBayesNet_minimalCondSet(self, *args)

    def __repr__(self) -> "std::string":
        r"""__repr__(IBayesNet self) -> std::string"""
        return _pyAgrum.IBayesNet___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(IBayesNet self) -> std::string"""
        return _pyAgrum.IBayesNet___str__(self)

    def arcs(self) -> "PyObject *":
        r"""
        arcs(IBayesNet self) -> PyObject *

        Returns
        -------
        list
        	The lisf of arcs in the IBayesNet

        """
        return _pyAgrum.IBayesNet_arcs(self)

    def parents(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        parents(IBayesNet self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        Set
            the set of the parents ids.

        """
        return _pyAgrum.IBayesNet_parents(self, id)

    def children(self, id: 'gum::NodeId') -> "PyObject *":
        r"""
        children(IBayesNet self, gum::NodeId id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.IBayesNet_children(self, id)

# Register IBayesNet in _pyAgrum:
_pyAgrum.IBayesNet_swigregister(IBayesNet)

class BayesNet(IBayesNet):
    r"""



    BayesNet represents a Bayesian Network.

    Available constructors:
    	``BayesNet(name='') -> BayesNet``

    	``BayesNet(source) -> BayesNet``


    Parameters
    ----------
    name: str
    	the name of the Bayes Net (optional)
    source : pyAgrum.BayesNet
    	the Bayesian network to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    @staticmethod
    def fastPrototype(dotlike: 'std::string const &', domainSize: 'gum::Size'=2) -> "gum::BayesNet< double >":
        r"""
        fastPrototype(std::string const & dotlike, gum::Size domainSize=2) -> BayesNet

        Create a bn with a dotlike syntax : 'a->b->c;b->d;'.

        The domain size maybe specified using 'a[10]'.

        Note that if the dotlike string contains such a specification for an already defined variable, the first specification will be used.

        Parameters
        ----------
        dotlike : str
        	the string containing the specification
        domainSize : int
        	the default domain size for variables

        Returns
        -------
        pyAgrum.BayesNet
        	the resulting bayesian network 

        """
        return _pyAgrum.BayesNet_fastPrototype(dotlike, domainSize)
    __swig_destroy__ = _pyAgrum.delete_BayesNet

    def __init__(self, *args):
        r"""
        __init__(BayesNet self) -> BayesNet
        __init__(BayesNet self, std::string name) -> BayesNet
        __init__(BayesNet self, BayesNet source) -> BayesNet
        """
        _pyAgrum.BayesNet_swiginit(self, _pyAgrum.new_BayesNet(*args))

    def cpt(self, *args) -> "gum::Potential< double > const &":
        r"""
        cpt(BayesNet self, gum::NodeId varId) -> Potential
        cpt(BayesNet self, std::string const & name) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.BayesNet.
        name : str
        	A variable's name in the pyAgrum.BayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound
            If no variable's id matches varId.

        """
        val = _pyAgrum.BayesNet_cpt(self, *args)

        val.__fill_distrib__()


        return val


    def variableNodeMap(self) -> "gum::VariableNodeMap const &":
        r"""
        variableNodeMap(BayesNet self) -> VariableNodeMap

        Returns
        -------
        pyAgrum.variableNodeMap
        	the variable node map

        """
        return _pyAgrum.BayesNet_variableNodeMap(self)

    def add(self, *args) -> "gum::NodeId":
        r"""
        add(BayesNet self, DiscreteVariable var) -> gum::NodeId
        add(BayesNet self, std::string const & name, unsigned int nbrmod) -> gum::NodeId
        add(BayesNet self, DiscreteVariable var, gum::MultiDimImplementation< double > * aContent) -> gum::NodeId
        add(BayesNet self, DiscreteVariable var, gum::NodeId id) -> gum::NodeId
        add(BayesNet self, DiscreteVariable var, gum::MultiDimImplementation< double > * aContent, gum::NodeId id) -> gum::NodeId

        Add a variable to the pyAgrum.BayesNet. 

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added
        name : str 
        	the variable name
        nbrmod : int
        	the numbre of modalities for the new variable
        id : int
        	the variable forced id in the pyAgrum.BayesNet

        Returns
        -------
        int 
        	the id of the new node

        Raises
        ------
        gum.DuplicateLabel
            If variable.name() is already used in this pyAgrum.BayesNet.
        gum.NotAllowed
            If nbrmod<2
        gum.DuplicateElement
            If id is already used.

        """
        return _pyAgrum.BayesNet_add(self, *args)

    def erase(self, *args) -> "void":
        r"""
        erase(BayesNet self, gum::NodeId varId)
        erase(BayesNet self, std::string const & name)
        erase(BayesNet self, DiscreteVariable var)

        Remove a variable from the gum::BayesNet.

        Removes the corresponding variable from the gum::BayesNet and from all of it's children gum::Potential.

        If no variable matches the given id, then nothing is done.

        Parameters
        ----------
        id : int
        	The variable's id to remove. 
        name : str
        	The variable's name to remove.
        var : pyAgrum.DiscreteVariable
        	A reference on the variable to remove. 

        """
        return _pyAgrum.BayesNet_erase(self, *args)

    def variable(self, *args) -> "gum::DiscreteVariable const &":
        r"""
        variable(BayesNet self, gum::NodeId id) -> DiscreteVariable
        variable(BayesNet self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        id : int
        	a variable's id
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_variable(self, *args)

    def changeVariableName(self, *args) -> "void":
        r"""
        changeVariableName(BayesNet self, gum::NodeId id, std::string const & new_name)
        changeVariableName(BayesNet self, std::string const & name, std::string const & new_name)

        Changes a variable's name in the gum::BayesNet.

        This will change the gum::DiscreteVariable names in the gum::BayesNet.

        Parameters
        ----------
        new_name : str
        	the new name of the variable
        NodeId : int
        	the id of the node
        name : str
        	the name of the variable

        Raises
        ------
        gum.DuplicateLabel
            If new_name is already used in this BayesNet.
        gum.NotFound
            If no variable matches id.

        """
        return _pyAgrum.BayesNet_changeVariableName(self, *args)

    def changeVariableLabel(self, *args) -> "void":
        r"""
        changeVariableLabel(BayesNet self, gum::NodeId id, std::string const & old_label, std::string const & new_label)
        changeVariableLabel(BayesNet self, std::string const & name, std::string const & old_label, std::string const & new_label)

        change the label of the variable associated to nodeId to the new value.

        Parameters
        ----------
        id : int
        	the id of the node
        name : str
        	the name of the variable
        old_label : str
        	the new label
        new_label : str
        	the new label

        Raises
        ------
        gum.NotFound
            if id/name is not a variable or if old_label does not exist.

        """
        return _pyAgrum.BayesNet_changeVariableLabel(self, *args)

    def nodeId(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        nodeId(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_nodeId(self, var)

    def idFromName(self, name: 'std::string const &') -> "gum::NodeId":
        r"""
        idFromName(BayesNet self, std::string const & name) -> gum::NodeId

        Returns a variable's id given its name in the graph.

        Parameters
        ----------
        name : str
        	The variable's name from which the id is returned.

        Returns
        -------
        int :
        	The variable's node id.

        Raises
        ------
        gum.NotFound
        	If name does not match a variable in the graph

        """
        return _pyAgrum.BayesNet_idFromName(self, name)

    def variableFromName(self, name: 'std::string const &') -> "gum::DiscreteVariable const &":
        r"""
        variableFromName(BayesNet self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the graph does not contain the variable

        """
        return _pyAgrum.BayesNet_variableFromName(self, name)

    def addArc(self, *args) -> "void":
        r"""
        addArc(BayesNet self, gum::NodeId tail, gum::NodeId head)
        addArc(BayesNet self, std::string const & tail, std::string const & head)

        Add an arc in the BN, and update arc.head's CPT.

        Parameters
        ----------
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        Raises
        ------
        gum.InvalidEdge
            If arc.tail and/or arc.head are not in the BN.

        """
        return _pyAgrum.BayesNet_addArc(self, *args)

    def eraseArc(self, *args) -> "void":
        r"""
        eraseArc(BayesNet self, Arc arc)
        eraseArc(BayesNet self, gum::NodeId tail, gum::NodeId head)
        eraseArc(BayesNet self, std::string const & tail, std::string const & head)

        Removes an arc in the BN, and update head's CTP.

        If (tail, head) doesn't exist, the nothing happens.

        Parameters
        ----------
        arc : pyAgrum.Arc 
        	The arc to be removed.
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BayesNet_eraseArc(self, *args)

    def beginTopologyTransformation(self) -> "void":
        r"""
        beginTopologyTransformation(BayesNet self)

        When inserting/removing arcs, node CPTs change their dimension with a cost in time.
        begin Multiple Change for all CPTs
        These functions delay the CPTs change to be done just once at the end of a sequence of topology modification, begins a sequence of insertions/deletions of arcs without changing the dimensions of the CPTs.

        """
        return _pyAgrum.BayesNet_beginTopologyTransformation(self)

    def endTopologyTransformation(self) -> "void":
        r"""
        endTopologyTransformation(BayesNet self)

        Terminates a sequence of insertions/deletions of arcs by adjusting all CPTs dimensions.
        End Multiple Change for all CPTs.

        Returns
        -------
        pyAgrum.BayesNet

        """
        return _pyAgrum.BayesNet_endTopologyTransformation(self)

    def reverseArc(self, *args) -> "void":
        r"""
        reverseArc(BayesNet self, gum::NodeId tail, gum::NodeId head)
        reverseArc(BayesNet self, std::string const & tail, std::string const & head)
        reverseArc(BayesNet self, Arc arc)

        Reverses an arc while preserving the same joint distribution. 

        Parameters
        ----------
        tail
        	(int) the id of the tail variable
        head
        	(int) the id of the head variable
        tail
        	(str) the name of the tail variable
        head
        	(str) the name of the head variable
        arc : pyAgrum.Arc
        	an arc 

        Raises
        ------
        gum.InvalidArc
            If the arc does not exsit or if its reversal would induce a directed cycle.

        """
        return _pyAgrum.BayesNet_reverseArc(self, *args)

    def addNoisyOR(self, *args) -> "gum::NodeId":
        r"""
        addNoisyOR(BayesNet self, DiscreteVariable var, double external_weight) -> gum::NodeId
        addNoisyOR(BayesNet self, DiscreteVariable var, double external_weight, gum::NodeId id) -> gum::NodeId

        Add a variable, it's associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable. 

        Raises
        --------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyOR(self, *args)

    def addNoisyORNet(self, *args) -> "gum::NodeId":
        r"""
        addNoisyORNet(BayesNet self, DiscreteVariable var, double external_weight) -> gum::NodeId
        addNoisyORNet(BayesNet self, DiscreteVariable var, double external_weight, gum::NodeId id) -> gum::NodeId

        Add a variable, its associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        """
        return _pyAgrum.BayesNet_addNoisyORNet(self, *args)

    def addNoisyORCompound(self, *args) -> "gum::NodeId":
        r"""
        addNoisyORCompound(BayesNet self, DiscreteVariable var, double external_weight) -> gum::NodeId
        addNoisyORCompound(BayesNet self, DiscreteVariable var, double external_weight, gum::NodeId id) -> gum::NodeId

        Add a variable, it's associate node and a noisyOR implementation.

        Since it seems that the 'classical' noisyOR is the Compound noisyOR, we keep the addNoisyOR as an alias for addNoisyORCompound.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        --------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyORCompound(self, *args)

    def addNoisyAND(self, *args) -> "gum::NodeId":
        r"""
        addNoisyAND(BayesNet self, DiscreteVariable var, double external_weight, gum::NodeId id) -> gum::NodeId
        addNoisyAND(BayesNet self, DiscreteVariable var, double external_weight) -> gum::NodeId

        Add a variable, its associate node and a noisyAND implementation.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addNoisyAND(self, *args)

    def addLogit(self, *args) -> "gum::NodeId":
        r"""
        addLogit(BayesNet self, DiscreteVariable var, double external_weight, gum::NodeId id) -> gum::NodeId
        addLogit(BayesNet self, DiscreteVariable var, double external_weight) -> gum::NodeId

        Add a variable, its associate node and a Logit implementation.

        (The id of the new variable can be automatically generated.)

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy
        externalWeight : double
        	the added external weight
        id : int
        	The proposed id for the variable.
        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.DuplicateElement
            If id is already used

        """
        return _pyAgrum.BayesNet_addLogit(self, *args)

    def addOR(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addOR(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Add a variable, it's associate node and an OR implementation.

        The id of the new variable is automatically generated.

        Warnings
        --------
        	If parents are not boolean, all value>1 is True

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy

        Returns
        -------
        int
        	the id of the added variable.

        Raises
        ------
        gum.SizeError
            If variable.domainSize()>2

        """
        return _pyAgrum.BayesNet_addOR(self, var)

    def addAND(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addAND(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Add a variable, it's associate node and an AND implementation.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy.

        Returns
        -------
        int
        	the id of the added variable. 

        Raises
        ------
        gum.SizeError
            If variable.domainSize()>2

        """
        return _pyAgrum.BayesNet_addAND(self, var)

    def addAMPLITUDE(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addAMPLITUDE(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addAMPLITUDE(self, var)

    def addCOUNT(self, var: 'DiscreteVariable', value: 'gum::Idx'=1) -> "gum::NodeId":
        r"""
        addCOUNT(BayesNet self, DiscreteVariable var, gum::Idx value=1) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addCOUNT(self, var, value)

    def addEXISTS(self, var: 'DiscreteVariable', value: 'gum::Idx'=1) -> "gum::NodeId":
        r"""
        addEXISTS(BayesNet self, DiscreteVariable var, gum::Idx value=1) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addEXISTS(self, var, value)

    def addFORALL(self, var: 'DiscreteVariable', value: 'gum::Idx'=1) -> "gum::NodeId":
        r"""
        addFORALL(BayesNet self, DiscreteVariable var, gum::Idx value=1) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added variable.

        """
        return _pyAgrum.BayesNet_addFORALL(self, var, value)

    def addMAX(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addMAX(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMAX(self, var)

    def addMEDIAN(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addMEDIAN(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMEDIAN(self, var)

    def addMIN(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        addMIN(BayesNet self, DiscreteVariable var) -> gum::NodeId

        Others aggregators

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable to be added

        Returns
        -------
        int
        	the id of the added value

        """
        return _pyAgrum.BayesNet_addMIN(self, var)

    def addWeightedArc(self, *args) -> "void":
        r"""
        addWeightedArc(BayesNet self, gum::NodeId tail, gum::NodeId head, double causalWeight)
        addWeightedArc(BayesNet self, std::string const & tail, std::string const & head, double causalWeight)

        Add an arc in the BN, and update arc.head's CPT.

        Parameters
        ----------
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)
        causalWeight : double
        	the added causal weight

        Raises
        ------
        gum.InvalidArc
            If arc.tail and/or arc.head are not in the BN.
        gum.InvalidArc
            If variable in arc.head is not a NoisyOR variable.

        """
        return _pyAgrum.BayesNet_addWeightedArc(self, *args)

    def generateCPTs(self) -> "void":
        r"""
        generateCPTs(BayesNet self)

        Randomly generates CPTs for a given structure.

        """
        return _pyAgrum.BayesNet_generateCPTs(self)

    def generateCPT(self, *args) -> "void":
        r"""
        generateCPT(BayesNet self, gum::NodeId node)
        generateCPT(BayesNet self, std::string const & name)

        Randomly generate CPT for a given node in a given structure.

        Parameters
        ----------
        node : int
        	The variable's id.
        name : str 
        	The variable's name.

        """
        return _pyAgrum.BayesNet_generateCPT(self, *args)

    def changePotential(self, *args) -> "void":
        r"""
        changePotential(BayesNet self, gum::NodeId id, Potential newPot)
        changePotential(BayesNet self, std::string const & name, Potential newPot)

        change the CPT associated to nodeId to newPot delete the old CPT associated to nodeId.

        Parameters
        ----------
        newPot : pyAgrum.Potential
        	the new potential
        NodeId : int
        	the id of the node
        name : str
        	the name of the variable

        Raises
        ------
        gum.NotAllowed
            If newPot has not the same signature as __probaMap[NodeId]

        """
        return _pyAgrum.BayesNet_changePotential(self, *args)

    def dag(self) -> "gum::DAG const &":
        r"""
        dag(BayesNet self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	a constant reference to the dag of this BayesNet.

        """
        val = _pyAgrum.BayesNet_dag(self)

        val = DAG(val) # copying the DAG


        return val


    def size(self) -> "gum::Size":
        r"""
        size(BayesNet self) -> gum::Size

        Returns
        -------
        int
            the number of nodes in the graph

        """
        return _pyAgrum.BayesNet_size(self)

    def nodes(self) -> "PyObject *":
        r"""
        nodes(BayesNet self) -> PyObject *

        Returns
        -------
        set
            the set of ids

        """
        return _pyAgrum.BayesNet_nodes(self)

    def log10DomainSize(self) -> "double":
        r"""
        log10DomainSize(BayesNet self) -> double

        Returns
        -------
        double
        	The log10 domain size of the joint probability for the model.

        """
        return _pyAgrum.BayesNet_log10DomainSize(self)

    def addStructureListener(self,whenNodeAdded=None,whenNodeDeleted=None,whenArcAdded=None,whenArcDeleted=None):
        """
        Add the listeners in parameters to the list of existing ones.

        Parameters
        ----------
        whenNodeAdded : lambda expression
          a function for when a node is added
        whenNodeDeleted : lambda expression
          a function for when a node is removed
        whenArcAdded : lambda expression
          a function for when an arc is added
        whenArcDeleted : lambda expression
          a function for when an arc is removed
        """
        if [whenNodeAdded,whenNodeDeleted,whenArcAdded,whenArcDeleted]==[None,None,None,None]:
          return

        if not hasattr(self,"_listeners"):
          self._listeners=[]

        nl = PythonBNListener(self, self.variableNodeMap())
        if whenNodeAdded is not None:
          nl.setWhenNodeAdded(whenNodeAdded)
        if whenNodeDeleted is not None:
          nl.setWhenNodeDeleted(whenNodeDeleted)
        if whenArcAdded is not None:
          nl.setWhenArcAdded(whenArcAdded)
        if whenArcDeleted is not None:
          nl.setWhenArcDeleted(whenArcDeleted)

        self._listeners.append(nl)


    def loadBIF(self, *args) -> "std::string":
        r"""
        loadBIF(BayesNet self, std::string name, PyObject * l=(PyObject *) 0) -> std::string

        Load a BIF file.

        Parameters
        ----------
        name : str
        	the file's name
        l : list
        	list of functions to execute

        Raises
        --------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadBIF(self, *args)

    def saveBIF(self, name: 'std::string') -> "void":
        r"""
        saveBIF(BayesNet self, std::string name)

        Save the BayesNet in a BIF file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveBIF(self, name)

    def loadDSL(self, *args) -> "std::string":
        r"""
        loadDSL(BayesNet self, std::string name, PyObject * l=(PyObject *) 0) -> std::string

        Load a DSL file.

        Parameters
        ----------
        name : str
        	the file's name
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadDSL(self, *args)

    def saveDSL(self, name: 'std::string') -> "void":
        r"""
        saveDSL(BayesNet self, std::string name)

        Save the BayesNet in a DSL file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveDSL(self, name)

    def loadNET(self, *args) -> "std::string":
        r"""
        loadNET(BayesNet self, std::string name, PyObject * l=(PyObject *) 0) -> std::string

        Load a NET file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadNET(self, *args)

    def saveNET(self, name: 'std::string') -> "void":
        r"""
        saveNET(BayesNet self, std::string name)

        Save the BayesNet in a NET file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveNET(self, name)

    def loadO3PRM(self, *args) -> "std::string":
        r"""
        loadO3PRM(BayesNet self, std::string name, std::string system="", std::string classpath="", PyObject * l=(PyObject *) 0) -> std::string

        Load an O3PRM file.

        Warnings
        --------
        The O3PRM language is the only language allowing to manipulate not only DiscretizedVariable but also RangeVariable and LabelizedVariable.

        Parameters
        ----------
        name : str
        	the file's name
        system : str
        	the system's name
        classpath : str
        	the classpath
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadO3PRM(self, *args)

    def saveO3PRM(self, name: 'std::string') -> "void":
        r"""
        saveO3PRM(BayesNet self, std::string name)

        Save the BayesNet in an O3PRM file.

        Warnings
        --------
        The O3PRM language is the only language allowing to manipulate not only DiscretizedVariable but also RangeVariable and LabelizedVariable.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveO3PRM(self, name)

    def loadBIFXML(self, *args) -> "std::string":
        r"""
        loadBIFXML(BayesNet self, std::string name, PyObject * l=(PyObject *) 0) -> std::string

        Load a BIFXML file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadBIFXML(self, *args)

    def saveBIFXML(self, name: 'std::string') -> "void":
        r"""
        saveBIFXML(BayesNet self, std::string name)

        Save the BayesNet in a BIFXML file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveBIFXML(self, name)

    def loadUAI(self, *args) -> "std::string":
        r"""
        loadUAI(BayesNet self, std::string name, PyObject * l=(PyObject *) 0) -> std::string

        Load an UAI file.

        Parameters
        ----------
        name : str
        	the name's file
        l : list
        	list of functions to execute

        Raises
        ------
        gum.IOError
            If file not found
        gum.FatalError
            If file is not valid

        """
        return _pyAgrum.BayesNet_loadUAI(self, *args)

    def saveUAI(self, name: 'std::string') -> "void":
        r"""
        saveUAI(BayesNet self, std::string name)

        Save the BayesNet in an UAI file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.BayesNet_saveUAI(self, name)

    def __repr__(self) -> "std::string":
        r"""__repr__(BayesNet self) -> std::string"""
        return _pyAgrum.BayesNet___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(BayesNet self) -> std::string"""
        return _pyAgrum.BayesNet___str__(self)

# Register BayesNet in _pyAgrum:
_pyAgrum.BayesNet_swigregister(BayesNet)

def BayesNet_fastPrototype(dotlike: 'std::string const &', domainSize: 'gum::Size'=2) -> "gum::BayesNet< double >":
    r"""
    BayesNet_fastPrototype(std::string const & dotlike, gum::Size domainSize=2) -> BayesNet

    Create a bn with a dotlike syntax : 'a->b->c;b->d;'.

    The domain size maybe specified using 'a[10]'.

    Note that if the dotlike string contains such a specification for an already defined variable, the first specification will be used.

    Parameters
    ----------
    dotlike : str
    	the string containing the specification
    domainSize : int
    	the default domain size for variables

    Returns
    -------
    pyAgrum.BayesNet
    	the resulting bayesian network 

    """
    return _pyAgrum.BayesNet_fastPrototype(dotlike, domainSize)

class BayesNetInference(object):
    r"""
    Proxy of C++ gum::BayesNetInference< double > class.
    Proxy of C++ gum::BayesNetInference< double > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined - class is abstract")
    __repr__ = _swig_repr
    StateOfInference_OutdatedBNStructure = _pyAgrum.BayesNetInference_StateOfInference_OutdatedBNStructure
    
    StateOfInference_OutdatedBNPotentials = _pyAgrum.BayesNetInference_StateOfInference_OutdatedBNPotentials
    
    StateOfInference_ReadyForInference = _pyAgrum.BayesNetInference_StateOfInference_ReadyForInference
    
    StateOfInference_Done = _pyAgrum.BayesNetInference_StateOfInference_Done
    
    __swig_destroy__ = _pyAgrum.delete_BayesNetInference

    def setBN(self, bn: 'IBayesNet') -> "void":
        r"""setBN(BayesNetInference self, IBayesNet bn)"""
        return _pyAgrum.BayesNetInference_setBN(self, bn)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""BN(BayesNetInference self) -> IBayesNet"""
        return _pyAgrum.BayesNetInference_BN(self)

    def domainSizes(self) -> "gum::NodeProperty< gum::Size > const &":
        r"""domainSizes(BayesNetInference self) -> gum::NodeProperty< gum::Size > const &"""
        return _pyAgrum.BayesNetInference_domainSizes(self)

    def isInferenceReady(self) -> "bool":
        r"""isInferenceReady(BayesNetInference self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceReady(self)

    def isInferenceOutdatedBNStructure(self) -> "bool":
        r"""isInferenceOutdatedBNStructure(BayesNetInference self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceOutdatedBNStructure(self)

    def isInferenceOutdatedBNPotentials(self) -> "bool":
        r"""isInferenceOutdatedBNPotentials(BayesNetInference self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceOutdatedBNPotentials(self)

    def isInferenceDone(self) -> "bool":
        r"""isInferenceDone(BayesNetInference self) -> bool"""
        return _pyAgrum.BayesNetInference_isInferenceDone(self)

    def isDone(self) -> "bool":
        r"""isDone(BayesNetInference self) -> bool"""
        return _pyAgrum.BayesNetInference_isDone(self)

    def prepareInference(self) -> "void":
        r"""prepareInference(BayesNetInference self)"""
        return _pyAgrum.BayesNetInference_prepareInference(self)

    def makeInference(self) -> "void":
        r"""makeInference(BayesNetInference self)"""
        return _pyAgrum.BayesNetInference_makeInference(self)

    def clear(self) -> "void":
        r"""clear(BayesNetInference self)"""
        return _pyAgrum.BayesNetInference_clear(self)

    def state(self) -> "gum::BayesNetInference< double >::StateOfInference":
        r"""state(BayesNetInference self) -> gum::BayesNetInference< double >::StateOfInference"""
        return _pyAgrum.BayesNetInference_state(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(BayesNetInference self, gum::NodeId id, gum::Idx const val)
        addEvidence(BayesNetInference self, std::string const & nodeName, gum::Idx const val)
        addEvidence(BayesNetInference self, gum::NodeId id, std::string const & label)
        addEvidence(BayesNetInference self, std::string const & nodeName, std::string const & label)
        addEvidence(BayesNetInference self, gum::NodeId id, Vector vals)
        addEvidence(BayesNetInference self, std::string const & nodeName, Vector vals)
        addEvidence(BayesNetInference self, Potential pot)
        addEvidence(BayesNetInference self, Potential pot)
        """
        return _pyAgrum.BayesNetInference_addEvidence(self, *args)

    def addSetOfEvidence(self, potset: 'gum::Set< gum::Potential< double > const * > const &') -> "void":
        r"""addSetOfEvidence(BayesNetInference self, gum::Set< gum::Potential< double > const * > const & potset)"""
        return _pyAgrum.BayesNetInference_addSetOfEvidence(self, potset)

    def addListOfEvidence(self, potlist: 'gum::List< gum::Potential< double > const * > const &') -> "void":
        r"""addListOfEvidence(BayesNetInference self, gum::List< gum::Potential< double > const * > const & potlist)"""
        return _pyAgrum.BayesNetInference_addListOfEvidence(self, potlist)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(BayesNetInference self, gum::NodeId id, gum::Idx const val)
        chgEvidence(BayesNetInference self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(BayesNetInference self, gum::NodeId id, std::string const & label)
        chgEvidence(BayesNetInference self, std::string const & nodeName, std::string const & label)
        chgEvidence(BayesNetInference self, gum::NodeId id, Vector vals)
        chgEvidence(BayesNetInference self, std::string const & nodeName, Vector vals)
        chgEvidence(BayesNetInference self, Potential pot)
        """
        return _pyAgrum.BayesNetInference_chgEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""eraseAllEvidence(BayesNetInference self)"""
        return _pyAgrum.BayesNetInference_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(BayesNetInference self, gum::NodeId id)
        eraseEvidence(BayesNetInference self, std::string const & nodeName)
        """
        return _pyAgrum.BayesNetInference_eraseEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(BayesNetInference self) -> bool
        hasEvidence(BayesNetInference self, gum::NodeId id) -> bool
        hasEvidence(BayesNetInference self, std::string const & nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasEvidence(self, *args)

    def hasHardEvidence(self, *args) -> "bool":
        r"""
        hasHardEvidence(BayesNetInference self, gum::NodeId id) -> bool
        hasHardEvidence(BayesNetInference self, std::string const & nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasHardEvidence(self, *args)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(BayesNetInference self, gum::NodeId id) -> bool
        hasSoftEvidence(BayesNetInference self, std::string const & nodeName) -> bool
        """
        return _pyAgrum.BayesNetInference_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""nbrEvidence(BayesNetInference self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""nbrHardEvidence(BayesNetInference self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""nbrSoftEvidence(BayesNetInference self) -> gum::Size"""
        return _pyAgrum.BayesNetInference_nbrSoftEvidence(self)

    def evidence(self) -> "gum::NodeProperty< gum::Potential< double > const * > const &":
        r"""evidence(BayesNetInference self) -> gum::NodeProperty< gum::Potential< double > const * > const &"""
        return _pyAgrum.BayesNetInference_evidence(self)

    def softEvidenceNodes(self) -> "gum::NodeSet const &":
        r"""softEvidenceNodes(BayesNetInference self) -> gum::NodeSet const &"""
        return _pyAgrum.BayesNetInference_softEvidenceNodes(self)

    def hardEvidenceNodes(self) -> "gum::NodeSet const &":
        r"""hardEvidenceNodes(BayesNetInference self) -> gum::NodeSet const &"""
        return _pyAgrum.BayesNetInference_hardEvidenceNodes(self)

    def hardEvidence(self) -> "gum::NodeProperty< gum::Idx > const &":
        r"""hardEvidence(BayesNetInference self) -> gum::NodeProperty< gum::Idx > const &"""
        return _pyAgrum.BayesNetInference_hardEvidence(self)

# Register BayesNetInference in _pyAgrum:
_pyAgrum.BayesNetInference_swigregister(BayesNetInference)

class LazyPropagation(object):
    r"""



    Class used for Lazy Propagation

    Available constructors:
    	``LazyPropagation(bn) -> LazyPropagation``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""__init__(LazyPropagation self, IBayesNet BN, gum::RelevantPotentialsFinderType arg3=DSEP_BAYESBALL_POTENTIALS, gum::FindBarrenNodesType arg4=FIND_BARREN_NODES, bool use_binary_join_tree=True) -> LazyPropagation"""
        _pyAgrum.LazyPropagation_swiginit(self, _pyAgrum.new_LazyPropagation(*args))

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_LazyPropagation

    def setTriangulation(self, new_triangulation: 'Triangulation') -> "void":
        r"""setTriangulation(LazyPropagation self, Triangulation new_triangulation)"""
        return _pyAgrum.LazyPropagation_setTriangulation(self, new_triangulation)

    def setRelevantPotentialsFinderType(self, type: 'gum::RelevantPotentialsFinderType') -> "void":
        r"""
        setRelevantPotentialsFinderType(LazyPropagation self, gum::RelevantPotentialsFinderType type)

        sets how we determine the relevant potentials to combine

        When a clique sends a message to a separator, it first constitute the set of the potentials it contains and of the potentials contained in the messages it received. If RelevantPotentialsFinderType = FIND_ALL, all these potentials are combined and projected to produce the message sent to the separator. If RelevantPotentialsFinderType = DSEP_BAYESBALL_NODES, then only the set of potentials d-connected to the variables of the separator are kept for combination and projection.

        0 = FIND_ALL
        1 = DSEP_BAYESBALL_NODES
        2 = DSEP_BAYESBALL_POTENTIALS
        3 = DSEP_KOLLER_FRIEDMAN_2009

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.LazyPropagation_setRelevantPotentialsFinderType(self, type)

    def setFindBarrenNodesType(self, type: 'gum::FindBarrenNodesType') -> "void":
        r"""
        setFindBarrenNodesType(LazyPropagation self, gum::FindBarrenNodesType type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.LazyPropagation_setFindBarrenNodesType(self, type)

    def joinTree(self) -> "gum::JoinTree const *":
        r"""
        joinTree(LazyPropagation self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current join tree used

        """
        return _pyAgrum.LazyPropagation_joinTree(self)

    def junctionTree(self) -> "gum::JunctionTree const *":
        r"""
        junctionTree(LazyPropagation self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.LazyPropagation_junctionTree(self)

    def evidenceProbability(self) -> "double":
        r"""
        evidenceProbability(LazyPropagation self) -> double

        Returns
        -------
        double
          the probability of evidence

        """
        return _pyAgrum.LazyPropagation_evidenceProbability(self)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LazyPropagation self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LazyPropagation_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LazyPropagation self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LazyPropagation_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LazyPropagation self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LazyPropagation_targets(self)

    def jointMutualInformation(self, targets: 'PyObject *') -> "double":
        r"""jointMutualInformation(LazyPropagation self, PyObject * targets) -> double"""
        return _pyAgrum.LazyPropagation_jointMutualInformation(self, targets)

    def jointPosterior(self, list: 'PyObject *') -> "gum::Potential< double >":
        r"""
        jointPosterior(LazyPropagation self, PyObject * list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LazyPropagation_jointPosterior(self, list)

    def addJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        addJointTarget(LazyPropagation self, PyObject * list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_addJointTarget(self, list)

    def eraseJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        eraseJointTarget(LazyPropagation self, PyObject * list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseJointTarget(self, list)

    def isJointTarget(self, list: 'PyObject *') -> "bool":
        r"""
        isJointTarget(LazyPropagation self, PyObject * list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_isJointTarget(self, list)

    def jointTargets(self) -> "PyObject *":
        r"""
        jointTargets(LazyPropagation self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.LazyPropagation_jointTargets(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LazyPropagation self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LazyPropagation_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LazyPropagation self, gum::NodeId const var) -> Potential
        posterior(LazyPropagation self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LazyPropagation_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LazyPropagation self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LazyPropagation_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LazyPropagation self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LazyPropagation self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LazyPropagation self, gum::NodeId const id, std::string const & val)
        addEvidence(LazyPropagation self, std::string const & nodeName, std::string const & val)
        addEvidence(LazyPropagation self, gum::NodeId const id, Vector vals)
        addEvidence(LazyPropagation self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LazyPropagation self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LazyPropagation self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LazyPropagation self, gum::NodeId const id, std::string const & val)
        chgEvidence(LazyPropagation self, std::string const & nodeName, std::string const & val)
        chgEvidence(LazyPropagation self, gum::NodeId const id, Vector vals)
        chgEvidence(LazyPropagation self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LazyPropagation self, gum::NodeId const id) -> bool
        hasEvidence(LazyPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LazyPropagation self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LazyPropagation_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LazyPropagation self, gum::NodeId const id)
        eraseEvidence(LazyPropagation self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LazyPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LazyPropagation self, gum::NodeId const id) -> bool
        hasSoftEvidence(LazyPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LazyPropagation_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LazyPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LazyPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LazyPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LazyPropagation_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LazyPropagation self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LazyPropagation_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LazyPropagation self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LazyPropagation_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LazyPropagation self, gum::NodeId const target)
        addTarget(LazyPropagation self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LazyPropagation_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LazyPropagation self, gum::NodeId const target)
        eraseTarget(LazyPropagation self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LazyPropagation self, gum::NodeId const variable) -> bool
        isTarget(LazyPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LazyPropagation_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LazyPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LazyPropagation_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LazyPropagation self, gum::NodeId const X) -> double
        H(LazyPropagation self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LazyPropagation_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LazyPropagation self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LazyPropagation self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LazyPropagation_evidenceImpact(self, *args)

    def eraseAllJointTargets(self) -> "void":
        r"""
        eraseAllJointTargets(LazyPropagation self)

        Clear all previously defined joint targets.

        """
        return _pyAgrum.LazyPropagation_eraseAllJointTargets(self)

    def eraseAllMarginalTargets(self) -> "void":
        r"""
        eraseAllMarginalTargets(LazyPropagation self)

        Clear all the previously defined marginal targets.

        """
        return _pyAgrum.LazyPropagation_eraseAllMarginalTargets(self)

    def nbrJointTargets(self) -> "gum::Size":
        r"""
        nbrJointTargets(LazyPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of joint targets

        """
        return _pyAgrum.LazyPropagation_nbrJointTargets(self)

    def I(self, X: 'gum::NodeId const', Y: 'gum::NodeId const') -> "double":
        r"""
        I(LazyPropagation self, gum::NodeId const X, gum::NodeId const Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LazyPropagation_I(self, X, Y)

    def VI(self, X: 'gum::NodeId const', Y: 'gum::NodeId const') -> "double":
        r"""
        VI(LazyPropagation self, gum::NodeId const X, gum::NodeId const Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          variation of information between X and Y

        """
        return _pyAgrum.LazyPropagation_VI(self, X, Y)

    def evidenceJointImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceJointImpact(LazyPropagation self, PyObject * targets, PyObject * evs) -> Potential
        evidenceJointImpact(LazyPropagation self, Vector_string targets, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(joint targets|evs) (for all instanciation of targets and evs)

        Parameters
        ----------
        targets :
          (int) a node Id
        targets :
          (str) a node name
        evs : set
          a set of nodes ids or names.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(target|evs)

        Raises
        ------
        gum.Exception
          If some evidene entered into the Bayes net are incompatible (their joint proba = 0)

        """
        return _pyAgrum.LazyPropagation_evidenceJointImpact(self, *args)

# Register LazyPropagation in _pyAgrum:
_pyAgrum.LazyPropagation_swigregister(LazyPropagation)

class ShaferShenoyInference(object):
    r"""



    Class used for Shafer-Shenoy inferences.

    Available constructors:
    	``ShaferShenoyInference(bn) -> ShaferShenoyInference``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""__init__(ShaferShenoyInference self, IBayesNet BN, gum::FindBarrenNodesType barren_type=FIND_BARREN_NODES, bool use_binary_join_tree=True) -> ShaferShenoyInference"""
        _pyAgrum.ShaferShenoyInference_swiginit(self, _pyAgrum.new_ShaferShenoyInference(*args))

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_ShaferShenoyInference

    def setTriangulation(self, new_triangulation: 'Triangulation') -> "void":
        r"""setTriangulation(ShaferShenoyInference self, Triangulation new_triangulation)"""
        return _pyAgrum.ShaferShenoyInference_setTriangulation(self, new_triangulation)

    def setFindBarrenNodesType(self, type: 'gum::FindBarrenNodesType') -> "void":
        r"""
        setFindBarrenNodesType(ShaferShenoyInference self, gum::FindBarrenNodesType type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.ShaferShenoyInference_setFindBarrenNodesType(self, type)

    def joinTree(self) -> "gum::JoinTree const *":
        r"""
        joinTree(ShaferShenoyInference self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current join tree used

        """
        return _pyAgrum.ShaferShenoyInference_joinTree(self)

    def junctionTree(self) -> "gum::JunctionTree const *":
        r"""
        junctionTree(ShaferShenoyInference self) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.ShaferShenoyInference_junctionTree(self)

    def evidenceProbability(self) -> "double":
        r"""
        evidenceProbability(ShaferShenoyInference self) -> double

        Returns
        -------
        double
          the probability of evidence

        """
        return _pyAgrum.ShaferShenoyInference_evidenceProbability(self)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(ShaferShenoyInference self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.ShaferShenoyInference_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(ShaferShenoyInference self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.ShaferShenoyInference_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(ShaferShenoyInference self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.ShaferShenoyInference_targets(self)

    def jointMutualInformation(self, targets: 'PyObject *') -> "double":
        r"""jointMutualInformation(ShaferShenoyInference self, PyObject * targets) -> double"""
        return _pyAgrum.ShaferShenoyInference_jointMutualInformation(self, targets)

    def jointPosterior(self, list: 'PyObject *') -> "gum::Potential< double >":
        r"""
        jointPosterior(ShaferShenoyInference self, PyObject * list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ShaferShenoyInference_jointPosterior(self, list)

    def addJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        addJointTarget(ShaferShenoyInference self, PyObject * list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_addJointTarget(self, list)

    def eraseJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        eraseJointTarget(ShaferShenoyInference self, PyObject * list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseJointTarget(self, list)

    def isJointTarget(self, list: 'PyObject *') -> "bool":
        r"""
        isJointTarget(ShaferShenoyInference self, PyObject * list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_isJointTarget(self, list)

    def jointTargets(self) -> "PyObject *":
        r"""
        jointTargets(ShaferShenoyInference self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.ShaferShenoyInference_jointTargets(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(ShaferShenoyInference self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.ShaferShenoyInference_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(ShaferShenoyInference self, gum::NodeId const var) -> Potential
        posterior(ShaferShenoyInference self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ShaferShenoyInference_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(ShaferShenoyInference self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.ShaferShenoyInference_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(ShaferShenoyInference self, gum::NodeId const id, gum::Idx const val)
        addEvidence(ShaferShenoyInference self, std::string const & nodeName, gum::Idx const val)
        addEvidence(ShaferShenoyInference self, gum::NodeId const id, std::string const & val)
        addEvidence(ShaferShenoyInference self, std::string const & nodeName, std::string const & val)
        addEvidence(ShaferShenoyInference self, gum::NodeId const id, Vector vals)
        addEvidence(ShaferShenoyInference self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(ShaferShenoyInference self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(ShaferShenoyInference self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(ShaferShenoyInference self, gum::NodeId const id, std::string const & val)
        chgEvidence(ShaferShenoyInference self, std::string const & nodeName, std::string const & val)
        chgEvidence(ShaferShenoyInference self, gum::NodeId const id, Vector vals)
        chgEvidence(ShaferShenoyInference self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(ShaferShenoyInference self, gum::NodeId const id) -> bool
        hasEvidence(ShaferShenoyInference self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(ShaferShenoyInference self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(ShaferShenoyInference self, gum::NodeId const id)
        eraseEvidence(ShaferShenoyInference self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(ShaferShenoyInference self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(ShaferShenoyInference self, gum::NodeId const id) -> bool
        hasSoftEvidence(ShaferShenoyInference self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(ShaferShenoyInference self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(ShaferShenoyInference self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(ShaferShenoyInference self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(ShaferShenoyInference self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(ShaferShenoyInference self)

        Add all the nodes as targets.

        """
        return _pyAgrum.ShaferShenoyInference_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(ShaferShenoyInference self, gum::NodeId const target)
        addTarget(ShaferShenoyInference self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.ShaferShenoyInference_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(ShaferShenoyInference self, gum::NodeId const target)
        eraseTarget(ShaferShenoyInference self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(ShaferShenoyInference self, gum::NodeId const variable) -> bool
        isTarget(ShaferShenoyInference self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ShaferShenoyInference_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(ShaferShenoyInference self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.ShaferShenoyInference_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(ShaferShenoyInference self, gum::NodeId const X) -> double
        H(ShaferShenoyInference self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ShaferShenoyInference_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(ShaferShenoyInference self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(ShaferShenoyInference self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.ShaferShenoyInference_evidenceImpact(self, *args)

    def eraseAllJointTargets(self) -> "void":
        r"""
        eraseAllJointTargets(ShaferShenoyInference self)

        Clear all previously defined joint targets.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllJointTargets(self)

    def eraseAllMarginalTargets(self) -> "void":
        r"""
        eraseAllMarginalTargets(ShaferShenoyInference self)

        Clear all the previously defined marginal targets.

        """
        return _pyAgrum.ShaferShenoyInference_eraseAllMarginalTargets(self)

    def nbrJointTargets(self) -> "gum::Size":
        r"""
        nbrJointTargets(ShaferShenoyInference self) -> gum::Size

        Returns
        -------
        int
          the number of joint targets

        """
        return _pyAgrum.ShaferShenoyInference_nbrJointTargets(self)

    def I(self, X: 'gum::NodeId const', Y: 'gum::NodeId const') -> "double":
        r"""
        I(ShaferShenoyInference self, gum::NodeId const X, gum::NodeId const Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ShaferShenoyInference_I(self, X, Y)

    def VI(self, X: 'gum::NodeId const', Y: 'gum::NodeId const') -> "double":
        r"""
        VI(ShaferShenoyInference self, gum::NodeId const X, gum::NodeId const Y) -> double

        Parameters
        ----------
        X : int
          a node Id
        Y : int
          another node Id

        Returns
        -------
        double
          variation of information between X and Y

        """
        return _pyAgrum.ShaferShenoyInference_VI(self, X, Y)

    def evidenceJointImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceJointImpact(ShaferShenoyInference self, PyObject * targets, PyObject * evs) -> Potential
        evidenceJointImpact(ShaferShenoyInference self, Vector_string targets, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(joint targets|evs) (for all instanciation of targets and evs)

        Parameters
        ----------
        targets :
          (int) a node Id
        targets :
          (str) a node name
        evs : set
          a set of nodes ids or names.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(target|evs)

        Raises
        ------
        gum.Exception
          If some evidene entered into the Bayes net are incompatible (their joint proba = 0)

        """
        return _pyAgrum.ShaferShenoyInference_evidenceJointImpact(self, *args)

# Register ShaferShenoyInference in _pyAgrum:
_pyAgrum.ShaferShenoyInference_swigregister(ShaferShenoyInference)

class VariableElimination(object):
    r"""



    Class used for Variable Elimination inference algorithm.

    Available constructors:
    	``VariableElimination(bn) -> VariableElimination``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""__init__(VariableElimination self, IBayesNet BN, gum::RelevantPotentialsFinderType relevant_type=DSEP_BAYESBALL_POTENTIALS, gum::FindBarrenNodesType arg4=FIND_BARREN_NODES) -> VariableElimination"""
        _pyAgrum.VariableElimination_swiginit(self, _pyAgrum.new_VariableElimination(*args))

        self._bn=args[0]#BN



    __swig_destroy__ = _pyAgrum.delete_VariableElimination

    def setTriangulation(self, new_triangulation: 'Triangulation') -> "void":
        r"""setTriangulation(VariableElimination self, Triangulation new_triangulation)"""
        return _pyAgrum.VariableElimination_setTriangulation(self, new_triangulation)

    def setRelevantPotentialsFinderType(self, type: 'gum::RelevantPotentialsFinderType') -> "void":
        r"""
        setRelevantPotentialsFinderType(VariableElimination self, gum::RelevantPotentialsFinderType type)

        sets how we determine the relevant potentials to combine

        When a clique sends a message to a separator, it first constitute the set of the potentials it contains and of the potentials contained in the messages it received. If RelevantPotentialsFinderType = FIND_ALL, all these potentials are combined and projected to produce the message sent to the separator. If RelevantPotentialsFinderType = DSEP_BAYESBALL_NODES, then only the set of potentials d-connected to the variables of the separator are kept for combination and projection.

        0 = FIND_ALL
        1 = DSEP_BAYESBALL_NODES
        2 = DSEP_BAYESBALL_POTENTIALS
        3 = DSEP_KOLLER_FRIEDMAN_2009

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.VariableElimination_setRelevantPotentialsFinderType(self, type)

    def setFindBarrenNodesType(self, type: 'gum::FindBarrenNodesType') -> "void":
        r"""
        setFindBarrenNodesType(VariableElimination self, gum::FindBarrenNodesType type)

        sets how we determine barren nodes

        Barren nodes are unnecessary for probability inference, so they can be safely discarded in this case (type = FIND_BARREN_NODES). This speeds-up inference. However, there are some cases in which we do not want to remove barren nodes, typically when we want to answer queries such as Most Probable Explanations (MPE).

        0 = FIND_NO_BARREN_NODES
        1 = FIND_BARREN_NODES

        Parameters
        ----------
        type : int
          the finder type

        Raises
        ------
        gum.InvalidArgument
          If type is not implemented

        """
        return _pyAgrum.VariableElimination_setFindBarrenNodesType(self, type)

    def junctionTree(self, id: 'gum::NodeId') -> "gum::JunctionTree const *":
        r"""
        junctionTree(VariableElimination self, gum::NodeId id) -> CliqueGraph

        Returns
        -------
        pyAgrum.CliqueGraph
          the current junction tree

        """
        return _pyAgrum.VariableElimination_junctionTree(self, id)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(VariableElimination self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.VariableElimination_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(VariableElimination self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.VariableElimination_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(VariableElimination self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.VariableElimination_targets(self)

    def jointMutualInformation(self, targets: 'PyObject *') -> "double":
        r"""jointMutualInformation(VariableElimination self, PyObject * targets) -> double"""
        return _pyAgrum.VariableElimination_jointMutualInformation(self, targets)

    def evidenceJointImpact(self, targets: 'PyObject *', evs: 'PyObject *') -> "gum::Potential< double >":
        r"""
        evidenceJointImpact(VariableElimination self, PyObject * targets, PyObject * evs) -> Potential

        Create a pyAgrum.Potential for P(joint targets|evs) (for all instanciation of targets and evs)

        Parameters
        ----------
        targets :
          (int) a node Id
        targets :
          (str) a node name
        evs : set
          a set of nodes ids or names.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(target|evs)

        Raises
        ------
        gum.Exception
          If some evidene entered into the Bayes net are incompatible (their joint proba = 0)

        """
        return _pyAgrum.VariableElimination_evidenceJointImpact(self, targets, evs)

    def jointPosterior(self, list: 'PyObject *') -> "gum::Potential< double >":
        r"""
        jointPosterior(VariableElimination self, PyObject * list) -> Potential

        Compute the joint posterior of a set of nodes.

        Parameters
        ----------
        list :
          the list of nodes whose posterior joint probability is wanted


        Warnings
        --------
        The order of the variables given by the list here or when the jointTarget is declared can not be assumed to be used bu the Potential.

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior joint probability of the set of nodes.

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.VariableElimination_jointPosterior(self, list)

    def addJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        addJointTarget(VariableElimination self, PyObject * list)

        Add a list of nodes as a new joint target. As a collateral effect, every node is added as a marginal target.

        Parameters
        ----------
        list
          a list of names of nodes

        Raises
        ------
        gum.UndefinedElement
          If some node(s) do not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_addJointTarget(self, list)

    def eraseJointTarget(self, list: 'PyObject *') -> "void":
        r"""
        eraseJointTarget(VariableElimination self, PyObject * list)

        Remove, if existing, the joint target.

        Parameters
        ----------
        list
          a list of names or Ids of nodes

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseJointTarget(self, list)

    def isJointTarget(self, list: 'PyObject *') -> "bool":
        r"""
        isJointTarget(VariableElimination self, PyObject * list) -> bool

        Parameters
        ----------
        list
          a list of nodes ids or names.

        Returns
        -------
        bool
          True if target is a joint target.

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_isJointTarget(self, list)

    def jointTargets(self) -> "PyObject *":
        r"""
        jointTargets(VariableElimination self) -> PyObject *

        Returns
        -------
        list
          the list of target sets

        """
        return _pyAgrum.VariableElimination_jointTargets(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(VariableElimination self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.VariableElimination_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(VariableElimination self, gum::NodeId const var) -> Potential
        posterior(VariableElimination self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.VariableElimination_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(VariableElimination self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.VariableElimination_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(VariableElimination self, gum::NodeId const id, gum::Idx const val)
        addEvidence(VariableElimination self, std::string const & nodeName, gum::Idx const val)
        addEvidence(VariableElimination self, gum::NodeId const id, std::string const & val)
        addEvidence(VariableElimination self, std::string const & nodeName, std::string const & val)
        addEvidence(VariableElimination self, gum::NodeId const id, Vector vals)
        addEvidence(VariableElimination self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(VariableElimination self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(VariableElimination self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(VariableElimination self, gum::NodeId const id, std::string const & val)
        chgEvidence(VariableElimination self, std::string const & nodeName, std::string const & val)
        chgEvidence(VariableElimination self, gum::NodeId const id, Vector vals)
        chgEvidence(VariableElimination self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(VariableElimination self, gum::NodeId const id) -> bool
        hasEvidence(VariableElimination self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(VariableElimination self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.VariableElimination_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(VariableElimination self, gum::NodeId const id)
        eraseEvidence(VariableElimination self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(VariableElimination self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(VariableElimination self, gum::NodeId const id) -> bool
        hasSoftEvidence(VariableElimination self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.VariableElimination_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(VariableElimination self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(VariableElimination self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(VariableElimination self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.VariableElimination_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(VariableElimination self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.VariableElimination_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(VariableElimination self)

        Add all the nodes as targets.

        """
        return _pyAgrum.VariableElimination_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(VariableElimination self, gum::NodeId const target)
        addTarget(VariableElimination self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.VariableElimination_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(VariableElimination self, gum::NodeId const target)
        eraseTarget(VariableElimination self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(VariableElimination self, gum::NodeId const variable) -> bool
        isTarget(VariableElimination self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.VariableElimination_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(VariableElimination self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.VariableElimination_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(VariableElimination self, gum::NodeId const X) -> double
        H(VariableElimination self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.VariableElimination_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(VariableElimination self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(VariableElimination self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.VariableElimination_evidenceImpact(self, *args)

# Register VariableElimination in _pyAgrum:
_pyAgrum.VariableElimination_swigregister(VariableElimination)

class GibbsSampling(object):
    r"""



    Class for making Gibbs sampling inference in bayesian networks.

    Available constructors:
    	``GibbsSampling(bn) -> GibbsSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(GibbsSampling self, IBayesNet bn) -> GibbsSampling"""
        _pyAgrum.GibbsSampling_swiginit(self, _pyAgrum.new_GibbsSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_GibbsSampling

    def setBurnIn(self, b: 'gum::Size') -> "void":
        r"""
        setBurnIn(GibbsSampling self, gum::Size b)

        Parameters
        ----------
        b : int
          size of burn in on number of iteration

        """
        return _pyAgrum.GibbsSampling_setBurnIn(self, b)

    def burnIn(self) -> "gum::Size":
        r"""
        burnIn(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          size of burn in on number of iteration

        """
        return _pyAgrum.GibbsSampling_burnIn(self)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(GibbsSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.GibbsSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(GibbsSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.GibbsSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(GibbsSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.GibbsSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(GibbsSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.GibbsSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(GibbsSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.GibbsSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(GibbsSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.GibbsSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(GibbsSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.GibbsSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(GibbsSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.GibbsSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(GibbsSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(GibbsSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.GibbsSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(GibbsSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.GibbsSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(GibbsSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.GibbsSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.GibbsSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(GibbsSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.GibbsSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.GibbsSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(GibbsSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.GibbsSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(GibbsSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.GibbsSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(GibbsSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.GibbsSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(GibbsSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.GibbsSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(GibbsSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.GibbsSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(GibbsSampling self, gum::NodeId const var) -> Potential
        posterior(GibbsSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.GibbsSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(GibbsSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.GibbsSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(GibbsSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(GibbsSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(GibbsSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(GibbsSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(GibbsSampling self, gum::NodeId const id, Vector vals)
        addEvidence(GibbsSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(GibbsSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(GibbsSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(GibbsSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(GibbsSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(GibbsSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(GibbsSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(GibbsSampling self, gum::NodeId const id) -> bool
        hasEvidence(GibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(GibbsSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.GibbsSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(GibbsSampling self, gum::NodeId const id)
        eraseEvidence(GibbsSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(GibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(GibbsSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(GibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.GibbsSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.GibbsSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(GibbsSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.GibbsSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(GibbsSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.GibbsSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(GibbsSampling self, gum::NodeId const target)
        addTarget(GibbsSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.GibbsSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(GibbsSampling self, gum::NodeId const target)
        eraseTarget(GibbsSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.GibbsSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(GibbsSampling self, gum::NodeId const variable) -> bool
        isTarget(GibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.GibbsSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.GibbsSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(GibbsSampling self, gum::NodeId const X) -> double
        H(GibbsSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.GibbsSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(GibbsSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(GibbsSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.GibbsSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(GibbsSampling self, gum::NodeId const id) -> Potential
        currentPosterior(GibbsSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.GibbsSampling_currentPosterior(self, *args)

    def nbrDrawnVar(self) -> "gum::Size":
        r"""
        nbrDrawnVar(GibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.GibbsSampling_nbrDrawnVar(self)

    def setNbrDrawnVar(self, _nbr: 'gum::Size') -> "void":
        r"""
        setNbrDrawnVar(GibbsSampling self, gum::Size _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.GibbsSampling_setNbrDrawnVar(self, _nbr)

    def isDrawnAtRandom(self) -> "bool":
        r"""
        isDrawnAtRandom(GibbsSampling self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.GibbsSampling_isDrawnAtRandom(self)

    def setDrawnAtRandom(self, _atRandom: 'bool') -> "void":
        r"""
        setDrawnAtRandom(GibbsSampling self, bool _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.GibbsSampling_setDrawnAtRandom(self, _atRandom)

# Register GibbsSampling in _pyAgrum:
_pyAgrum.GibbsSampling_swigregister(GibbsSampling)

class ImportanceSampling(object):
    r"""



    Class used for inferences using the Importance Sampling algorithm.

    Available constructors:
    	``ImportanceSampling(bn) -> ImportanceSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(ImportanceSampling self, IBayesNet bn) -> ImportanceSampling"""
        _pyAgrum.ImportanceSampling_swiginit(self, _pyAgrum.new_ImportanceSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_ImportanceSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(ImportanceSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.ImportanceSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(ImportanceSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.ImportanceSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(ImportanceSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.ImportanceSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(ImportanceSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.ImportanceSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(ImportanceSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.ImportanceSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(ImportanceSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.ImportanceSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(ImportanceSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.ImportanceSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(ImportanceSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.ImportanceSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(ImportanceSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ImportanceSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(ImportanceSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.ImportanceSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(ImportanceSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.ImportanceSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(ImportanceSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.ImportanceSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.ImportanceSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(ImportanceSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.ImportanceSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.ImportanceSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.ImportanceSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(ImportanceSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.ImportanceSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(ImportanceSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.ImportanceSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(ImportanceSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.ImportanceSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(ImportanceSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.ImportanceSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(ImportanceSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.ImportanceSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(ImportanceSampling self, gum::NodeId const var) -> Potential
        posterior(ImportanceSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ImportanceSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(ImportanceSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.ImportanceSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(ImportanceSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(ImportanceSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(ImportanceSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(ImportanceSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(ImportanceSampling self, gum::NodeId const id, Vector vals)
        addEvidence(ImportanceSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(ImportanceSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(ImportanceSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(ImportanceSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(ImportanceSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(ImportanceSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(ImportanceSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(ImportanceSampling self, gum::NodeId const id) -> bool
        hasEvidence(ImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(ImportanceSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.ImportanceSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(ImportanceSampling self, gum::NodeId const id)
        eraseEvidence(ImportanceSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(ImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(ImportanceSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(ImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(ImportanceSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.ImportanceSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(ImportanceSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.ImportanceSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(ImportanceSampling self, gum::NodeId const target)
        addTarget(ImportanceSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.ImportanceSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(ImportanceSampling self, gum::NodeId const target)
        eraseTarget(ImportanceSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(ImportanceSampling self, gum::NodeId const variable) -> bool
        isTarget(ImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.ImportanceSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(ImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.ImportanceSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(ImportanceSampling self, gum::NodeId const X) -> double
        H(ImportanceSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.ImportanceSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(ImportanceSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(ImportanceSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.ImportanceSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(ImportanceSampling self, gum::NodeId const id) -> Potential
        currentPosterior(ImportanceSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.ImportanceSampling_currentPosterior(self, *args)

# Register ImportanceSampling in _pyAgrum:
_pyAgrum.ImportanceSampling_swigregister(ImportanceSampling)

class WeightedSampling(object):
    r"""



    Class used for Weighted sampling inference algorithm.

    Available constructors:
    	``WeightedSampling(bn) -> WeightedSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(WeightedSampling self, IBayesNet bn) -> WeightedSampling"""
        _pyAgrum.WeightedSampling_swiginit(self, _pyAgrum.new_WeightedSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_WeightedSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(WeightedSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.WeightedSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(WeightedSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.WeightedSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(WeightedSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.WeightedSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(WeightedSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.WeightedSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(WeightedSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.WeightedSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(WeightedSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.WeightedSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(WeightedSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.WeightedSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(WeightedSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.WeightedSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(WeightedSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.WeightedSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(WeightedSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.WeightedSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(WeightedSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.WeightedSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(WeightedSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.WeightedSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.WeightedSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(WeightedSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.WeightedSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.WeightedSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.WeightedSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(WeightedSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.WeightedSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(WeightedSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.WeightedSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(WeightedSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.WeightedSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(WeightedSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.WeightedSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(WeightedSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.WeightedSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(WeightedSampling self, gum::NodeId const var) -> Potential
        posterior(WeightedSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.WeightedSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(WeightedSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.WeightedSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(WeightedSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(WeightedSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(WeightedSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(WeightedSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(WeightedSampling self, gum::NodeId const id, Vector vals)
        addEvidence(WeightedSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(WeightedSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(WeightedSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(WeightedSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(WeightedSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(WeightedSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(WeightedSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(WeightedSampling self, gum::NodeId const id) -> bool
        hasEvidence(WeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(WeightedSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.WeightedSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(WeightedSampling self, gum::NodeId const id)
        eraseEvidence(WeightedSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(WeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(WeightedSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(WeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.WeightedSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.WeightedSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(WeightedSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.WeightedSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(WeightedSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.WeightedSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(WeightedSampling self, gum::NodeId const target)
        addTarget(WeightedSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.WeightedSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(WeightedSampling self, gum::NodeId const target)
        eraseTarget(WeightedSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.WeightedSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(WeightedSampling self, gum::NodeId const variable) -> bool
        isTarget(WeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.WeightedSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(WeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.WeightedSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(WeightedSampling self, gum::NodeId const X) -> double
        H(WeightedSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.WeightedSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(WeightedSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(WeightedSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.WeightedSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(WeightedSampling self, gum::NodeId const id) -> Potential
        currentPosterior(WeightedSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.WeightedSampling_currentPosterior(self, *args)

# Register WeightedSampling in _pyAgrum:
_pyAgrum.WeightedSampling_swigregister(WeightedSampling)

class MonteCarloSampling(object):
    r"""



    Class used for Monte Carlo sampling inference algorithm.

    Available constructors:
    	``MonteCarloSampling(bn) -> MonteCarloSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(MonteCarloSampling self, IBayesNet bn) -> MonteCarloSampling"""
        _pyAgrum.MonteCarloSampling_swiginit(self, _pyAgrum.new_MonteCarloSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_MonteCarloSampling

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(MonteCarloSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.MonteCarloSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(MonteCarloSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.MonteCarloSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(MonteCarloSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.MonteCarloSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(MonteCarloSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.MonteCarloSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(MonteCarloSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.MonteCarloSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(MonteCarloSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.MonteCarloSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(MonteCarloSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.MonteCarloSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(MonteCarloSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.MonteCarloSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(MonteCarloSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.MonteCarloSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(MonteCarloSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.MonteCarloSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(MonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.MonteCarloSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(MonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.MonteCarloSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.MonteCarloSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(MonteCarloSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.MonteCarloSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.MonteCarloSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.MonteCarloSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(MonteCarloSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.MonteCarloSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(MonteCarloSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.MonteCarloSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(MonteCarloSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.MonteCarloSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(MonteCarloSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.MonteCarloSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(MonteCarloSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.MonteCarloSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(MonteCarloSampling self, gum::NodeId const var) -> Potential
        posterior(MonteCarloSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.MonteCarloSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(MonteCarloSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.MonteCarloSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(MonteCarloSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(MonteCarloSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(MonteCarloSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(MonteCarloSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(MonteCarloSampling self, gum::NodeId const id, Vector vals)
        addEvidence(MonteCarloSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(MonteCarloSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(MonteCarloSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(MonteCarloSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(MonteCarloSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(MonteCarloSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(MonteCarloSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(MonteCarloSampling self, gum::NodeId const id) -> bool
        hasEvidence(MonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(MonteCarloSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.MonteCarloSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(MonteCarloSampling self, gum::NodeId const id)
        eraseEvidence(MonteCarloSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(MonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(MonteCarloSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(MonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(MonteCarloSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.MonteCarloSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(MonteCarloSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.MonteCarloSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(MonteCarloSampling self, gum::NodeId const target)
        addTarget(MonteCarloSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.MonteCarloSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(MonteCarloSampling self, gum::NodeId const target)
        eraseTarget(MonteCarloSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(MonteCarloSampling self, gum::NodeId const variable) -> bool
        isTarget(MonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.MonteCarloSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(MonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.MonteCarloSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(MonteCarloSampling self, gum::NodeId const X) -> double
        H(MonteCarloSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.MonteCarloSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(MonteCarloSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(MonteCarloSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.MonteCarloSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(MonteCarloSampling self, gum::NodeId const id) -> Potential
        currentPosterior(MonteCarloSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.MonteCarloSampling_currentPosterior(self, *args)

# Register MonteCarloSampling in _pyAgrum:
_pyAgrum.MonteCarloSampling_swigregister(MonteCarloSampling)

class LoopyImportanceSampling(object):
    r"""

    Class used for inferences using a loopy version of importance sampling.

    Available constructors:
    	``LoopyImportanceSampling(bn) -> LoopyImportanceSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(LoopyImportanceSampling self, IBayesNet bn) -> LoopyImportanceSampling"""
        _pyAgrum.LoopyImportanceSampling_swiginit(self, _pyAgrum.new_LoopyImportanceSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyImportanceSampling

    def _makeInference(self) -> "void":
        r"""_makeInference(LoopyImportanceSampling self)"""
        return _pyAgrum.LoopyImportanceSampling__makeInference(self)

    def setVirtualLBPSize(self, vlbpsize: 'double') -> "void":
        r"""
        setVirtualLBPSize(LoopyImportanceSampling self, double vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyImportanceSampling_setVirtualLBPSize(self, vlbpsize)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LoopyImportanceSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyImportanceSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LoopyImportanceSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyImportanceSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LoopyImportanceSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyImportanceSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(LoopyImportanceSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyImportanceSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(LoopyImportanceSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyImportanceSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(LoopyImportanceSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyImportanceSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(LoopyImportanceSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyImportanceSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(LoopyImportanceSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyImportanceSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(LoopyImportanceSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyImportanceSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(LoopyImportanceSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyImportanceSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(LoopyImportanceSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyImportanceSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(LoopyImportanceSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyImportanceSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyImportanceSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(LoopyImportanceSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyImportanceSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyImportanceSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyImportanceSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(LoopyImportanceSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyImportanceSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(LoopyImportanceSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyImportanceSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(LoopyImportanceSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyImportanceSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(LoopyImportanceSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.LoopyImportanceSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LoopyImportanceSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyImportanceSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LoopyImportanceSampling self, gum::NodeId const var) -> Potential
        posterior(LoopyImportanceSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyImportanceSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LoopyImportanceSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyImportanceSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LoopyImportanceSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LoopyImportanceSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LoopyImportanceSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(LoopyImportanceSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(LoopyImportanceSampling self, gum::NodeId const id, Vector vals)
        addEvidence(LoopyImportanceSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LoopyImportanceSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LoopyImportanceSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LoopyImportanceSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(LoopyImportanceSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(LoopyImportanceSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(LoopyImportanceSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LoopyImportanceSampling self, gum::NodeId const id) -> bool
        hasEvidence(LoopyImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LoopyImportanceSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyImportanceSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LoopyImportanceSampling self, gum::NodeId const id)
        eraseEvidence(LoopyImportanceSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LoopyImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LoopyImportanceSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(LoopyImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LoopyImportanceSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyImportanceSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LoopyImportanceSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyImportanceSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LoopyImportanceSampling self, gum::NodeId const target)
        addTarget(LoopyImportanceSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyImportanceSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LoopyImportanceSampling self, gum::NodeId const target)
        eraseTarget(LoopyImportanceSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LoopyImportanceSampling self, gum::NodeId const variable) -> bool
        isTarget(LoopyImportanceSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyImportanceSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LoopyImportanceSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyImportanceSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LoopyImportanceSampling self, gum::NodeId const X) -> double
        H(LoopyImportanceSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyImportanceSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LoopyImportanceSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LoopyImportanceSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyImportanceSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(LoopyImportanceSampling self, gum::NodeId const id) -> Potential
        currentPosterior(LoopyImportanceSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyImportanceSampling_currentPosterior(self, *args)

# Register LoopyImportanceSampling in _pyAgrum:
_pyAgrum.LoopyImportanceSampling_swigregister(LoopyImportanceSampling)

class LoopyWeightedSampling(object):
    r"""

    Class used for inferences using a loopy version of weighted sampling.

    Available constructors:
    	``LoopyWeightedSampling(bn) -> LoopyWeightedSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(LoopyWeightedSampling self, IBayesNet bn) -> LoopyWeightedSampling"""
        _pyAgrum.LoopyWeightedSampling_swiginit(self, _pyAgrum.new_LoopyWeightedSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyWeightedSampling

    def _makeInference(self) -> "void":
        r"""_makeInference(LoopyWeightedSampling self)"""
        return _pyAgrum.LoopyWeightedSampling__makeInference(self)

    def setVirtualLBPSize(self, vlbpsize: 'double') -> "void":
        r"""
        setVirtualLBPSize(LoopyWeightedSampling self, double vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyWeightedSampling_setVirtualLBPSize(self, vlbpsize)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LoopyWeightedSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyWeightedSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LoopyWeightedSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyWeightedSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LoopyWeightedSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyWeightedSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(LoopyWeightedSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyWeightedSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(LoopyWeightedSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyWeightedSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(LoopyWeightedSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyWeightedSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(LoopyWeightedSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyWeightedSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(LoopyWeightedSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyWeightedSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(LoopyWeightedSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyWeightedSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(LoopyWeightedSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyWeightedSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(LoopyWeightedSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyWeightedSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(LoopyWeightedSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyWeightedSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyWeightedSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(LoopyWeightedSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyWeightedSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyWeightedSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyWeightedSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(LoopyWeightedSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyWeightedSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(LoopyWeightedSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyWeightedSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(LoopyWeightedSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyWeightedSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(LoopyWeightedSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.LoopyWeightedSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LoopyWeightedSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyWeightedSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LoopyWeightedSampling self, gum::NodeId const var) -> Potential
        posterior(LoopyWeightedSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyWeightedSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LoopyWeightedSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyWeightedSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LoopyWeightedSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LoopyWeightedSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LoopyWeightedSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(LoopyWeightedSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(LoopyWeightedSampling self, gum::NodeId const id, Vector vals)
        addEvidence(LoopyWeightedSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LoopyWeightedSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LoopyWeightedSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LoopyWeightedSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(LoopyWeightedSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(LoopyWeightedSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(LoopyWeightedSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LoopyWeightedSampling self, gum::NodeId const id) -> bool
        hasEvidence(LoopyWeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LoopyWeightedSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyWeightedSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LoopyWeightedSampling self, gum::NodeId const id)
        eraseEvidence(LoopyWeightedSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LoopyWeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LoopyWeightedSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(LoopyWeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LoopyWeightedSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyWeightedSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LoopyWeightedSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyWeightedSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LoopyWeightedSampling self, gum::NodeId const target)
        addTarget(LoopyWeightedSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyWeightedSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LoopyWeightedSampling self, gum::NodeId const target)
        eraseTarget(LoopyWeightedSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LoopyWeightedSampling self, gum::NodeId const variable) -> bool
        isTarget(LoopyWeightedSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyWeightedSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LoopyWeightedSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyWeightedSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LoopyWeightedSampling self, gum::NodeId const X) -> double
        H(LoopyWeightedSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyWeightedSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LoopyWeightedSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LoopyWeightedSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyWeightedSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(LoopyWeightedSampling self, gum::NodeId const id) -> Potential
        currentPosterior(LoopyWeightedSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyWeightedSampling_currentPosterior(self, *args)

# Register LoopyWeightedSampling in _pyAgrum:
_pyAgrum.LoopyWeightedSampling_swigregister(LoopyWeightedSampling)

class LoopyGibbsSampling(object):
    r"""

    Class used for inferences using a loopy version of Gibbs sampling.

    Available constructors:
    	``LoopyGibbsSampling(bn) -> LoopyGibbsSampling``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(LoopyGibbsSampling self, IBayesNet bn) -> LoopyGibbsSampling"""
        _pyAgrum.LoopyGibbsSampling_swiginit(self, _pyAgrum.new_LoopyGibbsSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyGibbsSampling

    def _makeInference(self) -> "void":
        r"""_makeInference(LoopyGibbsSampling self)"""
        return _pyAgrum.LoopyGibbsSampling__makeInference(self)

    def setVirtualLBPSize(self, vlbpsize: 'double') -> "void":
        r"""
        setVirtualLBPSize(LoopyGibbsSampling self, double vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyGibbsSampling_setVirtualLBPSize(self, vlbpsize)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LoopyGibbsSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyGibbsSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LoopyGibbsSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyGibbsSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LoopyGibbsSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyGibbsSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(LoopyGibbsSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyGibbsSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(LoopyGibbsSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyGibbsSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(LoopyGibbsSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyGibbsSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(LoopyGibbsSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyGibbsSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(LoopyGibbsSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyGibbsSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(LoopyGibbsSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyGibbsSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(LoopyGibbsSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyGibbsSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(LoopyGibbsSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyGibbsSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(LoopyGibbsSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyGibbsSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyGibbsSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(LoopyGibbsSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyGibbsSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyGibbsSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyGibbsSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(LoopyGibbsSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyGibbsSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(LoopyGibbsSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyGibbsSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(LoopyGibbsSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyGibbsSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(LoopyGibbsSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.LoopyGibbsSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LoopyGibbsSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyGibbsSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LoopyGibbsSampling self, gum::NodeId const var) -> Potential
        posterior(LoopyGibbsSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyGibbsSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LoopyGibbsSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyGibbsSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LoopyGibbsSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LoopyGibbsSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LoopyGibbsSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(LoopyGibbsSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(LoopyGibbsSampling self, gum::NodeId const id, Vector vals)
        addEvidence(LoopyGibbsSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LoopyGibbsSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LoopyGibbsSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LoopyGibbsSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(LoopyGibbsSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(LoopyGibbsSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(LoopyGibbsSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LoopyGibbsSampling self, gum::NodeId const id) -> bool
        hasEvidence(LoopyGibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LoopyGibbsSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyGibbsSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LoopyGibbsSampling self, gum::NodeId const id)
        eraseEvidence(LoopyGibbsSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LoopyGibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LoopyGibbsSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(LoopyGibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LoopyGibbsSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyGibbsSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LoopyGibbsSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyGibbsSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LoopyGibbsSampling self, gum::NodeId const target)
        addTarget(LoopyGibbsSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyGibbsSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LoopyGibbsSampling self, gum::NodeId const target)
        eraseTarget(LoopyGibbsSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LoopyGibbsSampling self, gum::NodeId const variable) -> bool
        isTarget(LoopyGibbsSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyGibbsSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyGibbsSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LoopyGibbsSampling self, gum::NodeId const X) -> double
        H(LoopyGibbsSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyGibbsSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LoopyGibbsSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LoopyGibbsSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyGibbsSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(LoopyGibbsSampling self, gum::NodeId const id) -> Potential
        currentPosterior(LoopyGibbsSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyGibbsSampling_currentPosterior(self, *args)

    def nbrDrawnVar(self) -> "gum::Size":
        r"""
        nbrDrawnVar(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.LoopyGibbsSampling_nbrDrawnVar(self)

    def setNbrDrawnVar(self, _nbr: 'gum::Size') -> "void":
        r"""
        setNbrDrawnVar(LoopyGibbsSampling self, gum::Size _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.LoopyGibbsSampling_setNbrDrawnVar(self, _nbr)

    def isDrawnAtRandom(self) -> "bool":
        r"""
        isDrawnAtRandom(LoopyGibbsSampling self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.LoopyGibbsSampling_isDrawnAtRandom(self)

    def setDrawnAtRandom(self, _atRandom: 'bool') -> "void":
        r"""
        setDrawnAtRandom(LoopyGibbsSampling self, bool _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.LoopyGibbsSampling_setDrawnAtRandom(self, _atRandom)

    def burnIn(self) -> "gum::Size":
        r"""
        burnIn(LoopyGibbsSampling self) -> gum::Size

        Returns
        -------
        int
          size of burn in on number of iteration

        """
        return _pyAgrum.LoopyGibbsSampling_burnIn(self)

    def setBurnIn(self, b: 'gum::Size') -> "void":
        r"""
        setBurnIn(LoopyGibbsSampling self, gum::Size b)

        Parameters
        ----------
        b : int
          size of burn in on number of iteration

        """
        return _pyAgrum.LoopyGibbsSampling_setBurnIn(self, b)

# Register LoopyGibbsSampling in _pyAgrum:
_pyAgrum.LoopyGibbsSampling_swigregister(LoopyGibbsSampling)

class LoopyMonteCarloSampling(object):
    r"""Proxy of C++ gum::LoopySamplingInference< double,gum::MonteCarloSampling > class."""

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(LoopyMonteCarloSampling self, IBayesNet bn) -> LoopyMonteCarloSampling"""
        _pyAgrum.LoopyMonteCarloSampling_swiginit(self, _pyAgrum.new_LoopyMonteCarloSampling(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyMonteCarloSampling

    def _makeInference(self) -> "void":
        r"""_makeInference(LoopyMonteCarloSampling self)"""
        return _pyAgrum.LoopyMonteCarloSampling__makeInference(self)

    def setVirtualLBPSize(self, vlbpsize: 'double') -> "void":
        r"""
        setVirtualLBPSize(LoopyMonteCarloSampling self, double vlbpsize)

        Parameters
        ----------
        vlbpsize : double
          the size of the virtual LBP

        """
        return _pyAgrum.LoopyMonteCarloSampling_setVirtualLBPSize(self, vlbpsize)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LoopyMonteCarloSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyMonteCarloSampling_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LoopyMonteCarloSampling self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyMonteCarloSampling_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LoopyMonteCarloSampling self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(LoopyMonteCarloSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyMonteCarloSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(LoopyMonteCarloSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyMonteCarloSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(LoopyMonteCarloSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(LoopyMonteCarloSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(LoopyMonteCarloSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyMonteCarloSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(LoopyMonteCarloSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyMonteCarloSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(LoopyMonteCarloSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyMonteCarloSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(LoopyMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyMonteCarloSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(LoopyMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyMonteCarloSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyMonteCarloSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(LoopyMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyMonteCarloSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyMonteCarloSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(LoopyMonteCarloSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyMonteCarloSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(LoopyMonteCarloSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyMonteCarloSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(LoopyMonteCarloSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyMonteCarloSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(LoopyMonteCarloSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.LoopyMonteCarloSampling__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LoopyMonteCarloSampling self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyMonteCarloSampling_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LoopyMonteCarloSampling self, gum::NodeId const var) -> Potential
        posterior(LoopyMonteCarloSampling self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LoopyMonteCarloSampling self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyMonteCarloSampling_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, std::string const & val)
        addEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, std::string const & val)
        addEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, Vector vals)
        addEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, std::string const & val)
        chgEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, std::string const & val)
        chgEvidence(LoopyMonteCarloSampling self, gum::NodeId const id, Vector vals)
        chgEvidence(LoopyMonteCarloSampling self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LoopyMonteCarloSampling self, gum::NodeId const id) -> bool
        hasEvidence(LoopyMonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LoopyMonteCarloSampling self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LoopyMonteCarloSampling self, gum::NodeId const id)
        eraseEvidence(LoopyMonteCarloSampling self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LoopyMonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LoopyMonteCarloSampling self, gum::NodeId const id) -> bool
        hasSoftEvidence(LoopyMonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LoopyMonteCarloSampling self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LoopyMonteCarloSampling self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyMonteCarloSampling_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LoopyMonteCarloSampling self, gum::NodeId const target)
        addTarget(LoopyMonteCarloSampling self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyMonteCarloSampling_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LoopyMonteCarloSampling self, gum::NodeId const target)
        eraseTarget(LoopyMonteCarloSampling self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LoopyMonteCarloSampling self, gum::NodeId const variable) -> bool
        isTarget(LoopyMonteCarloSampling self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyMonteCarloSampling_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LoopyMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LoopyMonteCarloSampling self, gum::NodeId const X) -> double
        H(LoopyMonteCarloSampling self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyMonteCarloSampling_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LoopyMonteCarloSampling self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LoopyMonteCarloSampling self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyMonteCarloSampling_evidenceImpact(self, *args)

    def currentPosterior(self, *args) -> "gum::Potential< double > const &":
        r"""
        currentPosterior(LoopyMonteCarloSampling self, gum::NodeId const id) -> Potential
        currentPosterior(LoopyMonteCarloSampling self, std::string const & name) -> Potential

        Computes and returns the current posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the current posterior probability of the node

        Raises
        ------
        UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyMonteCarloSampling_currentPosterior(self, *args)

# Register LoopyMonteCarloSampling in _pyAgrum:
_pyAgrum.LoopyMonteCarloSampling_swigregister(LoopyMonteCarloSampling)

class LoopyBeliefPropagation(object):
    r"""



    Class used for inferences using loopy belief propagation algorithm.

    Available constructors:
    	``LoopyBeliefPropagation(bn) -> LoopyBeliefPropagation``

    Parameters
    ----------
    bn : pyAgrum.BayesNet
    	a Bayesian network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'IBayesNet'):
        r"""__init__(LoopyBeliefPropagation self, IBayesNet bn) -> LoopyBeliefPropagation"""
        _pyAgrum.LoopyBeliefPropagation_swiginit(self, _pyAgrum.new_LoopyBeliefPropagation(bn))

        self._bn=bn#BN



    __swig_destroy__ = _pyAgrum.delete_LoopyBeliefPropagation

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))
        self.eraseAllEvidence()
        for k,v in evidces.items():
            self.addEvidence(k,v)



    def updateEvidence(self, evidces):
        """
        Apply chgEvidence(key,value) for every pairs in evidces (or addEvidence).

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be a dict, not %s"%(type(evidces)))

        for k,v in evidces.items():
            if self.hasEvidence(k):
                self.chgEvidence(k,v)
            else:
                self.addEvidence(k,v)



    def setTargets(self, targets):
        """
        Remove all the targets and add the ones in parameter.

        Parameters
        ----------
        targets : set
          a set of targets

        Raises
        ------
        gum.UndefinedElement
            If one target is not in the Bayes net
        """
        if not isinstance(targets, set):
            raise TypeError("setTargets parameter must be a set, not %s"%(type(targets)))

        self.eraseAllTargets()
        for k in targets:
            self.addTarget(k)



    def hardEvidenceNodes(self) -> "PyObject *":
        r"""
        hardEvidenceNodes(LoopyBeliefPropagation self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with hard evidence

        """
        return _pyAgrum.LoopyBeliefPropagation_hardEvidenceNodes(self)

    def softEvidenceNodes(self) -> "PyObject *":
        r"""
        softEvidenceNodes(LoopyBeliefPropagation self) -> PyObject *

        Returns
        -------
        set
          the set of nodes with soft evidence

        """
        return _pyAgrum.LoopyBeliefPropagation_softEvidenceNodes(self)

    def targets(self) -> "PyObject *":
        r"""
        targets(LoopyBeliefPropagation self) -> PyObject *

        Returns
        -------
        list
          the list of marginal targets

        """
        return _pyAgrum.LoopyBeliefPropagation_targets(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(LoopyBeliefPropagation self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.LoopyBeliefPropagation_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(LoopyBeliefPropagation self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.LoopyBeliefPropagation_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(LoopyBeliefPropagation self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.LoopyBeliefPropagation_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(LoopyBeliefPropagation self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.LoopyBeliefPropagation_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(LoopyBeliefPropagation self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.LoopyBeliefPropagation_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(LoopyBeliefPropagation self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyBeliefPropagation_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(LoopyBeliefPropagation self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.LoopyBeliefPropagation_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(LoopyBeliefPropagation self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.LoopyBeliefPropagation_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(LoopyBeliefPropagation self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.LoopyBeliefPropagation_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.LoopyBeliefPropagation_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(LoopyBeliefPropagation self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.LoopyBeliefPropagation_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.LoopyBeliefPropagation_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(LoopyBeliefPropagation self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.LoopyBeliefPropagation_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(LoopyBeliefPropagation self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.LoopyBeliefPropagation_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(LoopyBeliefPropagation self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.LoopyBeliefPropagation_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(LoopyBeliefPropagation self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.LoopyBeliefPropagation__asIApproximationSchemeConfiguration(self)

    def makeInference(self) -> "void":
        r"""
        makeInference(LoopyBeliefPropagation self)

        Perform the heavy computations needed to compute the targets' posteriors

        In a Junction tree propagation scheme, for instance, the heavy computations are those of the messages sent in the JT.
        This is precisely what makeInference should compute. Later, the computations of the posteriors can be done 'lightly' by multiplying and projecting those messages.

        """
        return _pyAgrum.LoopyBeliefPropagation_makeInference(self)

    def posterior(self, *args) -> "gum::Potential< double > const":
        r"""
        posterior(LoopyBeliefPropagation self, gum::NodeId const var) -> Potential
        posterior(LoopyBeliefPropagation self, std::string const nodeName) -> Potential

        Computes and returns the posterior of a node.

        Parameters
        ----------
        var : int
          the node Id of the node for which we need a posterior probability
        nodeName : str
          the node name of the node for which we need a posterior probability

        Returns
        -------
        pyAgrum.Potential
          a const ref to the posterior probability of the node

        Raises
        ------
        gum.UndefinedElement
          If an element of nodes is not in targets

        """
        return _pyAgrum.LoopyBeliefPropagation_posterior(self, *args)

    def BN(self) -> "gum::IBayesNet< double > const &":
        r"""
        BN(LoopyBeliefPropagation self) -> IBayesNet

        Returns
        -------
        pyAgrum.IBayesNet
          A constant reference over the IBayesNet referenced by this class.

        Raises
        ------
        gum.UndefinedElement
          If no Bayes net has been assigned to the inference.

        """
        return _pyAgrum.LoopyBeliefPropagation_BN(self)

    def addEvidence(self, *args) -> "void":
        r"""
        addEvidence(LoopyBeliefPropagation self, gum::NodeId const id, gum::Idx const val)
        addEvidence(LoopyBeliefPropagation self, std::string const & nodeName, gum::Idx const val)
        addEvidence(LoopyBeliefPropagation self, gum::NodeId const id, std::string const & val)
        addEvidence(LoopyBeliefPropagation self, std::string const & nodeName, std::string const & val)
        addEvidence(LoopyBeliefPropagation self, gum::NodeId const id, Vector vals)
        addEvidence(LoopyBeliefPropagation self, std::string const & nodeName, Vector vals)

        Adds a new evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node already has an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_addEvidence(self, *args)

    def chgEvidence(self, *args) -> "void":
        r"""
        chgEvidence(LoopyBeliefPropagation self, gum::NodeId const id, gum::Idx const val)
        chgEvidence(LoopyBeliefPropagation self, std::string const & nodeName, gum::Idx const val)
        chgEvidence(LoopyBeliefPropagation self, gum::NodeId const id, std::string const & val)
        chgEvidence(LoopyBeliefPropagation self, std::string const & nodeName, std::string const & val)
        chgEvidence(LoopyBeliefPropagation self, gum::NodeId const id, Vector vals)
        chgEvidence(LoopyBeliefPropagation self, std::string const & nodeName, Vector vals)

        Change the value of an already existing evidence on a node (might be soft or hard).

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name
        val :
          (int) a node value
        val :
          (str) the label of the node value
        vals : list
          a list of values

        Raises
        ------
        gum.InvalidArgument
          If the node does not already have an evidence
        gum.InvalidArgument
          If val is not a value for the node
        gum.InvalidArgument
          If the size of vals is different from the domain side of the node
        gum.FatalError
          If vals is a vector of 0s
        gum.UndefinedElement
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_chgEvidence(self, *args)

    def hasEvidence(self, *args) -> "bool":
        r"""
        hasEvidence(LoopyBeliefPropagation self, gum::NodeId const id) -> bool
        hasEvidence(LoopyBeliefPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if some node(s) (or the one in parameters) have received evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasEvidence(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(LoopyBeliefPropagation self)

        Removes all the evidence entered into the network.

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseAllEvidence(self)

    def eraseEvidence(self, *args) -> "void":
        r"""
        eraseEvidence(LoopyBeliefPropagation self, gum::NodeId const id)
        eraseEvidence(LoopyBeliefPropagation self, std::string const & nodeName)

        Remove the evidence, if any, corresponding to the node Id or name.

        Parameters
        ----------
        id : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseEvidence(self, *args)

    def hasHardEvidence(self, nodeName: 'std::string const &') -> "bool":
        r"""
        hasHardEvidence(LoopyBeliefPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a hard evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasHardEvidence(self, nodeName)

    def hasSoftEvidence(self, *args) -> "bool":
        r"""
        hasSoftEvidence(LoopyBeliefPropagation self, gum::NodeId const id) -> bool
        hasSoftEvidence(LoopyBeliefPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        id : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if node has received a soft evidence

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_hasSoftEvidence(self, *args)

    def nbrEvidence(self) -> "gum::Size":
        r"""
        nbrEvidence(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrEvidence(self)

    def nbrHardEvidence(self) -> "gum::Size":
        r"""
        nbrHardEvidence(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of hard evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrHardEvidence(self)

    def nbrSoftEvidence(self) -> "gum::Size":
        r"""
        nbrSoftEvidence(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of soft evidence entered into the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrSoftEvidence(self)

    def eraseAllTargets(self) -> "void":
        r"""
        eraseAllTargets(LoopyBeliefPropagation self)

        Clear all previously defined targets (marginal and joint targets).

        As a result, no posterior can be computed (since we can only compute the posteriors of the marginal or joint targets that have been added by the user).

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseAllTargets(self)

    def addAllTargets(self) -> "void":
        r"""
        addAllTargets(LoopyBeliefPropagation self)

        Add all the nodes as targets.

        """
        return _pyAgrum.LoopyBeliefPropagation_addAllTargets(self)

    def addTarget(self, *args) -> "void":
        r"""
        addTarget(LoopyBeliefPropagation self, gum::NodeId const target)
        addTarget(LoopyBeliefPropagation self, std::string const & nodeName)

        Add a marginal target to the list of targets.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : str
          a node name

        Raises
        ------
        gum.UndefinedElement
          If target is not a NodeId in the Bayes net

        """
        return _pyAgrum.LoopyBeliefPropagation_addTarget(self, *args)

    def eraseTarget(self, *args) -> "void":
        r"""
        eraseTarget(LoopyBeliefPropagation self, gum::NodeId const target)
        eraseTarget(LoopyBeliefPropagation self, std::string const & nodeName)

        Remove, if existing, the marginal target.

        Parameters
        ----------
        target : int
          a node Id
        nodeName : int
          a node name

        Raises
        ------
        gum.IndexError
          If one of the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_eraseTarget(self, *args)

    def isTarget(self, *args) -> "bool":
        r"""
        isTarget(LoopyBeliefPropagation self, gum::NodeId const variable) -> bool
        isTarget(LoopyBeliefPropagation self, std::string const & nodeName) -> bool

        Parameters
        ----------
        variable : int
         a node Id
        nodeName : str
          a node name

        Returns
        -------
        bool
          True if variable is a (marginal) target

        Raises
        ------
        gum.IndexError
          If the node does not belong to the Bayesian network
        gum.UndefinedElement
          If node Id is not in the Bayesian network

        """
        return _pyAgrum.LoopyBeliefPropagation_isTarget(self, *args)

    def nbrTargets(self) -> "gum::Size":
        r"""
        nbrTargets(LoopyBeliefPropagation self) -> gum::Size

        Returns
        -------
        int
          the number of marginal targets

        """
        return _pyAgrum.LoopyBeliefPropagation_nbrTargets(self)

    def H(self, *args) -> "double":
        r"""
        H(LoopyBeliefPropagation self, gum::NodeId const X) -> double
        H(LoopyBeliefPropagation self, std::string const & nodeName) -> double

        Parameters
        ----------
        X : int
          a node Id
        nodeName : str
          a node name

        Returns
        -------
        double
          the computed Shanon's entropy of a node given the observation

        """
        return _pyAgrum.LoopyBeliefPropagation_H(self, *args)

    def evidenceImpact(self, *args) -> "gum::Potential< double >":
        r"""
        evidenceImpact(LoopyBeliefPropagation self, gum::NodeId target, PyObject * evs) -> Potential
        evidenceImpact(LoopyBeliefPropagation self, std::string const & target, Vector_string evs) -> Potential

        Create a pyAgrum.Potential for P(target|evs) (for all instanciation of target and evs)

        Parameters
        ----------
        target : set
          a set of targets ids or names.
        evs : set
          a set of nodes ids or names.

        Warnings
        --------
        if some evs are d-separated, they are not included in the Potential.

        Returns
        -------
        pyAgrum.Potential
          a Potential for P(targets|evs)

        """
        return _pyAgrum.LoopyBeliefPropagation_evidenceImpact(self, *args)

# Register LoopyBeliefPropagation in _pyAgrum:
_pyAgrum.LoopyBeliefPropagation_swigregister(LoopyBeliefPropagation)

class ExactBNdistance(object):
    r"""



    Class representing exacte computation of divergence and distance between BNs

    Available constructors :

    	``ExactBNdistance(P,Q) -> ExactBNdistance``

    	``ExactBNdistance(ebnd) -> ExactBNdistance``

    Parameters
    ----------
    P : pyAgrum.IBayesNet
    	a Bayesian network
    Q : pyAgrum.IBayesNet
    	anotre Bayesian network
    ebnd : pyAgrum.ExactBNdistance
    	the exact BNdistance to copy

    Raises
    ------
    gum.OperationNotAllowed
    	If the 2BNs have not the same domain size of compatible node sets

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(ExactBNdistance self, IBayesNet P, IBayesNet Q) -> ExactBNdistance
        __init__(ExactBNdistance self, gum::BNdistance< double > const & kl) -> ExactBNdistance
        """
        _pyAgrum.ExactBNdistance_swiginit(self, _pyAgrum.new_ExactBNdistance(*args))
    __swig_destroy__ = _pyAgrum.delete_ExactBNdistance

    def compute(self) -> "PyObject *":
        r"""
        compute(ExactBNdistance self) -> PyObject *

        Returns
        -------
        dict
        	a dictionnary containing the different values after the computation.

        """
        return _pyAgrum.ExactBNdistance_compute(self)

# Register ExactBNdistance in _pyAgrum:
_pyAgrum.ExactBNdistance_swigregister(ExactBNdistance)

class GibbsBNdistance(ApproximationScheme):
    r"""



    Class representing a Gibbs-Approximated computation of divergence and distance between BNs

    Available constructors :

    	``GibbsBNdistance(P,Q) -> GibbsBNdistance``

    	``GibbsBNdistance(gbnd) -> GibbsBNdistance``

    Parameters
    ----------
    P : pyAgrum.IBayesNet
    	a Bayesian network
    Q : pyAgrum.IBayesNet
    	anotre Bayesian network
    gbnd : pyAgrum.GibbsBNdistance
    	the Gibbs BNdistance to copy

    Raises
    ------
    gum.OperationNotAllowed
    	If the 2BNs have not the same domain size of compatible node sets

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(GibbsBNdistance self, IBayesNet P, IBayesNet Q) -> GibbsBNdistance
        __init__(GibbsBNdistance self, gum::BNdistance< double > const & kl) -> GibbsBNdistance
        """
        _pyAgrum.GibbsBNdistance_swiginit(self, _pyAgrum.new_GibbsBNdistance(*args))
    __swig_destroy__ = _pyAgrum.delete_GibbsBNdistance

    def setBurnIn(self, b: 'gum::Size') -> "void":
        r"""
        setBurnIn(GibbsBNdistance self, gum::Size b)

        Parameters
        ----------
        b : int
        	size of burn in on number of iteration

        """
        return _pyAgrum.GibbsBNdistance_setBurnIn(self, b)

    def burnIn(self) -> "gum::Size":
        r"""
        burnIn(GibbsBNdistance self) -> gum::Size

        Returns
        -------
        int
        	size of burn in on number of iteration

        """
        return _pyAgrum.GibbsBNdistance_burnIn(self)

    def compute(self) -> "PyObject *":
        r"""
        compute(GibbsBNdistance self) -> PyObject *

        Returns
        -------
        dict
        	a dictionnary containing the different values after the computation.

        """
        return _pyAgrum.GibbsBNdistance_compute(self)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(GibbsBNdistance self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.GibbsBNdistance_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(GibbsBNdistance self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.GibbsBNdistance_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(GibbsBNdistance self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.GibbsBNdistance_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(GibbsBNdistance self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.GibbsBNdistance_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(GibbsBNdistance self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.GibbsBNdistance_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(GibbsBNdistance self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsBNdistance_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(GibbsBNdistance self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.GibbsBNdistance_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(GibbsBNdistance self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.GibbsBNdistance_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(GibbsBNdistance self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.GibbsBNdistance_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(GibbsBNdistance self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.GibbsBNdistance_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(GibbsBNdistance self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.GibbsBNdistance_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(GibbsBNdistance self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.GibbsBNdistance_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(GibbsBNdistance self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.GibbsBNdistance_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(GibbsBNdistance self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.GibbsBNdistance_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(GibbsBNdistance self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.GibbsBNdistance_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(GibbsBNdistance self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.GibbsBNdistance_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(GibbsBNdistance self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.GibbsBNdistance__asIApproximationSchemeConfiguration(self)

    def nbrDrawnVar(self) -> "gum::Size":
        r"""
        nbrDrawnVar(GibbsBNdistance self) -> gum::Size

        Returns
        -------
        int
          the number of variable drawn at each iteration

        """
        return _pyAgrum.GibbsBNdistance_nbrDrawnVar(self)

    def setNbrDrawnVar(self, _nbr: 'gum::Size') -> "void":
        r"""
        setNbrDrawnVar(GibbsBNdistance self, gum::Size _nbr)

        Parameters
        ----------
        _nbr : int
          the number of variables to be drawn at each iteration

        """
        return _pyAgrum.GibbsBNdistance_setNbrDrawnVar(self, _nbr)

    def isDrawnAtRandom(self) -> "bool":
        r"""
        isDrawnAtRandom(GibbsBNdistance self) -> bool

        Returns
        -------
        bool
          True if variables are drawn at random

        """
        return _pyAgrum.GibbsBNdistance_isDrawnAtRandom(self)

    def setDrawnAtRandom(self, _atRandom: 'bool') -> "void":
        r"""
        setDrawnAtRandom(GibbsBNdistance self, bool _atRandom)

        Parameters
        ----------
        _atRandom : bool
          indicates if variables should be drawn at random

        """
        return _pyAgrum.GibbsBNdistance_setDrawnAtRandom(self, _atRandom)

# Register GibbsBNdistance in _pyAgrum:
_pyAgrum.GibbsBNdistance_swigregister(GibbsBNdistance)

class CredalNet(object):
    r"""



    Constructor used to create a CredalNet (step by step or with two BayesNet)

    Available constructors:
        ``CredalNet() -> CredalNet``

        ``CredalNet(src_min_num,src_max_den) -> CredalNet``

        ``CredalNet(src_min_num,src_max_den) -> CredalNet``

    Parameters
    ----------
    src_min_num
    	(str) the path to a BayesNet which contains lower probabilities.
    src_max_den
    	(str) the (optional) path to a BayesNet which contains upper probabilities.
    src_min_num
    	(pyAgrum.BayesNet) the BayesNet which contains lower probabilities.
    src_max_den
    	(pyAgrum.BayesNet) the (optional) BayesNet which contains upper probabilities. 

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    NodeType_Precise = _pyAgrum.CredalNet_NodeType_Precise
    
    NodeType_Credal = _pyAgrum.CredalNet_NodeType_Credal
    
    NodeType_Vacuous = _pyAgrum.CredalNet_NodeType_Vacuous
    
    NodeType_Indic = _pyAgrum.CredalNet_NodeType_Indic
    

    def __init__(self, *args):
        r"""
        __init__(CredalNet self) -> CredalNet
        __init__(CredalNet self, std::string const & src_min_num, std::string const & src_max_den="") -> CredalNet
        __init__(CredalNet self, BayesNet src_min_num, BayesNet src_max_den=gum::BayesNet()) -> CredalNet
        """
        _pyAgrum.CredalNet_swiginit(self, _pyAgrum.new_CredalNet(*args))
    __swig_destroy__ = _pyAgrum.delete_CredalNet

    def addVariable(self, name: 'std::string const &', card: 'gum::Size const &') -> "gum::NodeId":
        r"""
        addVariable(CredalNet self, std::string const & name, gum::Size const & card) -> gum::NodeId

        Parameters
        ----------
        name : str
        	the name of the new variable
        card: int
            the domainSize of the new variable

        Returns
        -------
        int
        	the id of the new node

        """
        return _pyAgrum.CredalNet_addVariable(self, name, card)

    def addArc(self, tail: 'gum::NodeId const &', head: 'gum::NodeId const &') -> "void":
        r"""
        addArc(CredalNet self, gum::NodeId const & tail, gum::NodeId const & head)

        Adds an arc between two nodes

        Parameters
        ----------
        tail :
        	the id of the tail node
        head : int 
        	the id of the head node

        Raises
        ------
        gum.InvalidDirectedCircle
        	If any (directed) cycle is created by this arc
        gum.InvalidNode
        	If head or tail does not belong to the graph nodes
        gum.DuplicateElement
        	If one of the arc already exists

        """
        return _pyAgrum.CredalNet_addArc(self, tail, head)

    def setCPTs(self, id: 'gum::NodeId const &', cpt: 'std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > const &') -> "void":
        r"""
        setCPTs(CredalNet self, gum::NodeId const & id, std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > const & cpt)

        Warnings
        --------
        (experimental function) - Parameters to be wrapped


        Set the vertices of the credal sets (all of the conditionals) of a given node

        Parameters
        ----------
        id : int
        	the NodeId of the node
        cpt	: tbw 
        	the vertices of every credal set (for each instantiation of the parents)

        Warning
        -------
        DOES not change the BayesNet (s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_setCPTs(self, id, cpt)

    def setCPT(self, *args) -> "void":
        r"""
        setCPT(CredalNet self, gum::NodeId const & id, gum::Size & entry, std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const & cpt)
        setCPT(CredalNet self, gum::NodeId const & id, Instantiation ins, std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const & cpt)

        Warnings
        --------
        (experimental function) - Parameters to be wrapped


        Set the vertices of one credal set of a given node (any instantiation index)

        Parameters
        ----------
        id : int
        	the Id of the node
        entry : int
        	the index of the instantiation (from 0 to K - 1) excluding the given node (only the parents are used to compute the index of the credal set)
        ins : pyAgrum.Instantiation
        	the Instantiation (only the parents matter to find the credal set index) 
        cpt	: tbw
        	the vertices of every credal set (for each instantiation of the parents)

        Warnings
        --------
        DOES not change the BayesNet(s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_setCPT(self, *args)

    def fillConstraints(self, id: 'gum::NodeId const &', lower: 'Vector', upper: 'Vector') -> "void":
        r"""
        fillConstraints(CredalNet self, gum::NodeId const & id, Vector lower, Vector upper)

        Set the interval constraints of the credal sets of a given node (all instantiations) 

        Parameters
        ----------
        id : int 
        	The id of the node
        lower : list
        	The lower value for each probability in correct order
        upper : list
        	The upper value for each probability in correct order

        Warnings
        --------
        You need to call intervalToCredal when done filling all constraints.

        Warning
        -------
        DOES change the BayesNet (s) associated to this credal net !

        """
        return _pyAgrum.CredalNet_fillConstraints(self, id, lower, upper)

    def fillConstraint(self, *args) -> "void":
        r"""
        fillConstraint(CredalNet self, gum::NodeId const & id, gum::Idx const & entry, Vector lower, Vector upper)
        fillConstraint(CredalNet self, gum::NodeId const & id, Instantiation ins, Vector lower, Vector upper)

        Set the interval constraints of a credal set of a given node (from an instantiation index)

        Parameters
        ----------
        id : int 
        	The id of the node
        entry : int
        	The index of the instantiation excluding the given node (only the parents are used to compute the index of the credal set)
        ins : pyAgrum.Instantiation
        	The Instantiation
        lower : list
        	The lower value for each probability in correct order
        upper : list
        	The upper value for each probability in correct order

        Warnings
        --------
        You need to call intervalToCredal when done filling all constraints.

        Warning
        -------
        DOES change the BayesNet (s) associated to this credal net ! 

        """
        return _pyAgrum.CredalNet_fillConstraint(self, *args)

    def instantiation(self, id: 'gum::NodeId const &') -> "gum::Instantiation":
        r"""
        instantiation(CredalNet self, gum::NodeId const & id) -> Instantiation

        Get an Instantiation from a node id, usefull to fill the constraints of the network.

        bnet accessors / shortcuts.

        Parameters
        ----------
        id : int
        	the id of the node we want an instantiation from

        Returns
        -------
        pyAgrum.Instantiation
            the instantiation 

        """
        return _pyAgrum.CredalNet_instantiation(self, id)

    def domainSize(self, id: 'gum::NodeId const &') -> "gum::Size":
        r"""
        domainSize(CredalNet self, gum::NodeId const & id) -> gum::Size

        Parameters
        ----------
        id : int
        	The id of the node

        Returns
        -------
        int
            The cardinality of the node 

        """
        return _pyAgrum.CredalNet_domainSize(self, id)

    def bnToCredal(self, beta: 'double const', oneNet: 'bool const', keepZeroes: 'bool const'=False) -> "void":
        r"""
        bnToCredal(CredalNet self, double const beta, bool const oneNet, bool const keepZeroes=False)

        Perturbates the BayesNet provided as input for this CredalNet by generating intervals instead of point probabilities and then computes each vertex of each credal set.

        Parameters
        ----------
        beta : double
        	The beta used to perturbate the network
        oneNet : bool
        	used as a flag. Set to True if one BayesNet if provided with counts, to False if two BayesNet are provided; one with probabilities (the lower net) and one with denominators over the first modalities (the upper net)
        keepZeroes : bool
        	used as a flag as whether or not - respectively True or False - we keep zeroes as zeroes. Default is False, i.e. zeroes are not kept

        """
        return _pyAgrum.CredalNet_bnToCredal(self, beta, oneNet, keepZeroes)

    def intervalToCredalWithFiles(self) -> "void":
        r"""
        intervalToCredalWithFiles(CredalNet self)

        Warnings
        --------
        Deprecated : use intervalToCredal (lrsWrapper with no input / output files needed).


        Computes the vertices of each credal set according to their interval definition (uses lrs).

        Use this method when using a single BayesNet storing counts of events. 

        """
        return _pyAgrum.CredalNet_intervalToCredalWithFiles(self)

    def intervalToCredal(self) -> "void":
        r"""
        intervalToCredal(CredalNet self)

        Computes the vertices of each credal set according to their interval definition (uses lrs).

        Use this method when using two BayesNet, one with lower probabilities and one with upper probabilities.

        """
        return _pyAgrum.CredalNet_intervalToCredal(self)

    def lagrangeNormalization(self) -> "void":
        r"""
        lagrangeNormalization(CredalNet self)

        Normalize counts of a BayesNet storing counts of each events such that no probability is 0.

        Use this method when using a single BayesNet storing counts of events. Lagrange normalization. This call is irreversible and modify counts stored by __src_bn.

        Doest not performs computations of the parameters but keeps normalized counts of events only. Call idmLearning to compute the probabilities (with any parameter value). 

        """
        return _pyAgrum.CredalNet_lagrangeNormalization(self)

    def idmLearning(self, s: 'gum::Idx const'=0, keepZeroes: 'bool const'=False) -> "void":
        r"""
        idmLearning(CredalNet self, gum::Idx const s=0, bool const keepZeroes=False)

        Learns parameters from a BayesNet storing counts of events.

        Use this method when using a single BayesNet storing counts of events. IDM model if s > 0, standard point probability if s = 0 (default value if none precised).

        Parameters
        ----------
        s : int
        	the IDM parameter.
        keepZeroes : bool
        	used as a flag as whether or not - respectively True or False - we keep zeroes as zeroes. Default is False, i.e. zeroes are not kept. 

        """
        return _pyAgrum.CredalNet_idmLearning(self, s, keepZeroes)

    def approximatedBinarization(self) -> "void":
        r"""
        approximatedBinarization(CredalNet self)

        Approximate binarization.

        Each bit has a lower and upper probability which is the lowest - resp. highest - over all vertices of the credal set. Enlarge the orignal credal sets and may induce huge imprecision.

        Warnings
        --------
        Enlarge the orignal credal sets and therefor induce huge imprecision by propagation. Not recommended, use MCSampling or something else instead

        """
        return _pyAgrum.CredalNet_approximatedBinarization(self)

    def saveBNsMinMax(self, min_path: 'std::string const &', max_path: 'std::string const &') -> "void":
        r"""
        saveBNsMinMax(CredalNet self, std::string const & min_path, std::string const & max_path)

        If this CredalNet was built over a perturbed BayesNet, one can save the intervals as two BayesNet.

        to call after bnToCredal(GUM_SCALAR beta) save a BN with lower probabilities and a BN with upper ones

        Parameters
        ----------
        min_path : str
        	the path to save the BayesNet which contains the lower probabilities of each node X.
        max_path : str
        	the path to save the BayesNet which contains the upper probabilities of each node X.

        """
        return _pyAgrum.CredalNet_saveBNsMinMax(self, min_path, max_path)

    def computeCPTMinMax(self) -> "void":
        r"""
        computeCPTMinMax(CredalNet self)

        Used with binary networks to speed-up L2U inference.

        Store the lower and upper probabilities of each node X over the 'True' modality.

        """
        return _pyAgrum.CredalNet_computeCPTMinMax(self)

    def src_bn(self) -> "gum::BayesNet< double > const &":
        r"""
        src_bn(CredalNet self) -> BayesNet

        Returns
        -------
        pyAgrum.BayesNet
            Returns a constant reference to the original BayesNet (used as a DAG, it's CPTs does not matter). 

        """
        return _pyAgrum.CredalNet_src_bn(self)

    def current_bn(self) -> "gum::BayesNet< double > const &":
        r"""
        current_bn(CredalNet self) -> BayesNet

        Returns
        -------
        pyAgrum.BayesNet
            Returs a constant reference to the actual BayesNet (used as a DAG, it's CPTs does not matter). 

        """
        return _pyAgrum.CredalNet_current_bn(self)

    def credalNet_currentCpt(self) -> "gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &":
        r"""
        credalNet_currentCpt(CredalNet self) -> gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
            a constant reference to the (up-to-date) CredalNet CPTs.

        """
        return _pyAgrum.CredalNet_credalNet_currentCpt(self)

    def credalNet_srcCpt(self) -> "gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &":
        r"""
        credalNet_srcCpt(CredalNet self) -> gum::NodeProperty< std::vector< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > >,std::allocator< std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
            a constant reference to the (up-to-date) CredalNet CPTs.

        """
        return _pyAgrum.CredalNet_credalNet_srcCpt(self)

    def currentNodeType(self, id: 'gum::NodeId const &') -> "gum::credal::CredalNet< double >::NodeType":
        r"""
        currentNodeType(CredalNet self, gum::NodeId const & id) -> gum::credal::CredalNet< double >::NodeType

        Parameters
        ----------
        id : int 
        	The constant reference to the choosen NodeId

        Returns
        -------
        pyAgrum.CredalNet
            the type of the choosen node in the (up-to-date) CredalNet __current_bn if any, __src_bn otherwise. 

        """
        return _pyAgrum.CredalNet_currentNodeType(self, id)

    def nodeType(self, id: 'gum::NodeId const &') -> "gum::credal::CredalNet< double >::NodeType":
        r"""
        nodeType(CredalNet self, gum::NodeId const & id) -> gum::credal::CredalNet< double >::NodeType

        Parameters
        ----------
        id : int
        	the constant reference to the choosen NodeId

        Returns
        -------
        pyAgrum.CredalNet
        	the type of the choosen node in the (up-to-date) CredalNet in __src_bn. 

        """
        return _pyAgrum.CredalNet_nodeType(self, id)

    def epsilonMin(self) -> "double const &":
        r"""
        epsilonMin(CredalNet self) -> double const &

        Returns
        -------
        double
            a constant reference to the lowest perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMin(self)

    def epsilonMax(self) -> "double const &":
        r"""
        epsilonMax(CredalNet self) -> double const &

        Returns
        -------
        double
            a constant reference to the highest perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMax(self)

    def epsilonMean(self) -> "double const &":
        r"""
        epsilonMean(CredalNet self) -> double const &

        Returns
        -------
        double
            a constant reference to the average perturbation of the BayesNet provided as input for this CredalNet. 

        """
        return _pyAgrum.CredalNet_epsilonMean(self)

    def isSeparatelySpecified(self) -> "bool const":
        r"""
        isSeparatelySpecified(CredalNet self) -> bool const

        Returns
        -------
        bool
        	True if this CredalNet is separately and interval specified, False otherwise. 

        """
        return _pyAgrum.CredalNet_isSeparatelySpecified(self)

    def hasComputedCPTMinMax(self) -> "bool const":
        r"""
        hasComputedCPTMinMax(CredalNet self) -> bool const

        Returns
        -------
        bool
            True this CredalNet has called computeCPTMinMax() to speed-up inference with binary networks and L2U.

        """
        return _pyAgrum.CredalNet_hasComputedCPTMinMax(self)

    def get_CPT_min(self) -> "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &":
        r"""
        get_CPT_min(CredalNet self) -> std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
        	a constant reference to the lower probabilities of each node X over the 'True' modality

        """
        return _pyAgrum.CredalNet_get_CPT_min(self)

    def get_CPT_max(self) -> "std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &":
        r"""
        get_CPT_max(CredalNet self) -> std::vector< std::vector< double,std::allocator< double > >,std::allocator< std::vector< double,std::allocator< double > > > > const &

        Warnings
        --------
        Experimental function - Return type to be wrapped

        Returns
        -------
        tbw
        	a constant reference to the upper probabilities of each node X over the 'True' modality

        """
        return _pyAgrum.CredalNet_get_CPT_max(self)

    def __repr__(self) -> "std::string":
        r"""__repr__(CredalNet self) -> std::string"""
        return _pyAgrum.CredalNet___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(CredalNet self) -> std::string"""
        return _pyAgrum.CredalNet___str__(self)

# Register CredalNet in _pyAgrum:
_pyAgrum.CredalNet_swigregister(CredalNet)

class CNMonteCarloSampling(object):
    r"""



    Class used for inferences in credal networks with Monte Carlo sampling algorithm.

    Available constructors:

        ``CNMonteCarloSampling(cn) -> CNMonteCarloSampling``

    Parameters
    ----------
    cn: pyAgrum.CredalNet
      a Credal network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, credalNet: 'CredalNet'):
        r"""__init__(CNMonteCarloSampling self, CredalNet credalNet) -> CNMonteCarloSampling"""
        _pyAgrum.CNMonteCarloSampling_swiginit(self, _pyAgrum.new_CNMonteCarloSampling(credalNet))
    __swig_destroy__ = _pyAgrum.delete_CNMonteCarloSampling

    def makeInference(self) -> "void":
        r"""
        makeInference(CNMonteCarloSampling self)

        Starts the inference.

        """
        return _pyAgrum.CNMonteCarloSampling_makeInference(self)

    def insertEvidenceFile(self, path: 'std::string const &') -> "void":
        r"""
        insertEvidenceFile(CNMonteCarloSampling self, std::string const & path)

        Insert evidence from file.

        Parameters
        ----------
        path : str
        	the path to the evidence file. 

        """
        return _pyAgrum.CNMonteCarloSampling_insertEvidenceFile(self, path)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(CNMonteCarloSampling self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.CNMonteCarloSampling_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(CNMonteCarloSampling self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.CNMonteCarloSampling_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(CNMonteCarloSampling self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.CNMonteCarloSampling_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(CNMonteCarloSampling self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.CNMonteCarloSampling_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(CNMonteCarloSampling self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.CNMonteCarloSampling_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(CNMonteCarloSampling self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNMonteCarloSampling_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(CNMonteCarloSampling self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.CNMonteCarloSampling_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(CNMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.CNMonteCarloSampling_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(CNMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.CNMonteCarloSampling_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(CNMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.CNMonteCarloSampling_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(CNMonteCarloSampling self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.CNMonteCarloSampling_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(CNMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNMonteCarloSampling_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(CNMonteCarloSampling self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.CNMonteCarloSampling_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(CNMonteCarloSampling self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.CNMonteCarloSampling_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(CNMonteCarloSampling self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.CNMonteCarloSampling_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(CNMonteCarloSampling self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.CNMonteCarloSampling_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(CNMonteCarloSampling self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.CNMonteCarloSampling__asIApproximationSchemeConfiguration(self)

    def setRepetitiveInd(self, flag: 'bool const') -> "void":
        r"""
        setRepetitiveInd(CNMonteCarloSampling self, bool const flag)

        Parameters
        ----------
        flag : bool
        	True if repetitive independence is to be used, false otherwise. Only usefull with dynamic networks. 

        """
        return _pyAgrum.CNMonteCarloSampling_setRepetitiveInd(self, flag)

    def marginalMax(self, *args) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        marginalMax(CNMonteCarloSampling self, gum::NodeId const id) -> Vector
        marginalMax(CNMonteCarloSampling self, std::string const name) -> Vector

        Get the upper marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which upper marginals we want.
        varName : str
        	the variable name which upper marginals we want. 

        Returns
        -------
        list
            a constant reference to this node upper marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNMonteCarloSampling_marginalMax(self, *args)

    def marginalMin(self, *args) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        marginalMin(CNMonteCarloSampling self, gum::NodeId const id) -> Vector
        marginalMin(CNMonteCarloSampling self, std::string const name) -> Vector

        Get the lower marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which lower marginals we want.
        varName : str
        	the variable name which lower marginals we want. 

        Returns
        -------
        list
            a constant reference to this node lower marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNMonteCarloSampling_marginalMin(self, *args)

    def insertModalsFile(self, path: 'std::string const &') -> "void":
        r"""
        insertModalsFile(CNMonteCarloSampling self, std::string const & path)

        Insert variables modalities from file to compute expectations.

        Parameters
        ----------
        path : str
        	The path to the modalities file. 

        """
        return _pyAgrum.CNMonteCarloSampling_insertModalsFile(self, path)

    def dynamicExpMax(self, varName: 'std::string const &') -> "std::vector< double,std::allocator< double > > const &":
        r"""
        dynamicExpMax(CNMonteCarloSampling self, std::string const & varName) -> Vector

        Get the upper dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which upper expectation we want.

        Returns
        -------
        double
            a constant reference to the variable upper expectation over all time steps. 

        """
        return _pyAgrum.CNMonteCarloSampling_dynamicExpMax(self, varName)

    def dynamicExpMin(self, varName: 'std::string const &') -> "std::vector< double,std::allocator< double > > const &":
        r"""
        dynamicExpMin(CNMonteCarloSampling self, std::string const & varName) -> Vector

        Get the lower dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which lower expectation we want.

        Returns
        -------
        double
            a constant reference to the variable lower expectation over all time steps. 

        """
        return _pyAgrum.CNMonteCarloSampling_dynamicExpMin(self, varName)

# Register CNMonteCarloSampling in _pyAgrum:
_pyAgrum.CNMonteCarloSampling_swigregister(CNMonteCarloSampling)

class CNLoopyPropagation(object):
    r"""



    Class used for inferences in credal networks with Loopy Propagation algorithm.

    Available constructors:

        ``CNLoopyPropagation(cn) -> CNLoopyPropagation``

    Parameters
    ----------
    cn: pyAgrum.CredalNet
      a Credal network

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr
    InferenceType_nodeToNeighbours = _pyAgrum.CNLoopyPropagation_InferenceType_nodeToNeighbours
    
    InferenceType_ordered = _pyAgrum.CNLoopyPropagation_InferenceType_ordered
    
    InferenceType_randomOrder = _pyAgrum.CNLoopyPropagation_InferenceType_randomOrder
    

    def makeInference(self) -> "void":
        r"""
        makeInference(CNLoopyPropagation self)

        Starts the inference.

        """
        return _pyAgrum.CNLoopyPropagation_makeInference(self)

    def inferenceType(self, *args) -> "gum::credal::CNLoopyPropagation< double >::InferenceType":
        r"""
        inferenceType(CNLoopyPropagation self, gum::credal::CNLoopyPropagation< double >::InferenceType inft)
        inferenceType(CNLoopyPropagation self) -> gum::credal::CNLoopyPropagation< double >::InferenceType

        Returns
        -------
        int
        	the inference type

        """
        return _pyAgrum.CNLoopyPropagation_inferenceType(self, *args)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(CNLoopyPropagation self)

        Erase all inference related data to perform another one.

        You need to insert evidence again if needed but modalities are kept. You can insert new ones by using the appropriate method which will delete the old ones.

        """
        return _pyAgrum.CNLoopyPropagation_eraseAllEvidence(self)

    def saveInference(self, path: 'std::string const &') -> "void":
        r"""
        saveInference(CNLoopyPropagation self, std::string const & path)

        Saves marginals.

        Parameters
        ----------
        path : str
        	The path to the file to save marginals. 

        """
        return _pyAgrum.CNLoopyPropagation_saveInference(self, path)

    def __init__(self, cnet: 'CredalNet'):
        r"""__init__(CNLoopyPropagation self, CredalNet cnet) -> CNLoopyPropagation"""
        _pyAgrum.CNLoopyPropagation_swiginit(self, _pyAgrum.new_CNLoopyPropagation(cnet))
    __swig_destroy__ = _pyAgrum.delete_CNLoopyPropagation

    def insertEvidenceFile(self, path: 'std::string const &') -> "void":
        r"""
        insertEvidenceFile(CNLoopyPropagation self, std::string const & path)

        Insert evidence from file.

        Parameters
        ----------
        path : str
        	the path to the evidence file. 

        """
        return _pyAgrum.CNLoopyPropagation_insertEvidenceFile(self, path)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(CNLoopyPropagation self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.CNLoopyPropagation_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(CNLoopyPropagation self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.CNLoopyPropagation_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(CNLoopyPropagation self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.CNLoopyPropagation_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(CNLoopyPropagation self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.CNLoopyPropagation_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(CNLoopyPropagation self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.CNLoopyPropagation_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(CNLoopyPropagation self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNLoopyPropagation_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(CNLoopyPropagation self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.CNLoopyPropagation_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(CNLoopyPropagation self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.CNLoopyPropagation_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(CNLoopyPropagation self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.CNLoopyPropagation_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(CNLoopyPropagation self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.CNLoopyPropagation_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(CNLoopyPropagation self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.CNLoopyPropagation_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(CNLoopyPropagation self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.CNLoopyPropagation_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(CNLoopyPropagation self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.CNLoopyPropagation_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(CNLoopyPropagation self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.CNLoopyPropagation_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(CNLoopyPropagation self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.CNLoopyPropagation_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(CNLoopyPropagation self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.CNLoopyPropagation_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(CNLoopyPropagation self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.CNLoopyPropagation__asIApproximationSchemeConfiguration(self)

    def setRepetitiveInd(self, flag: 'bool const') -> "void":
        r"""
        setRepetitiveInd(CNLoopyPropagation self, bool const flag)

        Parameters
        ----------
        flag : bool
        	True if repetitive independence is to be used, false otherwise. Only usefull with dynamic networks. 

        """
        return _pyAgrum.CNLoopyPropagation_setRepetitiveInd(self, flag)

    def marginalMax(self, *args) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        marginalMax(CNLoopyPropagation self, gum::NodeId const id) -> Vector
        marginalMax(CNLoopyPropagation self, std::string const name) -> Vector

        Get the upper marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which upper marginals we want.
        varName : str
        	the variable name which upper marginals we want. 

        Returns
        -------
        list
            a constant reference to this node upper marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNLoopyPropagation_marginalMax(self, *args)

    def marginalMin(self, *args) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        marginalMin(CNLoopyPropagation self, gum::NodeId const id) -> Vector
        marginalMin(CNLoopyPropagation self, std::string const name) -> Vector

        Get the lower marginals of a given node id.

        Parameters
        ----------
        id : int
        	the node id which lower marginals we want.
        varName : str
        	the variable name which lower marginals we want. 

        Returns
        -------
        list
            a constant reference to this node lower marginals.

        Raises
        ------
        gum.IndexError
        	If the node does not belong to the Credal network

        """
        return _pyAgrum.CNLoopyPropagation_marginalMin(self, *args)

    def insertModalsFile(self, path: 'std::string const &') -> "void":
        r"""
        insertModalsFile(CNLoopyPropagation self, std::string const & path)

        Insert variables modalities from file to compute expectations.

        Parameters
        ----------
        path : str
        	The path to the modalities file. 

        """
        return _pyAgrum.CNLoopyPropagation_insertModalsFile(self, path)

    def dynamicExpMax(self, varName: 'std::string const &') -> "std::vector< double,std::allocator< double > > const &":
        r"""
        dynamicExpMax(CNLoopyPropagation self, std::string const & varName) -> Vector

        Get the upper dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which upper expectation we want.

        Returns
        -------
        double
            a constant reference to the variable upper expectation over all time steps. 

        """
        return _pyAgrum.CNLoopyPropagation_dynamicExpMax(self, varName)

    def dynamicExpMin(self, varName: 'std::string const &') -> "std::vector< double,std::allocator< double > > const &":
        r"""
        dynamicExpMin(CNLoopyPropagation self, std::string const & varName) -> Vector

        Get the lower dynamic expectation of a given variable prefix.

        Parameters
        ----------
        varName : str
        	the variable name prefix which lower expectation we want.

        Returns
        -------
        double
            a constant reference to the variable lower expectation over all time steps. 

        """
        return _pyAgrum.CNLoopyPropagation_dynamicExpMin(self, varName)

# Register CNLoopyPropagation in _pyAgrum:
_pyAgrum.CNLoopyPropagation_swigregister(CNLoopyPropagation)

class InfluenceDiagram(DAGmodel):
    r"""



    InfluenceDiagram represents an Influence Diagram.

    Available constructors:
        ``InfluenceDiagram() -> InfluenceDiagram``

        ``InfluenceDiagram(source) -> InfluenceDiagram``

    Parameters
    ----------
    source : pyAgrum.InfluenceDiagram
      the InfluenceDiagram to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __swig_destroy__ = _pyAgrum.delete_InfluenceDiagram

    def __init__(self, *args):
        r"""
        __init__(InfluenceDiagram self) -> InfluenceDiagram
        __init__(InfluenceDiagram self, InfluenceDiagram source) -> InfluenceDiagram
        """
        _pyAgrum.InfluenceDiagram_swiginit(self, _pyAgrum.new_InfluenceDiagram(*args))

    def toDot(self) -> "std::string":
        r"""
        toDot(InfluenceDiagram self) -> std::string

        Returns
        -------
        str
            a friendly display of the graph in DOT format

        """
        return _pyAgrum.InfluenceDiagram_toDot(self)

    def cpt(self, varId: 'gum::NodeId') -> "gum::Potential< double > const &":
        r"""
        cpt(InfluenceDiagram self, gum::NodeId varId) -> Potential

        Returns the CPT of a variable.

        Parameters
        ----------
        VarId : int
        	A variable's id in the pyAgrum.BayesNet.

        Returns
        -------
        pyAgrum.Potential
        	The variable's CPT. 

        Raises
        ------
        gum.NotFound
        	If no variable's id matches varId. 

        """
        val = _pyAgrum.InfluenceDiagram_cpt(self, varId)

        val.__fill_distrib__()


        return val


    def utility(self, varId: 'gum::NodeId') -> "gum::Potential< double > const &":
        r"""
        utility(InfluenceDiagram self, gum::NodeId varId) -> Potential

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        pyAgrum.Potential
        	the utility table of the node

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        val = _pyAgrum.InfluenceDiagram_utility(self, varId)

        val.__fill_distrib__()


        return val


    def isUtilityNode(self, varId: 'gum::NodeId') -> "bool":
        r"""
        isUtilityNode(InfluenceDiagram self, gum::NodeId varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is an utility node

        """
        return _pyAgrum.InfluenceDiagram_isUtilityNode(self, varId)

    def isDecisionNode(self, varId: 'gum::NodeId') -> "bool":
        r"""
        isDecisionNode(InfluenceDiagram self, gum::NodeId varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is a decision node

        """
        return _pyAgrum.InfluenceDiagram_isDecisionNode(self, varId)

    def isChanceNode(self, varId: 'gum::NodeId') -> "bool":
        r"""
        isChanceNode(InfluenceDiagram self, gum::NodeId varId) -> bool

        Parameters
        ----------
        varId : int 
        	the tested node id.

        Returns
        -------
        bool
        	true if node is a chance node

        """
        return _pyAgrum.InfluenceDiagram_isChanceNode(self, varId)

    def utilityNodeSize(self) -> "gum::Size":
        r"""
        utilityNodeSize(InfluenceDiagram self) -> gum::Size

        Returns
        -------
        int
        	the number of utility nodes

        """
        return _pyAgrum.InfluenceDiagram_utilityNodeSize(self)

    def chanceNodeSize(self) -> "gum::Size":
        r"""
        chanceNodeSize(InfluenceDiagram self) -> gum::Size

        Returns
        -------
        int
        	the number of chance nodes. 

        """
        return _pyAgrum.InfluenceDiagram_chanceNodeSize(self)

    def decisionNodeSize(self) -> "gum::Size":
        r"""
        decisionNodeSize(InfluenceDiagram self) -> gum::Size

        Returns
        -------
        int
        	the number of decision nodes

        """
        return _pyAgrum.InfluenceDiagram_decisionNodeSize(self)

    def variable(self, id: 'gum::NodeId') -> "gum::DiscreteVariable const &":
        r"""
        variable(InfluenceDiagram self, gum::NodeId id) -> DiscreteVariable

        Parameters
        ----------
        id : int
         	the node id

        Returns
        ------
        pyAgrum.DiscreteVariable
        	a constant reference over a variabe given it's node id

        Raises
        ------
        gum.NotFound
        	If no variable's id matches the parameter 

        """
        return _pyAgrum.InfluenceDiagram_variable(self, id)

    def nodeId(self, var: 'DiscreteVariable') -> "gum::NodeId":
        r"""
        nodeId(InfluenceDiagram self, DiscreteVariable var) -> gum::NodeId

        Parameters
        ----------
        var : pyAgrum.DiscreteVariable
        	a variable

        Returns
        -------
        int
        	the id of the variable

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        return _pyAgrum.InfluenceDiagram_nodeId(self, var)

    def idFromName(self, name: 'std::string const &') -> "gum::NodeId":
        r"""
        idFromName(InfluenceDiagram self, std::string const & name) -> gum::NodeId

        Returns a variable's id given its name.

        Parameters
        ----------
        name : str
        	the variable's name from which the id is returned.

        Returns
        -------
        int
        	the variable's node id. 

        Raises
        ------
        gum.NotFound
        	If no such name exists in the graph. 

        """
        return _pyAgrum.InfluenceDiagram_idFromName(self, name)

    def variableFromName(self, name: 'std::string const &') -> "gum::DiscreteVariable const &":
        r"""
        variableFromName(InfluenceDiagram self, std::string const & name) -> DiscreteVariable

        Parameters
        ----------
        name : str
        	a variable's name

        Returns
        -------
        pyAgrum.DiscreteVariable
        	the variable

        Raises
        ------
        gum.IndexError
        	If the InfluenceDiagram does not contain the variable

        """
        return _pyAgrum.InfluenceDiagram_variableFromName(self, name)

    def add(self, variable: 'DiscreteVariable', id: 'gum::NodeId'=0) -> "gum::NodeId":
        r"""
        add(InfluenceDiagram self, DiscreteVariable variable, gum::NodeId id=0) -> gum::NodeId

        Add a chance variable, it's associate node and it's CPT.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	The variable added by copy.
        id : int
        	The chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_add(self, variable, id)

    def addDecisionNode(self, variable: 'DiscreteVariable', id: 'gum::NodeId'=0) -> "gum::NodeId":
        r"""
        addDecisionNode(InfluenceDiagram self, DiscreteVariable variable, gum::NodeId id=0) -> gum::NodeId

        Add a decision variable.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy.
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addDecisionNode(self, variable, id)

    def addChanceNode(self, *args) -> "gum::NodeId":
        r"""
        addChanceNode(InfluenceDiagram self, DiscreteVariable variable, gum::NodeId id=0) -> gum::NodeId
        addChanceNode(InfluenceDiagram self, DiscreteVariable variable, gum::MultiDimImplementation< double > * aContent, gum::NodeId id=0) -> gum::NodeId

        Add a chance variable, it's associate node and it's CPT.

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy.
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose.

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addChanceNode(self, *args)

    def addUtilityNode(self, *args) -> "gum::NodeId":
        r"""
        addUtilityNode(InfluenceDiagram self, DiscreteVariable variable, gum::NodeId id=0) -> gum::NodeId
        addUtilityNode(InfluenceDiagram self, DiscreteVariable variable, gum::MultiDimImplementation< double > * aContent, gum::NodeId id=0) -> gum::NodeId

        Add a utility variable, it's associate node and it's UT. 

        The id of the new variable is automatically generated.

        Parameters
        ----------
        variable : pyAgrum.DiscreteVariable
        	the variable added by copy
        id : int
        	the chosen id. If 0, the NodeGraphPart will choose

        Warnings
        --------
        give an id (not 0) should be reserved for rare and specific situations !!! 

        Returns
        -------
        int
            the id of the added variable. 

        Raises
        ------
        gum.InvalidArgument
        	If variable has more than one label
        gum.DuplicateElement
        	If id(<>0) is already used 

        """
        return _pyAgrum.InfluenceDiagram_addUtilityNode(self, *args)

    def erase(self, *args) -> "void":
        r"""
        erase(InfluenceDiagram self, gum::NodeId id)
        erase(InfluenceDiagram self, DiscreteVariable var)

        Erase a Variable from the network and remove the variable from all his childs.

        If no variable matches the id, then nothing is done.

        Parameters
        ----------
        id : int
        	The id of the variable to erase.
        var : pyAgrum.DiscreteVariable
        	The reference on the variable to remove. 

        """
        return _pyAgrum.InfluenceDiagram_erase(self, *args)

    def changeVariableName(self, id: 'gum::NodeId', new_name: 'std::string const &') -> "void":
        r"""
        changeVariableName(InfluenceDiagram self, gum::NodeId id, std::string const & new_name)

        Parameters
        ----------
        id : int
        	the node Id
        new_name : str
        	the name of the variable 

        Raises
        ------
        gum.DuplicateLabel
        	If this name already exists
        gum.NotFound
        	If no nodes matches id. 

        """
        return _pyAgrum.InfluenceDiagram_changeVariableName(self, id, new_name)

    def addArc(self, tail: 'gum::NodeId', head: 'gum::NodeId') -> "void":
        r"""
        addArc(InfluenceDiagram self, gum::NodeId tail, gum::NodeId head)

        Add an arc in the ID, and update diagram's potential nodes cpt if necessary.

        Parameters
        ----------
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        Raises
        ------
        gum.InvalidEdge
        	If arc.tail and/or arc.head are not in the ID.
        gum.InvalidEdge
        	If tail is a utility node 

        """
        return _pyAgrum.InfluenceDiagram_addArc(self, tail, head)

    def eraseArc(self, *args) -> "void":
        r"""
        eraseArc(InfluenceDiagram self, Arc arc)
        eraseArc(InfluenceDiagram self, gum::NodeId tail, gum::NodeId head)

        Removes an arc in the ID, and update diagram's potential nodes cpt if necessary.

        If (tail, head) doesn't exist, the nothing happens.

        Parameters
        ----------
        arc : pyAgrum.Arc
        	The arc to be removed.
        tail : int
          the id of the tail node
        head : int
          the id of the head node

        """
        return _pyAgrum.InfluenceDiagram_eraseArc(self, *args)

    def decisionOrderExists(self) -> "bool":
        r"""
        decisionOrderExists(InfluenceDiagram self) -> bool

        Returns
        -------
        bool
        	True if a directed path exist with all decision node

        """
        return _pyAgrum.InfluenceDiagram_decisionOrderExists(self)

    def getDecisionGraph(self) -> "gum::DAG *":
        r"""
        getDecisionGraph(InfluenceDiagram self) -> DAG

        Returns
        -------
        pyAgrum.DAG
        	the temporal Graph. 

        """
        return _pyAgrum.InfluenceDiagram_getDecisionGraph(self)

    def getDecisionOrder(self) -> "std::vector< gum::NodeId,std::allocator< gum::NodeId > > *":
        r"""
        getDecisionOrder(InfluenceDiagram self) -> std::vector< gum::NodeId,std::allocator< gum::NodeId > > *

        Returns
        -------
        list
        	the sequence of decision nodes in the directed path.

        Raises
        ------
        NotFound
        	If such a path does not exist 

        """
        return _pyAgrum.InfluenceDiagram_getDecisionOrder(self)

    def existsPathBetween(self, src: 'gum::NodeId', dest: 'gum::NodeId') -> "bool":
        r"""
        existsPathBetween(InfluenceDiagram self, gum::NodeId src, gum::NodeId dest) -> bool

        Returns
        -------
        bool
        	true if a path exists between two nodes. 

        """
        return _pyAgrum.InfluenceDiagram_existsPathBetween(self, src, dest)

    def names(self) -> "PyObject *":
        r"""
        names(InfluenceDiagram self) -> PyObject *

        Returns
        -------
        list
        	The names of the InfluenceDiagram variables

        """
        return _pyAgrum.InfluenceDiagram_names(self)

    def ids(self) -> "PyObject *":
        r"""
        ids(InfluenceDiagram self) -> PyObject *

        .. note:: Deprecated in pyAgrum>0.13.0
            Please use nodes() instead

        """
        return _pyAgrum.InfluenceDiagram_ids(self)

    def arcs(self) -> "PyObject *":
        r"""
        arcs(InfluenceDiagram self) -> PyObject *

        Returns
        -------
        list:
        	the list of all the arcs in the Influence Diagram.

        """
        return _pyAgrum.InfluenceDiagram_arcs(self)

    def parents(self, id: 'gum::NodeId const') -> "PyObject *":
        r"""
        parents(InfluenceDiagram self, gum::NodeId const id) -> PyObject *

        Parameters
        ----------
        id :
        	The id of the child node

        Returns
        -------
        set
            the set of the parents ids.

        """
        return _pyAgrum.InfluenceDiagram_parents(self, id)

    def children(self, id: 'gum::NodeId const') -> "PyObject *":
        r"""
        children(InfluenceDiagram self, gum::NodeId const id) -> PyObject *

        Parameters
        ----------
        id : int
          the id of the parent

        Returns
        -------
        Set
        	the set of all the children

        """
        return _pyAgrum.InfluenceDiagram_children(self, id)

    def loadBIFXML(self, *args) -> "bool":
        r"""
        loadBIFXML(InfluenceDiagram self, std::string name, PyObject * l=(PyObject *) 0) -> bool

        Load a BIFXML file.

        Parameters
        ----------
        name : str
        	the name's file

        Raises
        ------
        gum.IOError
        	If file not found
        gum.FatalError
        	If file is not valid

        """
        return _pyAgrum.InfluenceDiagram_loadBIFXML(self, *args)

    def saveBIFXML(self, name: 'std::string') -> "void":
        r"""
        saveBIFXML(InfluenceDiagram self, std::string name)

        Save the BayesNet in a BIFXML file.

        Parameters
        ----------
        name : str
        	the file's name

        """
        return _pyAgrum.InfluenceDiagram_saveBIFXML(self, name)

    def __repr__(self) -> "std::string":
        r"""__repr__(InfluenceDiagram self) -> std::string"""
        return _pyAgrum.InfluenceDiagram___repr__(self)

    def __str__(self) -> "std::string":
        r"""__str__(InfluenceDiagram self) -> std::string"""
        return _pyAgrum.InfluenceDiagram___str__(self)

# Register InfluenceDiagram in _pyAgrum:
_pyAgrum.InfluenceDiagram_swigregister(InfluenceDiagram)

class InfluenceDiagramInference(object):
    r"""
    Proxy of C++ gum::InfluenceDiagramInference< double > class.
    Proxy of C++ gum::InfluenceDiagramInference< double > class.
    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, infDiag: 'InfluenceDiagram'):
        r"""__init__(InfluenceDiagramInference self, InfluenceDiagram infDiag) -> InfluenceDiagramInference"""
        _pyAgrum.InfluenceDiagramInference_swiginit(self, _pyAgrum.new_InfluenceDiagramInference(infDiag))
    __swig_destroy__ = _pyAgrum.delete_InfluenceDiagramInference

    def makeInference(self) -> "void":
        r"""
        makeInference(InfluenceDiagramInference self)

        Makes the inference. 

        """
        return _pyAgrum.InfluenceDiagramInference_makeInference(self)

    def getMEU(self) -> "double":
        r"""
        getMEU(InfluenceDiagramInference self) -> double

        Returns maximum expected utility obtained from inference.

        Raises
        ------
        gum.OperationNotAllowed
        	If no inference have yet been made 

        """
        return _pyAgrum.InfluenceDiagramInference_getMEU(self)

    def getBestDecisionChoice(self, decisionId: 'gum::NodeId') -> "gum::Idx":
        r"""
        getBestDecisionChoice(InfluenceDiagramInference self, gum::NodeId decisionId) -> gum::Idx

        Returns best choice for decision variable given in parameter ( based upon MEU criteria )

        Parameters
        ----------
        decisionId : int
        	the id of the decision variable

        Raises
        ------
        gum.OperationNotAllowed
        	If no inference have yet been made
        gum.InvalidNode
        	If node given in parmaeter is not a decision node 

        """
        return _pyAgrum.InfluenceDiagramInference_getBestDecisionChoice(self, decisionId)

    def displayResult(self) -> "std::string":
        r"""
        displayResult(InfluenceDiagramInference self) -> std::string

        Displays the result of an inference.

        """
        return _pyAgrum.InfluenceDiagramInference_displayResult(self)

    def insertEvidence(self, evidenceList: 'gum::List< gum::Potential< double > const * > const &') -> "void":
        r"""
        insertEvidence(InfluenceDiagramInference self, gum::List< gum::Potential< double > const * > const & evidenceList)

        Insert new evidence in the graph.

        Parameters
        ----------
        evidenceList : list
        	a list of potentials as evidences

        Warnings
        --------
        If an evidence already w.r.t. a given node and a new evidence w.r.t. this node is onserted, the old evidence is removed

        Raises
        ------
        gum.OperationNotAllowed
        	If an evidence is over more than one variable

        """
        return _pyAgrum.InfluenceDiagramInference_insertEvidence(self, evidenceList)

    def eraseEvidence(self, evidence: 'Potential') -> "void":
        r"""
        eraseEvidence(InfluenceDiagramInference self, Potential evidence)

        Parameters
        ----------
        evidence : pyAgrum.Potential
        	the evidence to remove

        Raises
        ------
        gum.IndexError
        	If the evidence does not belong to the influence diagram

        """
        return _pyAgrum.InfluenceDiagramInference_eraseEvidence(self, evidence)

    def eraseAllEvidence(self) -> "void":
        r"""
        eraseAllEvidence(InfluenceDiagramInference self)

        Removes all the evidence entered into the diagram.

        """
        return _pyAgrum.InfluenceDiagramInference_eraseAllEvidence(self)

    def displayStrongJunctionTree(self, *args) -> "void":
        r"""
        displayStrongJunctionTree(InfluenceDiagramInference self, std::ostream & stream=std::cout)

        Displays on terminal the result of strong junction tree computation for test purpose only.

        Parameters
        ----------
        args : TBW

        """
        return _pyAgrum.InfluenceDiagramInference_displayStrongJunctionTree(self, *args)

    def influenceDiagram(self) -> "gum::InfluenceDiagram< double > const &":
        r"""
        influenceDiagram(InfluenceDiagramInference self) -> InfluenceDiagram

        Returns a constant reference over the InfluenceDiagram on which this class work.

        Returns
        -------
        pyAgrum.InfluenceDiagram
        	the InfluenceDiagram on which this class work

        """
        return _pyAgrum.InfluenceDiagramInference_influenceDiagram(self)

    def setEvidence(self, evidces):
        """
        Erase all the evidences and apply addEvidence(key,value) for every pairs in evidces.

        Parameters
        ----------
        evidces : dict
          a dict of evidences

        Raises
        ------
        gum.InvalidArgument
            If one value is not a value for the node
        gum.InvalidArgument
            If the size of a value is different from the domain side of the node
        gum.FatalError
            If one value is a vector of 0s
        gum.UndefinedElement
            If one node does not belong to the Bayesian network
        """
        if not isinstance(evidces, dict):
            raise TypeError("setEvidence parameter must be dict, not %s"%(type(evidces)))
        bn = self.influenceDiagram()

    # set evidences
        self.list_pot = []

        try:
          items=evidces.iteritems()
        except AttributeError:
          items=evidces.items()

        for var_name, evidce in items:
            pot = Potential()

            if isinstance(var_name, int):
                var = bn.variable(var_name)
            elif isinstance(var_name, str):
                var = bn.variableFromName(var_name)
            else:
                raise TypeError('values of the dict must be int or string')

            pot.add(var)
            if isinstance(evidce, (int, float, str)):
                pot[:] = 0
    # determine the var type
                try:
                    cast_var = var.toLabelizedVar()
                    if isinstance(evidce, int):
                        index = evidce
                    elif isinstance(evidce, str):
                        index = cast_var[evidce]
                    else:
                        raise TypeError('values of the dict must be int or string')
                except RuntimeError:
                    try:
                        cast_var = var.toRangeVar()
                        if isinstance(evidce, int):
                            index = cast_var[str(evidce)]
                        elif isinstance(evidce, str):
                            index = cast_var[evidce]
                        else:
                            raise TypeError('values of the dict must be int or string')
                    except RuntimeError:
                        cast_var = var.toDiscretizedVar()
                        if isinstance(evidce, float):
                            index = cast_var.index(evidce)
                        elif isinstance(evidce, str):
                            index = cast_var.index(float(evidce))
                        else:
                            raise TypeError('values of the dict must be float or string')
                pot[index] = 1
            elif isinstance(evidce, (list, tuple)):
                pot[:] = evidce
            else:
                raise TypeError('dict values must be number, string or sequence')
            self.list_pot.append(pot)

        self.eraseAllEvidence()
        self._setEvidence(self.list_pot)



    def _setEvidence(self, evidences: 'PyObject *') -> "void":
        r"""_setEvidence(InfluenceDiagramInference self, PyObject * evidences)"""
        return _pyAgrum.InfluenceDiagramInference__setEvidence(self, evidences)

    def junctionTreeToDot(self) -> "std::string const":
        r"""
        junctionTreeToDot(InfluenceDiagramInference self) -> std::string const

        Returns
        -------
        str
        	the result of strong junction tree computation for test purpose only.

        """
        return _pyAgrum.InfluenceDiagramInference_junctionTreeToDot(self)

# Register InfluenceDiagramInference in _pyAgrum:
_pyAgrum.InfluenceDiagramInference_swigregister(InfluenceDiagramInference)

class BNLearner(object):
    r"""



    Available constructors:
    	``BNLearner(filename) -> BNLearner``

    	``BNLearner(filename,src,parse_database=false) -> BNLearner``

    	``BNLearner(learner) -> BNLearner``

    Parameters
    ----------
    filename: str
    	the file to learn from
    src : pyAgrum.BayesNet
    	the Bayesian network used to find those modalities
    parse_database : bool
    	if true, the modalities specified by the user will be considered as a superset of the modalities of the variables.
    learner : pyAgrum.BNLearner
    	the BNLearner to copy

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, *args):
        r"""
        __init__(BNLearner self, std::string const & filename, Vector_string missing_symbols={"?"}) -> BNLearner
        __init__(BNLearner self, gum::learning::DatabaseTable< > const & db) -> BNLearner
        __init__(BNLearner self, std::string const & filename, BayesNet src, Vector_string missing_symbols={"?"}) -> BNLearner
        __init__(BNLearner self, BNLearner arg2) -> BNLearner
        __init__(BNLearner self, BNLearner arg2) -> BNLearner
        """
        _pyAgrum.BNLearner_swiginit(self, _pyAgrum.new_BNLearner(*args))
    __swig_destroy__ = _pyAgrum.delete_BNLearner

    def learnBN(self) -> "gum::BayesNet< double >":
        r"""
        learnBN(BNLearner self) -> BayesNet

        learn a BayesNet from a file (must have read the db before)

        Returns
        -------
        pyAgrum.BayesNet
        	the learned BayesNet

        """
        return _pyAgrum.BNLearner_learnBN(self)

    def learnParameters(self, *args) -> "gum::BayesNet< double >":
        r"""
        learnParameters(BNLearner self, DAG dag, bool take_into_account_score=True) -> BayesNet
        learnParameters(BNLearner self, bool take_into_account_score=True) -> BayesNet

        learns a BN (its parameters) when its structure is known.

        Parameters
        ----------
        dag : pyAgrum.DAG
        bn : pyAgrum.BayesNet
        take_into_account_score : bool
        	The dag passed in argument may have been learnt from a structure learning. In this case, if the score used to learn the structure has an implicit apriori (like K2 which has a 1-smoothing apriori), it is important to also take into account this implicit apriori for parameter learning. By default, if a score exists, we will learn parameters by taking into account the apriori specified by methods useAprioriXXX () + the implicit apriori of the score, else we just take into account the apriori specified by useAprioriXXX ()

        Returns
        -------
        pyAgrum.BayesNet
        	the learned BayesNet

        Raises
        ------
        gum.MissingVariableInDatabase
        	If a variable of the BN is not found in the database
        gum.UnknownLabelInDatabase
        	If a label is found in the database that do not correspond to the variable

        """
        return _pyAgrum.BNLearner_learnParameters(self, *args)

    def chi2(self, *args) -> "PyObject *":
        r"""
        chi2(BNLearner self, std::string const & var1, std::string const & var2, Vector_string knw={}) -> PyObject

        chi2 computes the chi2 statistic and pvalue for two columns, given a list of other columns.


        Parameters
        ----------
        name1: str
        	the name of the first column

        name2 : str
        	the name of the second column

        knowing : [str]
        	the list of names of conditioning columns

        Returns
        -------
        statistic,pvalue
        	the chi2 statistic and the associated p-value as a Tuple

        """
        return _pyAgrum.BNLearner_chi2(self, *args)

    def G2(self, *args) -> "PyObject *":
        r"""
        G2(BNLearner self, std::string const & var1, std::string const & var2, Vector_string knw={}) -> PyObject

        G2 computes the G2 statistic and pvalue for two columns, given a list of other columns.


        Parameters
        ----------
        name1: str
        	the name of the first column

        name2 : str
        	the name of the second column

        knowing : [str]
        	the list of names of conditioning columns

        Returns
        -------
        statistic,pvalue
        	the G2 statistic and the associated p-value as a Tuple

        """
        return _pyAgrum.BNLearner_G2(self, *args)

    def setVerbosity(self, v: 'bool') -> "void":
        r"""
        setVerbosity(BNLearner self, bool v)

        Parameters
        ----------
        v : bool
                verbosity

        """
        return _pyAgrum.BNLearner_setVerbosity(self, v)

    def setEpsilon(self, eps: 'double') -> "void":
        r"""
        setEpsilon(BNLearner self, double eps)

        Parameters
        ----------
        eps : double
        	the epsilon we want to use

        Raises
        ------
        gum.OutOfLowerBound
        	If eps<0

        """
        return _pyAgrum.BNLearner_setEpsilon(self, eps)

    def setMinEpsilonRate(self, rate: 'double') -> "void":
        r"""
        setMinEpsilonRate(BNLearner self, double rate)

        Parameters
        ----------
        rate : double
        	the minimal epsilon rate

        """
        return _pyAgrum.BNLearner_setMinEpsilonRate(self, rate)

    def setMaxIter(self, max: 'gum::Size') -> "void":
        r"""
        setMaxIter(BNLearner self, gum::Size max)

        Parameters
        ----------
        max : int
        	the maximum number of iteration

        Raises
        ------
        gum.OutOfLowerBound
        	If max <= 1

        """
        return _pyAgrum.BNLearner_setMaxIter(self, max)

    def setMaxTime(self, timeout: 'double') -> "void":
        r"""
        setMaxTime(BNLearner self, double timeout)

        Parameters
        ----------
        tiemout : double
        	stopping criterion on timeout (in seconds)

        Raises
        ------
        gum.OutOfLowerBound
        	If timeout<=0.0

        """
        return _pyAgrum.BNLearner_setMaxTime(self, timeout)

    def setPeriodSize(self, p: 'gum::Size') -> "void":
        r"""
        setPeriodSize(BNLearner self, gum::Size p)

        Parameters
        ----------
        p : int
        	number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.BNLearner_setPeriodSize(self, p)

    def verbosity(self) -> "bool":
        r"""
        verbosity(BNLearner self) -> bool

        Returns
        -------
        bool
        	True if the verbosity is enabled

        """
        return _pyAgrum.BNLearner_verbosity(self)

    def epsilon(self) -> "double":
        r"""
        epsilon(BNLearner self) -> double

        Returns
        -------
        double
        	the value of epsilon

        """
        return _pyAgrum.BNLearner_epsilon(self)

    def minEpsilonRate(self) -> "double":
        r"""
        minEpsilonRate(BNLearner self) -> double

        Returns
        -------
        double
        	the value of the minimal epsilon rate

        """
        return _pyAgrum.BNLearner_minEpsilonRate(self)

    def maxIter(self) -> "gum::Size":
        r"""
        maxIter(BNLearner self) -> gum::Size

        Returns
        -------
        int
        	the criterion on number of iterations

        """
        return _pyAgrum.BNLearner_maxIter(self)

    def maxTime(self) -> "double":
        r"""
        maxTime(BNLearner self) -> double

        Returns
        -------
        double
        	the timeout(in seconds)

        """
        return _pyAgrum.BNLearner_maxTime(self)

    def periodSize(self) -> "gum::Size":
        r"""
        periodSize(BNLearner self) -> gum::Size

        Returns
        -------
        int
        	the number of samples between 2 stopping

        Raises
        ------
        gum.OutOfLowerBound
        	If p<1

        """
        return _pyAgrum.BNLearner_periodSize(self)

    def nbrIterations(self) -> "gum::Size":
        r"""
        nbrIterations(BNLearner self) -> gum::Size

        Returns
        -------
        int
        	the number of iterations

        """
        return _pyAgrum.BNLearner_nbrIterations(self)

    def currentTime(self) -> "double":
        r"""
        currentTime(BNLearner self) -> double

        Returns
        -------
        double
        	get the current running time in second (double)

        """
        return _pyAgrum.BNLearner_currentTime(self)

    def messageApproximationScheme(self) -> "std::string":
        r"""
        messageApproximationScheme(BNLearner self) -> std::string

        Returns
        -------
        str
        	the approximation scheme message

        """
        return _pyAgrum.BNLearner_messageApproximationScheme(self)

    def history(self) -> "std::vector< double,std::allocator< double > > const &":
        r"""
        history(BNLearner self) -> Vector

        Returns
        -------
        tuple
        	the scheme history

        Raises
        ------
        gum.OperationNotAllowed
        	If the scheme did not performed or if verbosity is set to false

        """
        return _pyAgrum.BNLearner_history(self)

    def _asIApproximationSchemeConfiguration(self) -> "gum::IApproximationSchemeConfiguration const &":
        r"""_asIApproximationSchemeConfiguration(BNLearner self) -> IApproximationSchemeConfiguration"""
        return _pyAgrum.BNLearner__asIApproximationSchemeConfiguration(self)

    def learnDAG(self) -> "gum::DAG":
        r"""
        learnDAG(BNLearner self) -> DAG

        learn a structure from a file

        Returns
        -------
        pyAgrum.DAG
        	the learned DAG

        """
        return _pyAgrum.BNLearner_learnDAG(self)

    def names(self) -> "std::vector< std::string,std::allocator< std::string > > const &":
        r"""
        names(BNLearner self) -> Vector_string

        Returns
        -------
        List[str]
        	the names of the variables in the database

        """
        return _pyAgrum.BNLearner_names(self)

    def idFromName(self, var_name: 'std::string const &') -> "gum::NodeId":
        r"""
        idFromName(BNLearner self, std::string const & var_name) -> gum::NodeId

        Parameters
        ----------
        var_names : str
        	a variable's name

        Returns
        -------
        int
        	the column id corresponding to a variable name

        Raises
        ------
        gum.MissingVariableInDatabase
        	If a variable of the BN is not found in the database.

        """
        return _pyAgrum.BNLearner_idFromName(self, var_name)

    def nameFromId(self, id: 'gum::NodeId') -> "std::string const &":
        r"""
        nameFromId(BNLearner self, gum::NodeId id) -> std::string const &

        Parameters
        ----------
        id
        	a node id

        Returns
        -------
        str
        	the variable's name

        """
        return _pyAgrum.BNLearner_nameFromId(self, id)

    def useScoreAIC(self) -> "void":
        r"""useScoreAIC(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreAIC(self)

    def useScoreBD(self) -> "void":
        r"""useScoreBD(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreBD(self)

    def useScoreBDeu(self) -> "void":
        r"""useScoreBDeu(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreBDeu(self)

    def useScoreBIC(self) -> "void":
        r"""useScoreBIC(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreBIC(self)

    def useScoreK2(self) -> "void":
        r"""useScoreK2(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreK2(self)

    def useScoreLog2Likelihood(self) -> "void":
        r"""useScoreLog2Likelihood(BNLearner self)"""
        return _pyAgrum.BNLearner_useScoreLog2Likelihood(self)

    def setDatabaseWeight(self, new_weight: 'double const') -> "void":
        r"""
        setDatabaseWeight(BNLearner self, double const new_weight)

        Set the database weight.

        Parameters
        ----------
        weight : double
        	the database weight

        """
        return _pyAgrum.BNLearner_setDatabaseWeight(self, new_weight)

    def setRecordWeight(self, i: 'std::size_t const', weight: 'double const') -> "void":
        r"""setRecordWeight(BNLearner self, std::size_t const i, double const weight)"""
        return _pyAgrum.BNLearner_setRecordWeight(self, i, weight)

    def databaseWeight(self) -> "double":
        r"""databaseWeight(BNLearner self) -> double"""
        return _pyAgrum.BNLearner_databaseWeight(self)

    def recordWeight(self, i: 'std::size_t const') -> "double":
        r"""recordWeight(BNLearner self, std::size_t const i) -> double"""
        return _pyAgrum.BNLearner_recordWeight(self, i)

    def useNoApriori(self) -> "void":
        r"""useNoApriori(BNLearner self)"""
        return _pyAgrum.BNLearner_useNoApriori(self)

    def useAprioriSmoothing(self, *args) -> "void":
        r"""
        useAprioriSmoothing(BNLearner self, double weight=1)
        useAprioriSmoothing(BNLearner self)
        """
        return _pyAgrum.BNLearner_useAprioriSmoothing(self, *args)

    def useAprioriDirichlet(self, *args) -> "void":
        r"""
        useAprioriDirichlet(BNLearner self, std::string const & filename, double weight=1)
        useAprioriDirichlet(BNLearner self, std::string const & filename)
        """
        return _pyAgrum.BNLearner_useAprioriDirichlet(self, *args)

    def useAprioriBDeu(self, *args) -> "void":
        r"""
        useAprioriBDeu(BNLearner self, double weight=1)
        useAprioriBDeu(BNLearner self)

        The BDeu apriori adds weight to all the cells of the counting tables.
        In other words, it adds weight rows in the database with equally probable
        values.

        Parameters
        ----------
        weight : double
        	the apriori weight

        """
        return _pyAgrum.BNLearner_useAprioriBDeu(self, *args)

    def useGreedyHillClimbing(self) -> "void":
        r"""useGreedyHillClimbing(BNLearner self)"""
        return _pyAgrum.BNLearner_useGreedyHillClimbing(self)

    def useLocalSearchWithTabuList(self, *args) -> "void":
        r"""
        useLocalSearchWithTabuList(BNLearner self, gum::Size tabu_size=100, gum::Size nb_decrease=2)
        useLocalSearchWithTabuList(BNLearner self, gum::Size tabu_size=100)
        useLocalSearchWithTabuList(BNLearner self)

        Indicate that we wish to use a local search with tabu list

        Parameters
        ----------
        tabu_size : int
                The size of the tabu list

        nb_decrease : int
                The max number of changes decreasing the score consecutively that we allow to apply

        """
        return _pyAgrum.BNLearner_useLocalSearchWithTabuList(self, *args)

    def useK2(self, *args) -> "void":
        r"""
        useK2(BNLearner self, PyObject * l)
        useK2(BNLearner self, gum::Sequence< gum::NodeId > const & order)
        useK2(BNLearner self, std::vector< gum::NodeId,std::allocator< gum::NodeId > > const & order)

        Indicate that we wish to use K2.

        Parameters
        ----------
        order : list
                a list of ids

        """
        return _pyAgrum.BNLearner_useK2(self, *args)

    def setMaxIndegree(self, max_indegree: 'gum::Size') -> "void":
        r"""setMaxIndegree(BNLearner self, gum::Size max_indegree)"""
        return _pyAgrum.BNLearner_setMaxIndegree(self, max_indegree)

    def setSliceOrder(self, *args) -> "void":
        r"""
        setSliceOrder(BNLearner self, PyObject * l)
        setSliceOrder(BNLearner self, gum::NodeProperty< gum::NodeId > const & slice_order)
        setSliceOrder(BNLearner self, std::vector< std::vector< std::string,std::allocator< std::string > >,std::allocator< std::vector< std::string,std::allocator< std::string > > > > const & slices)

        Set a partial order on the nodes.

        Parameters
        ----------
        l : list
                a list of sequences (composed of ids of rows or string)

        """
        return _pyAgrum.BNLearner_setSliceOrder(self, *args)

    def setPossibleSkeleton(self, skeleton: 'UndiGraph') -> "void":
        r"""setPossibleSkeleton(BNLearner self, UndiGraph skeleton)"""
        return _pyAgrum.BNLearner_setPossibleSkeleton(self, skeleton)

    def addPossibleEdge(self, *args) -> "void":
        r"""
        addPossibleEdge(BNLearner self, Edge edge)
        addPossibleEdge(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        addPossibleEdge(BNLearner self, std::string const & tail, std::string const & head)
        """
        return _pyAgrum.BNLearner_addPossibleEdge(self, *args)

    def erasePossibleEdge(self, *args) -> "void":
        r"""
        erasePossibleEdge(BNLearner self, Edge edge)
        erasePossibleEdge(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        erasePossibleEdge(BNLearner self, std::string const & tail, std::string const & head)

        Allow the 2 arcs to be added if necessary.

        Parameters
        ----------
        arc : pyAgrum
        	an arc
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BNLearner_erasePossibleEdge(self, *args)

    def addForbiddenArc(self, *args) -> "void":
        r"""
        addForbiddenArc(BNLearner self, Arc arc)
        addForbiddenArc(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        addForbiddenArc(BNLearner self, std::string const & tail, std::string const & head)

        The arc in parameters won't be added.

        Parameters
        ----------
        arc : pyAgrum.Arc
        	an arc
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BNLearner_addForbiddenArc(self, *args)

    def eraseForbiddenArc(self, *args) -> "void":
        r"""
        eraseForbiddenArc(BNLearner self, Arc arc)
        eraseForbiddenArc(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        eraseForbiddenArc(BNLearner self, std::string const & tail, std::string const & head)

        Allow the arc to be added if necessary.

        Parameters
        ----------
        arc : pyAgrum
        	an arc
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BNLearner_eraseForbiddenArc(self, *args)

    def addMandatoryArc(self, *args) -> "void":
        r"""
        addMandatoryArc(BNLearner self, Arc arc)
        addMandatoryArc(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        addMandatoryArc(BNLearner self, std::string const & tail, std::string const & head)

        Allow to add prior structural knowledge.

        Parameters
        ----------
        arc : pyAgrum.Arc
        	an arc
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        Raises
        ------
        gum.InvalidDirectedCycle
        	If the added arc creates a directed cycle in the DAG

        """
        return _pyAgrum.BNLearner_addMandatoryArc(self, *args)

    def eraseMandatoryArc(self, *args) -> "void":
        r"""
        eraseMandatoryArc(BNLearner self, Arc arc)
        eraseMandatoryArc(BNLearner self, gum::NodeId const tail, gum::NodeId const head)
        eraseMandatoryArc(BNLearner self, std::string const & tail, std::string const & head)

        Parameters
        ----------
        arc : pyAgrum
        	an arc
        head :
        	a variable's id (int)
        tail :
        	a variable's id (int)
        head :
        	a variable's name (str)
        tail :
        	a variable's name (str)

        """
        return _pyAgrum.BNLearner_eraseMandatoryArc(self, *args)

    def useEM(self, epsilon: 'double const') -> "void":
        r"""
        useEM(BNLearner self, double const epsilon)

        Indicates if we use EM for parameter learning.

        Parameters
        ----------
        epsilon : double
        	if epsilon=0.0 then EM is not used
        	if epsilon>0 then EM is used and stops when the sum of the cumulative squared error on parameters is les than epsilon.

        """
        return _pyAgrum.BNLearner_useEM(self, epsilon)

    def hasMissingValues(self) -> "bool":
        r"""
        hasMissingValues(BNLearner self) -> bool

        Indicates whether there are missing values in the database.

        Returns
        -------
        bool
            True if there are some missing values in the database.

        """
        return _pyAgrum.BNLearner_hasMissingValues(self)

    def logLikelihood(self, *args) -> "double":
        r"""
        logLikelihood(BNLearner self, std::vector< gum::NodeId,std::allocator< gum::NodeId > > const & vars, std::vector< gum::NodeId,std::allocator< gum::NodeId > > const & knowing={}) -> double
        logLikelihood(BNLearner self, std::vector< gum::NodeId,std::allocator< gum::NodeId > > const & vars) -> double
        logLikelihood(BNLearner self, Vector_string vars, Vector_string knowing={}) -> double
        logLikelihood(BNLearner self, Vector_string vars) -> double

        logLikelihood computes the log-likelihood for the columns in vars, given the columns in the list knowing (optional)


        Parameters
        ----------
        vars: List[str]
        	the name of the columns of interest

        knowing : List[str]
        	the (optional) list of names of conditioning columns

        Returns
        -------
        double
        	the log-likelihood (base 2)

        """
        return _pyAgrum.BNLearner_logLikelihood(self, *args)

    def nbRows(self) -> "gum::Size":
        r"""
        nbRows(BNLearner self) -> gum::Size

        Return the number of row in the database


        Returns
        -------
        int
        	the number of rows in the database

        """
        return _pyAgrum.BNLearner_nbRows(self)

    def nbCols(self) -> "gum::Size":
        r"""
        nbCols(BNLearner self) -> gum::Size

        Return the nimber of columns in the database


        Returns
        -------
        int
        	the number of columns in the database

        """
        return _pyAgrum.BNLearner_nbCols(self)

    def setInitialDAG(self, g: 'DAG') -> "void":
        r"""
        setInitialDAG(BNLearner self, DAG g)

        Parameters
        ----------
        dag : pyAgrum.DAG
        	an initial DAG structure

        """
        return _pyAgrum.BNLearner_setInitialDAG(self, g)

    def use3off2(self) -> "void":
        r"""
        use3off2(BNLearner self)

        Indicate that we wish to use 3off2.

        """
        return _pyAgrum.BNLearner_use3off2(self)

    def useMIIC(self) -> "void":
        r"""
        useMIIC(BNLearner self)

        Indicate that we wish to use MIIC.

        """
        return _pyAgrum.BNLearner_useMIIC(self)

    def useNML(self) -> "void":
        r"""
        useNML(BNLearner self)

        Indicate that we wish to use the NML correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useNML(self)

    def useMDL(self) -> "void":
        r"""
        useMDL(BNLearner self)

        Indicate that we wish to use the MDL correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useMDL(self)

    def useNoCorr(self) -> "void":
        r"""
        useNoCorr(BNLearner self)

        Indicate that we wish to use the NoCorr correction for 3off2 or MIIC

        """
        return _pyAgrum.BNLearner_useNoCorr(self)

    def latentVariables(self, *args) -> "std::vector< gum::Arc,std::allocator< gum::Arc > > const":
        r"""
        latentVariables(BNLearner self) -> PyObject
        latentVariables(BNLearner self) -> std::vector< gum::Arc,std::allocator< gum::Arc > > const

        Warnings
        --------
        learner must be using 3off2 or MIIC algorithm

        Returns
        -------
        list
        	the list of latent variables

        """
        return _pyAgrum.BNLearner_latentVariables(self, *args)

    def learnMixedStructure(self) -> "gum::MixedGraph":
        r"""
        learnMixedStructure(BNLearner self) -> MixedGraph

        Warnings
        --------
        learner must be using 3off2 or MIIC algorithm

        Returns
        -------
        pyAgrum.EssentialGraph
        	the learned structure as an EssentialGraph

        """
        val = _pyAgrum.BNLearner_learnMixedStructure(self)

        bn=BayesNet()
        for i in range(len(self.names())):
          bn.add(self.nameFromId(i),2)
        ge=EssentialGraph(bn,val)
        ge._bn=bn
        return ge


        return val


# Register BNLearner in _pyAgrum:
_pyAgrum.BNLearner_swigregister(BNLearner)

class BNDatabaseGenerator(object):
    r"""



    BNGenerator is used to easily generate databases from a gum.BayesNet.

    Available constructors:

        ``BNDatabaseGenerator(bn) -> BNDatabaseGenerator``

    Parameters
    ----------
    bn: gum.BayesNet
        the Bayesian network used to generate data.

    """

    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
    __repr__ = _swig_repr

    def __init__(self, bn: 'BayesNet'):
        r"""
        __init__(BNDatabaseGenerator self, BayesNet bn) -> BNDatabaseGenerator

        BNGenerator is used to easily generate databases from a gum.BayesNet.

        Available constructors:

            ``BNDatabaseGenerator(bn) -> BNDatabaseGenerator``

        Parameters
        ----------
        bn: gum.BayesNet
            the Bayesian network used to generate data.

        """
        _pyAgrum.BNDatabaseGenerator_swiginit(self, _pyAgrum.new_BNDatabaseGenerator(bn))
    __swig_destroy__ = _pyAgrum.delete_BNDatabaseGenerator

    def drawSamples(self, nbSamples: 'gum::Size') -> "double":
        r"""drawSamples(BNDatabaseGenerator self, gum::Size nbSamples) -> double"""
        return _pyAgrum.BNDatabaseGenerator_drawSamples(self, nbSamples)

    def toCSV(self, *args) -> "void":
        r"""toCSV(BNDatabaseGenerator self, std::string const & csvFileURL, bool useLabels=True, bool append=False, std::string csvSeparator=",", bool checkOnAppend=False)"""
        return _pyAgrum.BNDatabaseGenerator_toCSV(self, *args)

    def toDatabaseTable(self, useLabels: 'bool'=True) -> "gum::learning::DatabaseTable< >":
        r"""toDatabaseTable(BNDatabaseGenerator self, bool useLabels=True) -> gum::learning::DatabaseTable< >"""
        return _pyAgrum.BNDatabaseGenerator_toDatabaseTable(self, useLabels)

    def database(self) -> "std::vector< std::vector< gum::Idx,std::allocator< gum::Idx > >,std::allocator< std::vector< gum::Idx,std::allocator< gum::Idx > > > >":
        r"""database(BNDatabaseGenerator self) -> std::vector< std::vector< gum::Idx,std::allocator< gum::Idx > >,std::allocator< std::vector< gum::Idx,std::allocator< gum::Idx > > > >"""
        return _pyAgrum.BNDatabaseGenerator_database(self)

    def setVarOrder(self, *args) -> "void":
        r"""
        setVarOrder(BNDatabaseGenerator self, std::vector< gum::Idx,std::allocator< gum::Idx > > const & varOrder)
        setVarOrder(BNDatabaseGenerator self, Vector_string varOrder)
        """
        return _pyAgrum.BNDatabaseGenerator_setVarOrder(self, *args)

    def setVarOrderFromCSV(self, *args) -> "void":
        r"""setVarOrderFromCSV(BNDatabaseGenerator self, std::string const & csvFileURL, std::string const & csvSeparator=",")"""
        return _pyAgrum.BNDatabaseGenerator_setVarOrderFromCSV(self, *args)

    def setTopologicalVarOrder(self) -> "void":
        r"""setTopologicalVarOrder(BNDatabaseGenerator self)"""
        return _pyAgrum.BNDatabaseGenerator_setTopologicalVarOrder(self)

    def setAntiTopologicalVarOrder(self) -> "void":
        r"""setAntiTopologicalVarOrder(BNDatabaseGenerator self)"""
        return _pyAgrum.BNDatabaseGenerator_setAntiTopologicalVarOrder(self)

    def setRandomVarOrder(self) -> "void":
        r"""setRandomVarOrder(BNDatabaseGenerator self)"""
        return _pyAgrum.BNDatabaseGenerator_setRandomVarOrder(self)

    def varOrder(self) -> "std::vector< gum::Idx,std::allocator< gum::Idx > >":
        r"""varOrder(BNDatabaseGenerator self) -> std::vector< gum::Idx,std::allocator< gum::Idx > >"""
        return _pyAgrum.BNDatabaseGenerator_varOrder(self)

    def varOrderNames(self) -> "std::vector< std::string,std::allocator< std::string > >":
        r"""varOrderNames(BNDatabaseGenerator self) -> Vector_string"""
        return _pyAgrum.BNDatabaseGenerator_varOrderNames(self)

    def log2likelihood(self) -> "double":
        r"""log2likelihood(BNDatabaseGenerator self) -> double"""
        return _pyAgrum.BNDatabaseGenerator_log2likelihood(self)

# Register BNDatabaseGenerator in _pyAgrum:
_pyAgrum.BNDatabaseGenerator_swigregister(BNDatabaseGenerator)


def statsObj() -> "void":
    r"""statsObj()"""
    return _pyAgrum.statsObj()


