API-Specification

pracmln comes with an easy-to-use API, which lets you use the learning and reasoning methods provided by pracmln convently in your own applications.

MLNs

An MLN is represented by an instance of the class pracmln.MLN. An existing MLN can be loaded using its static load method:

mln = MLN.load(files='path/to/file')
static MLN.load(files, logic='FirstOrderLogic', grammar='PRACGrammar', mln=None)

Reads an MLN object from a file or a set of files.

Parameters
  • files – one or more pracmln.mlnpath strings. If multiple file names are given, the contents of all files will be concatenated.

  • logic – (string) the type of logic to be used. Either FirstOrderLogic or FuzzyLogic.

  • grammar – (string) the syntax to be used for parsing the MLN file. Either PRACGrammar or StandardGrammar.

Alternatively, the constructor can be used to load the MLN::

mln = MLN(mlnfile='path/to/mlnfile', grammar='PRACGrammar', logic='FirstOrderLogic')
class pracmln.MLN(logic='FirstOrderLogic', grammar='PRACGrammar', mlnfile=None)

Represents a Markov logic network.

Member formulas

a list of logic.common.Formula objects representing the formulas of the MLN.

Member predicates

a dict mapping predicate names to mlnpreds.Predicate objects.

Parameters
  • logic – (string) the type of logic to be used in this MLN. Possible values are FirstOrderLogic and FuzzyLogic.

  • grammar – (string) the syntax to be used. Possible grammars are PRACGrammar and StandardGrammar.

  • mlnfile – can be a path to an MLN file or a file object.

If no mlnfile is specified, the constructor creates an empty MLN object. Using the << operator, one can feed content into the MLN:

>>> from pracmln import MLN
>>> mln = MLN()
>>> mln << 'foo(x)' # predicate declaration
>>> mln << 'bar(y)' # another pred declaration
>>> mln << 'bar(?x) => bar(?y).' # hard logical constraint
>>> mln << 'logx(.75)/log(.25) foo(?x)' # weighted formula

We can dump the MLN into the regular MLN file format by using the write method:

>>> mln.write()



// predicate declarations
bar(y)
foo(x)

// formulas
bar(?x) => bar(?y).
logx(.75)/log(.25)  foo(?x)

If your terminal supports ASCII escape sequences, the syntax of the result will be highlighted. By specifying a stream, one can dump the MLN into a file.

MLN.write(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, color=None)

Writes the MLN to the given stream.

The default stream is sys.stdout. In order to print the MLN to the console, a simple call of mln.write() is sufficient. If color is not specified (is None), then the output to the console will be colored and uncolored for every other stream.

Parameters
  • stream – the stream to write the MLN to.

  • color – whether or not output should be colorized.

We can access the predicates of the MLN using the predicates attribute:

>>> for pred in mln.predicates:
...     print repr(pred)
...
<Predicate: bar(y)>
<Predicate: foo(x)>

Formulas are instances of pracmln.logic.Formula and stored in the formulas attribute:

>>> for f in mln.formulas:
...     print f
...     f.print_structure()
...
bar(?x) => bar(?y)
<Implication: bar(?x) => bar(?y)>: [idx=0, weight=inf] bar(?x) => bar(?y) = ?
    <Lit: bar(?x)>: [idx=?, weight=?] bar(?x) = ?
    <Lit: bar(?y)>: [idx=?, weight=?] bar(?y) = ?
foo(?x)
<Lit: foo(?x)>: [idx=1, weight=logx(.75)/log(.25)] foo(?x) = ?

The method print_structure prints the logical structure of a formula as well as a couple of properties, such as its index in the MLN and its weight. As you can see, hard formula constraints are internally represented by assiging them a weight of float('inf'). In presence of evidence, print_structure also prints the truth value of each constituent of a formula, which is a float value in {0,1} for formulas with FOL semantics, and in [0,1] in case of fuzzy logics semantics. If the truth value cannot be determined (as in our example here for we don’t have evidence yet), this is indicated by a question mark = ?.

