Skip to main content

Essential tools and interfaces for WMI solving.

Project description

pywmi Build Status

Installation

pip install pywmi

pywmi offers various services and engines that require additional installation steps.

SMT solvers

pywmi relies upon pysmt to interface with SMT solvers. If you want to benefit from functionality relying on SMT solvers please install an SMT solver through the pysmt-install tool that comes as part of your pywmi installation.

pysmt-install --msat  # example to install mathsat, more solvers are available

For older versions of PySMT (older than version 0.8), you have to make sure that when you use pywmi, the SMT solvers are on your path. The pysmt-install tool can show you the necessary commands.

pysmt-install --env

XADD engine

The XADD engine performs WMI using XADDs as described in Kolb et al., 2018. To use this engine you need Java, Gurobi and the xadd library JAR file. The pywmi-install tool that comes with your pywmi installation can automatically download and install the JAR file, however, you need to install Java and Gurobi manually. Once you did that, just call:

pywmi-install xadd
pywmi-install xadd --force  # To download a new version

Predicate abstraction engine

The predicate abstraction engine (short PA engine) uses MathSAT and Latte to solve WMI using predicate abstraction, as described in Morettin et al., 2017. In order to use the PA engine, you need to install the MathSAT SMT solver (see instructions above), Latte (see instructions below) and the wmipa library. You can use the pysmt-install utility to download the library.

pywmi-install pa
pywmi-install pa --force  # To download a new version

Manual installation

You can also download or clone the library manually and add it to your PYTHONPATH

  1. Download / clone the wmipa library
  2. Add the directory containing the library to your PYTHONPATH

Native XSDD engine

The native XSDD engine (and the PiecewiseXSDD class for representing piecewise functions) are implemented using the PySDD library. The PySDD package can be installed as follows:

pip install git+https://github.com/wannesm/PySDD.git#egg=PySDD

External XSDD engine

WMI using XSDD inference is also supported by pywmi. To use the XSDD engine you need to install HAL-ProbLog by following the instructions provided in the README file.

Summary

  1. Install the dmd compiler v2.078.3
  2. git clone https://github.com/ariovistus/pyd.git
  3. cd pyd
  4. python setup.py install
  5. cd ../
  6. git clone --recursive https://github.com/ML-KULeuven/psipy.git
  7. cd psypi
  8. python psipy/build_psi.py
  9. python setup.py install
  10. Add the psi library to your path (command printed during the previous step)
  11. cd ../
  12. git clone https://bitbucket.org/pedrozudo/hal_problog.git
  13. cd hal_problog
  14. python setup.py install

Take care that your code does not run in the same directory as the one you cloned the libraries, as they will pollute your namespace.

Latte

The Latte integration backend as well as the predicate abstraction solver require Latte to be installed. You can find the latest releases on their GitHub releases page. You'll probably want the bundle: latte-integrale.

Summary

  1. wget "https://github.com/latte-int/latte/releases/download/version_1_7_5/latte-integrale-1.7.5.tar.gz"
  2. tar -xvzf latte-integrale-1.7.5.tar.gz
  3. cd latte-integrale-1.7.5
  4. ./configure
  5. make

Usage

Calling pywmi

Setup density and query

import pysmt.shortcuts as smt

# Create a "domain" with boolean variables a and b and real variables x, y (both between 0 and 1)
domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])

a, b = domain.get_bool_symbols()  # Get PySMT symbols for the boolean variables
x, y = domain.get_real_symbols()  # Get PySMT variables for the continuous variables

# Create support
support = (a | b) & (~a | ~b) & (x <= y) & domain.get_bounds()

# Create weight function (PySMT requires constants to be wrapped, e.g., smt.Real(0.2))
weight_function = smt.Ite(a, smt.Real(0.2), smt.Real(0.8)) * (smt.Ite(x <= 0.5, smt.Real(0.2), 0.2 + y) + smt.Real(0.1))

# Create query
query = x <= y / 2

Use engine to perform inference

# Create rejection-sampling based engine (no setup required)
rejection_engine = RejectionEngine(domain, support, weight_function, sample_count=100000)

print("Volume (Rejection):           ", rejection_engine.compute_volume())  # Compute the weighted model integral
print("Query probability (Rejection):", rejection_engine.compute_probability(query))  # Compute query probability

Use XADD engine (make sure you have installed the prerequisites)

# Create XADD engine (mode resolve refers to the integration algorithm described in
# Kolb et al. Efficient symbolic integration for probabilistic inference. IJCAI 2018)
# !! Requires XADD solver to be setup (see above) !!
xadd_engine = XaddEngine(domain, support, weight_function, mode="resolve")

print("Volume (XADD):                ", xadd_engine.compute_volume())  # Compute the weighted model integral
print("Query probability (XADD):     ", xadd_engine.compute_probability(query))  # Compute query probability

Generating uniform samples and their labels

from pywmi.sample import uniform
# n: Required number of samples
# domain, support: Domain and support defined as above
samples = uniform(domain, n)
labels = evaluate(samples, support, samples)

Generating weighted positive samples

from pywmi.sample import positive
# n: Required number of samples
# domain, support, weight: Defining the density as above
# Optional:
#   sample_pool_size: The number of uniformly sampled positive samples to weight and select the samples from
#   sample_count: The number of samples to draw initially, from which to build the positive pool
#   max_samples: The maximum number of uniformly sampled samples (positive or negative) to generate before failing
#                => If max_samples is exceeded a SamplingError will be raised
samples, positive_ratio = positive(n, domain, support, weight)

Handle densities and write to files

# Wrap support and weight function (and optionally queries) in a density object
density = Density(domain, support, weight_function, [query])

# Density object can be saved to and loaded from files
filename = "my_density.json"
density.to_file(filename)  # Save to file
density = Density.from_file(filename)  # Load from file

Work from command line

# Compare engines from command line
python -m pywmi my_density.json compare rej:n100000 xadd:mresolve  # Compute the weighted model integral
python -m pywmi my_density.json compare rej:n100000 xadd:mresolve -q 0  # Compute query probability (query at index 0)

# Compute volumes and probabilities from command line
# You can provide multiple engines and the result of the first engine not to fail will be returned
python -m pywmi my_density.json volume rej:n100000  # Compute weighted model integral
python -m pywmi my_density.json prob rej:n100000  # Compute all query probabilities

# Plot 2-D support
python -m pywmi my_density.json plot -o my_density.png

Find the complete running example in pywmi/tests/running_example.py

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pywmi-0.7.15.tar.gz (198.3 kB view hashes)

Uploaded Source

Built Distribution

pywmi-0.7.15-py2.py3-none-any.whl (228.1 kB view hashes)

Uploaded Python 2 Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page