Databases

The central datastructures for representing relational data is the pracmln.Database class. It stores atomic facts about the relational domain of discourse by maintaining a mapping of ground atoms to their respective truth value.

A serialized .db database file can be loaded using the Database.load method:

>>> from pracmln import Database
>>> dbs = Database.load(mln, 'path/to/dbfile')

Since there may be multiple independent databases stored in a single .db file (separated by ---) load always returns a list of pracmln.Database objects.

The mln parameter of the load method must point to an instantated pracmln.MLN object containing all the predicate declarations of atoms occuring in the database. The default constructor creates an empty database:

>>> db = Database(mln)
class pracmln.Database(mln, evidence=None, dbfile=None, ignore_unknown_preds=False)

Represents an MLN Database, which consists of a set of ground atoms, each assigned a truth value.

Member mln

the respective mln.base.MLN object that this Database is associated with

Member domains

dict mapping the variable domains specific to this data base (i.e. without values from the MLN domains which are not present in the DB) to the set possible values.

Member evidence

dictionary mapping ground atom strings to truth values.

Parameters
  • mln – the mln.base.MLN instance that the database shall be associated with.

  • evidence – a dictionary mapping ground atoms to their truth values.

  • dbfile – if specified, a database is loaded from the given file path.

  • ignore_unknown_preds – see mln.database.parse_db()

Loading a database from a static serialized file is fine, but if you consider integrating SRL techniques seamlessly in your application, you rather want to create databases representing the evidences for your reasoning tasks at runtime. pracmln has been designed to support convenient dynamic generation of relational data. Once a database has been loaded or created, new facts can be added using the << operator

>>> db << 'foo(X)'

or by directly setting the truth value of an atom:

>>> db['bar(Y)'] = .0

Similarly to the pracmln.MLN, databases have a write method that prints them to the console:

>>> db.write()
[                              ]   0.000 %  bar(Y)
[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] 100.000 %  foo(X)

The bars in front of the atom names indicate the truth values/probabilities of the respective atom. When writing them to a file, they can be switched off.

Database.write(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, color=None, bars=True)

Writes this database into the stream in the MLN Database format. The stream must provide a write() method as file objects do.

Truth values of atoms that have been asserted once can be retracted from a database using the del operator:

>>> del db['bar(Y)']
>>> db.write()
[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] 100.000 %  foo(X)

A convenient method is Database.query, which lets you make a PROLOG-like query to the database for an arbitrary formula in FOL.

Database.query(formula, thr=1)

Makes to the database a ‘prolog-like’ query given by the specified formula.

Returns a generator of dictionaries with variable-value assignments for which the formula has a truth value of at least thr.

Parameters
  • formula – the formula the database shall be queried with.

  • thr – the threshold for truth values.

Warning

This is very inefficient, since all groundings will be instantiated; so keep the queries short.

Example

>>> for r in db.query('foo(?x, ?y)'):
>>>     print r
>>>
{'?x': 'X1', '?y': 'Y1'}
{'?x': 'X2', '?y': 'Y2'}

Reasoning

Once an MLN and a database have been loaded or created, we can perform inference using the pracmln.MLNQuery class, which wraps around all inference algorithms provided by pracmln. It takes the MLN object subject to reasoning as a parameter as well as any of the parameters for the inference algorithms described in Inference Methods.

>>> from pracmln import MLNQuery
>>> result = MLNQuery(mln=mln, db=db).run()
>>> result.write()
[■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■] 100.000 % bar(X)
[■■■■■■■■■■■■■■■■■■■■■■■       ]  75.660 % foo(K)

API Reference

pracmln.MLN

class pracmln.MLN(logic='FirstOrderLogic', grammar='PRACGrammar', mlnfile=None)

Represents a Markov logic network.

Member formulas

a list of logic.common.Formula objects representing the formulas of the MLN.

Member predicates

a dict mapping predicate names to mlnpreds.Predicate objects.

Parameters
  • logic – (string) the type of logic to be used in this MLN. Possible values are FirstOrderLogic and FuzzyLogic.

  • grammar – (string) the syntax to be used. Possible grammars are PRACGrammar and StandardGrammar.

  • mlnfile – can be a path to an MLN file or a file object.

constant(domain, *values)

Adds to the MLN a constant domain value to the domain specified.

If the domain doesn’t exist, it is created.

Parameters
  • domain – (string) the name of the domain the given value shall be added to.

  • values – (string) the values to be added.

copy()

Returns a deep copy of this MLN, which is not yet materialized.

declare_predicate(predicate)

Adds a predicate declaration to the MLN:

Parameters

predicate – an instance of a Predicate or one of its subclasses specifying a predicate declaration.

formula(formula, weight=0.0, fixweight=False, unique_templvars=None)

Adds a formula to this MLN. The respective domains of constants are updated, if necessary. If formula is an integer, returns the formula with the respective index or the formula object that has been created from formula. The formula will be automatically tied to this MLN.

Parameters
  • formula – a Logic.Formula object or a formula string

  • weight – an optional weight. May be a mathematical expression as a string (e.g. log(0.1)), real-valued number or mln.infty to indicate a hard formula.

  • fixweight – indicates whether or not the weight of this formula should be fixed during learning.

  • unique_templvars – specifies a list of template variables that will create only unique combinations of expanded formulas

ground(db)

Creates and returns a ground Markov Random Field for the given database.

Parameters
  • db – database filename (string) or Database object

  • cw – if the closed-world assumption shall be applied (to all predicates)

  • cwpreds – a list of predicate names the closed-world assumption shall be applied.

iter_formulas_printable()

Iterate over all formulas, yield nicely formatted strings.

iterformulas()

Returns a generator yielding (idx, formula) tuples.

iterpreds()

Yields the predicates defined in this MLN alphabetically ordered.

learn(databases, method=<class 'pracmln.mln.learning.bpll.BPLL'>, **params)

Triggers the learning parameter learning process for a given set of databases. Returns a new MLN object with the learned parameters.

Parameters

databases – list of mln.database.Database objects or filenames

static load(files, logic='FirstOrderLogic', grammar='PRACGrammar', mln=None)

Reads an MLN object from a file or a set of files.

Parameters
  • files – one or more pracmln.mlnpath strings. If multiple file names are given, the contents of all files will be concatenated.

  • logic – (string) the type of logic to be used. Either FirstOrderLogic or FuzzyLogic.

  • grammar – (string) the syntax to be used for parsing the MLN file. Either PRACGrammar or StandardGrammar.

materialize(*dbs)

Materializes this MLN with respect to the databases given. This must be called before learning or inference can take place.

Returns a new MLN instance containing expanded formula templates and materialized weights. Normally, this method should not be called from the outside. Also takes into account whether or not particular domain values or predictaes are actually used in the data, i.e. if a predicate is not used in any of the databases, all formulas that make use of this predicate are ignored.

Parameters

dbs – list of database.Database objects for materialization.

predicate(predicate)

Returns the predicate object with the given predicate name, or declares a new predicate.

If predicate is a string, this method returns the predicate object assiciated to the given predicate name. If it is a predicate instance, it declares the new predicate in this MLN and returns the MLN instance. In the latter case, this is equivalent to MLN.declare_predicate().

Parameters

predicate – name of the predicate to be returned or a Predicate instance specifying the predicate to be declared.

Returns

the Predicate object or None if there is no predicate with this name. If a new predicate is declared, returns this MLN instance.

Example

>>> mln = MLN()
>>> mln.predicate(Predicate(foo, [arg0, arg1]))
       .predicate(Predicate(bar, [arg1, arg2])) # this declares predicates foo and bar
>>> mln.predicate('foo')
<Predicate: foo(arg0,arg1)>
print_formulas()

Nicely prints the formulas and their weights.

tofile(filename)

Creates the file with the given filename and writes this MLN into it.

update_domain(domain)

Combines the existing domain (if any) with the given one.

Parameters

domain – a dictionary with domain Name to list of string constants to add

update_predicates(mln)

Merges the predicate definitions of this MLN with the definitions of the given one.

Parameters

mln – an instance of an MLN object.

weight(idx, weight=None)

Returns or sets the weight of the formula with index idx.

write(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, color=None)

Writes the MLN to the given stream.

The default stream is sys.stdout. In order to print the MLN to the console, a simple call of mln.write() is sufficient. If color is not specified (is None), then the output to the console will be colored and uncolored for every other stream.

Parameters
  • stream – the stream to write the MLN to.

  • color – whether or not output should be colorized.

class pracmln.Database(mln, evidence=None, dbfile=None, ignore_unknown_preds=False)

Represents an MLN Database, which consists of a set of ground atoms, each assigned a truth value.

Member mln

the respective mln.base.MLN object that this Database is associated with

Member domains

dict mapping the variable domains specific to this data base (i.e. without values from the MLN domains which are not present in the DB) to the set possible values.

Member evidence

dictionary mapping ground atom strings to truth values.

Parameters
  • mln – the mln.base.MLN instance that the database shall be associated with.

  • evidence – a dictionary mapping ground atoms to their truth values.

  • dbfile – if specified, a database is loaded from the given file path.

  • ignore_unknown_preds – see mln.database.parse_db()

class PseudoMRF(db)

can be used in order to use only a Database object to ground formulas (without instantiating an MRF) and determine the truth of these ground formulas by partly replicating the interface of an MRF object

iter_true_var_assignments(formula, truth_thr=1.0)

Iterates over all groundings of formula that evaluate to true given this Pseudo-MRF.

add(gndlit, truth=1)

Adds the fact represented by the ground atom, which might be a GroundLit object or a string.

Parameters
  • gndlit – the ground literal to be added to the database. Can be either a string or a logic.common.Logic.GroundLit instance.

  • truth – the truth value of this ground literal. 0 stands for false, 1 for true. In case of soft or fuzzy evidence, any truth value in [0,1] is allowed.

copy(mln=None)

Returns a copy this Database. If mln is specified, asserts this database for the given MLN.

Parameters

mln – if mln is specified, the new MLN will be associated with mln, if not, it will be associated with self.mln.

domain(domain)

Returns the list of domain values of the given domain, or None if no domain with the given name exists. If domain is dict, the domain values will be updated and the domain will be created, if necessary.

Parameters

domain – the name of the domain to be returned.

gndatoms(prednames=None)

Iterates over all ground atoms in this database that match any of the given predicate names. If no predicate name is specified, it yields all ground atoms in the database.

Parameters

prednames – a list of predicate names that this iteration should be filtered by.

Returns

a generator of (atom, truth) tuples.

isempty()

Returns True iff there is an assertion for any ground atom in this database and False if the truth values all ground atoms are None AND all domains are empty.

ishard()

Determines whether or not this database contains exclusively hard evidences.

static load(mln, dbfiles, ignore_unknown_preds=False, db=None)

Reads one or multiple database files containing literals and/or domains. Returns one or multiple databases where domains is dictionary mapping domain names to lists of constants defined in the database and evidence is a dictionary mapping ground atom strings to truth values

Parameters
  • dbfile – a single one or a list of paths to database file.

  • mln – the MLN object which should be used to load the database.

Returns

either one single or a list of database objects.

Example
>>> mln = MLN()
>>> db = Database.load(mln, './example.db')
query(formula, thr=1)

Makes to the database a ‘prolog-like’ query given by the specified formula.

Returns a generator of dictionaries with variable-value assignments for which the formula has a truth value of at least thr.

Parameters
  • formula – the formula the database shall be queried with.

  • thr – the threshold for truth values.

Warning

This is very inefficient, since all groundings will be instantiated; so keep the queries short.

Example

>>> for r in db.query('foo(?x, ?y)'):
>>>     print r
>>>
{'?x': 'X1', '?y': 'Y1'}
{'?x': 'X2', '?y': 'Y2'}
retract(gndatom)

Removes the evidence of the given ground atom in this database.

Also cleans up the domains if an atom is removed that makes use of a domain value that is not used by any other evidence atom.

Parameters

gndatom – a string representation of the ground atom to be removed from the database or a logic.common.Logic.GroundAtom instance.

retractall(predname)

Retracts all evidence atoms of the given predicate name in this database.

rmval(domain, value)

Removes the value value from the domain domain of this database.

This removal is complete, i.e. it also retracts all atoms in this database that the respective value is participating in as an argument.

Parameters
  • domain – (str) the domain from which the value is to be removed.

  • value – (str) the value to be removed.

tofile(filename)

Writes this database into the file with the given filename.

truth(gndatom)

Returns the evidence truth value of the given ground atom.

Parameters

gndatom – a ground atom string

Returns

the truth value of the ground atom, or None if it is not specified.

union(dbs, mln=None)

Returns a new database consisting of the union of all databases given in the arguments. If mln is specified, the new database will be attached to that one, otherwise the mln of this database will be used.

write(stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, color=None, bars=True)

Writes this database into the stream in the MLN Database format. The stream must provide a write() method as file objects do.

In this section, we will introduce the basic interface for using the reasoning methods for MLNs provided by pracmln.

The easiest way

ROS Service interface

Introduction

This is a tutorial for the ROS service that can be used to query an MLN. We will describe the implemantation of the server together with the ROS messages that are associated with this project. We will also present an example client program that can be used as a template.

Server methods

scripts.mln_server.handle_mln_query(req)

Handles the query from the client. It expects req to have two fields, req.query and an optional req.config. req.query should be of type MLNQuery while req.config should be of type MLNConfig.

It returns a list of AtomProbPair objects. Each element of the list is an atom with it’s corresponding degree of truth.

scripts.mln_server.mln_interface_server()

Keeps an infinite loop while waiting for clients to ask for the service.

scripts.mln_server.Storage.getInstance()

Storage is a singleton class that keeps track of an MLNInfer object together with the settings for the inference proceedure.

Example client

scripts.mln_mln.mln_interface_client(query, config=None)

This is an example of the client quering the service. The important thing to note is that you have the option to set the configuration parameters only once and use the the same settings in further calls.

Messages

MLNQuery.msg

This ROS message contains the following fields:

queries - This message is an ecoding of the queries that will

sent to the service.

MLNResponse.msg

This ROS message contains the follwing fields:

results - This is what is returned by the service. results

is a list of AtomProbPair objects. Each atom is associated with a probability value.

MLNConfig.msg

This is a message that is used to initialize the configuration parameters for quering the service. You have an option to pass this argument only once and reuse the same configurations over and over. It contains the following fields:

mlnFiles - a *.mln file that describes the MLN

db - the evidence database

method - the inference method to be used

engine - the inference engine to be used

output_filename - the name of the output filename

saveResults - this field should be set to true if you wish to save the results

logic - specifies the logic to be used for inference

grammar - specifies the grammar to be used

AtomProbPair.msg

This message is a pair of an Atom and a Probabality. It contains the following fields:

atom - string describing the atom

prob - a probability value for the atom’s degree of truth

Services

MLNInterface.srv

This is the main service. It contains two fields:

MLNQuery - This is the query string

MLNConfig - This specifies which engine, inference method

etc is going to be used for inference. This should be set at least once.