API Documentation¶
The heart of the Clorm ORM involves defining the mapping from ground predicates to member variables of a Python object. There are two aspects to this: fields, that define how logical terms are mapped to Python objects, and predicate definitions, that define predicate and function names, their arities and the appropriate field for each of the parameters.
Fields¶
Fields provide a specification for how to convert clingo.Symbol
objects into
more intuitive Python objects.
- class clorm.RawField(*args, **kwargs)¶
A class that represents a field that correspond to logical terms.
A field is typically used as part of a
ComplexTerm
orPredicate
definition. It defines the data type of an ASP term and provides functions for translating the term to a more convenient Python type.It contains two class functions
cltopy
andpytocl
that implement the translation from Clingo to Python and Python to Clingo respectively. ForRawField
these functions simply pass the values straight though, howeverRawField
can be sub-classed to build a chain of translations.StringField
,IntegerField
, andConstantField
are predefined sub-classes that provide translations for the ASP simple terms; string, integer and constant.To sub-class RawField (or one of its sub-classes) simply specify
cltopy
andpytocl
functions that take an input and perform some translation to an output format.Note: the
cltopy
andpytocl
functions are legitmately allowed to throw either aTypeError
orValueError
exception when provided with bad input. These exceptions will be treated as a failure to unify when trying to unify clingo symbols to facts. However, any other exception is passed through as a genuine error. This should be kept in mind if you are writing your own field class.Example
import datetime class DateField(StringField): pytocl = lambda dt: dt.strftime("%Y%m%d") cltopy = lambda s: datetime.datetime.strptime(s,"%Y%m%d").date()
Because
DateField
sub-classesStringField
, rather than sub-classingRawField
directly, it forms a longer data translation chain:clingo symbol object – RawField – StringField – DateField – python date object
Here the
DateField.cltopy
is called at the end of the chain of translations, so it expects a Python string object as input and outputs a date object.DateField.pytocl
does the opposite and inputs a date object and is expected to output a Python string object.- Parameters
default – A default value (or function) to be used when instantiating a
Predicate
orComplexTerm
object. If a Pythoncallable
object is specified (i.e., a function or functor) then it will be called (with no arguments) when the predicate/complex-term object is instantiated.index (bool) – Determine if this field should be indexed by default in a
FactBase`
. Defaults toFalse
.
- classmethod cltopy(v)¶
Called when translating data from Clingo to Python
- classmethod pytocl(v)¶
Called when translating data from Python to Clingo
- classmethod unifies(v)¶
Returns whether a Clingo.Symbol can be unified with this type of term
- property default¶
Returns the default value for the field (or
None
if no default was set).Note: 1) if a function was specified as the default then testing
default
will call this function and return the value, 2) if your RawField sub-class allows a default value ofNone
then you need to check thehas_default
property to distinguish between no default value and aNone
default value.
- property index¶
Returns whether this field should be indexed by default in a FactBase
- class clorm.StringField(*args, **kwargs)¶
A field to convert between a Clingo.String object and a Python string.
- class clorm.ConstantField(*args, **kwargs)¶
A field to convert between a simple
Clingo.Function
object and a Python string.Note: currently
ConstantField
treats a string with a starting “-” as a negated constant. In hindsight this was a mistake and is now deprecated. While I don’t think anyone actually used this functionality (since it was never documented) nevertheless I will keep it there until the Clorm version 2.0 release.
- class clorm.IntegerField(*args, **kwargs)¶
A field to convert between a Clingo.Number object and a Python integer.
- class clorm.SimpleField(*args, **kwargs)¶
A class that represents a field corresponding to any simple term: string, constant, or integer.
Converting from an ASP string, constant, or integer will produce the expected Python string or integer object. However, since ASP strings and constants both map to Python strings therefore converting from Python to ASP is less straightforward. In this case it uses a regular expression to determine if the string matches an ASP constant or if it should be treated as a quoted string.
Because of this potential for ambiguity it is often better to use the distinct
IntegerField
,ConstantField
, andStringField
classes rather than theSimpleField
class.
- clorm.refine_field(*args)¶
Factory function that returns a field sub-class with restricted values.
A helper factory function to define a sub-class of a RawField (or sub-class) that restricts the allowable values. For example, if you have a constant in a predicate that is restricted to the days of the week (“monday”, …, “sunday”), you then want the Python code to respect that restriction and throw an error if the user enters the wrong value (e.g. a spelling error such as “wednsday”). Restrictions are also useful for unification if you want to unify based on some specific value.
Example
WorkDayField = refine_field("WorkDayField", ConstantField, ["monday", "tuesday", "wednesday", "thursday", "friday"]) class WorksOn(Predicate): employee = ConstantField() workday = WorkdDayField()
Instead of a passing a list of values the last parameter can also be a function/functor. If the last parameter is callable then it is treated as a function that takes a field value and returns true if it is a valid value.
Example
PosIntField = refine_field("PosIntField", NumberField, lambda x : x >= 0)
The function must be called using positional arguments with either 2 or 3 arguments. For the 3 argument case a class name is specified for the name of the new field. For the 2 argument case an anonymous field class name is automatically generated.
Example
WorkDayField = refine_field(ConstantField, ["monday", "tuesday", "wednesday", "thursday", "friday"])
Only positional arguments are supported.
- Parameters
subclass_name (optional) – new sub-class name (anonymous if none specified).
field_class – the field that is being sub-classed
values|functor – a list of values or a functor to determine validity
- clorm.combine_fields(*args)¶
Factory function that returns a field sub-class that combines other fields
A helper factory function to define a sub-class of RawField that combines other RawField subclasses. The subclass is defined such that it’s
pytocl()
(respectivelycltopy()
) function tries to return the value returned by the underlying sub-field’spytocl()
( (respectivelycltopy()
) function. If the first sub-field fails then the second is called, and so on until there are no matching sub-fields. If there is no match then a TypeError is raised.Example
MixedField = combine_fields("MixedField",[ConstantField,IntegerField])
Only positional arguments are supported.
- Parameters
subclass_name (optional) – new sub-class name (anonymous if none specified).
field_subclasses – the fields to combine
- clorm.define_nested_list_field(*args)¶
Factory function that returns a RawField sub-class for nested lists
ASP doesn’t have an explicit notion of a list, but sometimes it is useful to encode a list as a series of nested pairs (ie., a head-tail encoding) with an empty tuple indicating the end of the list.
Example
(1,(2,(3,()))) % Encodes a list [1,2,3]
This function is a helper factory function to define a sub-class of RawField that deals with a nested list encoding consisting of elements of some other RawField subclass.
Example
# Unifies against a nested list of constants NestedListField = define_nested_list_field("NLField",ConstantField)
Only positional arguments are supported.
- Parameters
subclass_name (optional) – new sub-class name (anonymous if none specified).
element_definition – the field type for each list element
Predicates and Complex Terms¶
In logical terminology predicates and terms are both considered non logical
symbols; where the logical symbols are the operator symbols for conjunction,
negation, implication, etc. While simple terms (constants, strings, and
integers) are handled by Clorm as special cases, complex terms and predicates
are both encapsulated in the Predicate
class, with ComplexTerm
simply
being an alias to this class.
- class clorm.Predicate(*args, **kwargs)¶
Encapsulates an ASP predicate or complex term in an easy to access object.
This is the heart of the ORM model for defining the mapping of a complex term or predicate to a Python object.
ComplexTerm
is simply an alias forPredicate
.Example
class Booking(Predicate): date = StringField(index = True) time = StringField(index = True) name = StringField(default = "relax") b1 = Booking("20190101", "10:00") b2 = Booking("20190101", "11:00", "Dinner")
Field names can be any valid Python variable name subject to the following restrictions:
it cannot start with a “_”, or
it cannot be be one of the following reserved words: “meta”, “raw”, “clone”, or “Field”.
The constructor creates a predicate instance (i.e., a fact) or complex term. If the
raw
parameter is used then it tries to unify the supplied Clingo.Symbol with the class definition, and will raise a ValueError if it fails to unify.- Parameters
**kwargs –
if a single named parameter
raw
is specified then it will try to unify the parameter with the specification, ornamed parameters corresponding to the field names.
- Field¶
A RawField sub-class corresponding to a Field for this class
- meta¶
Meta data (definitional information) for the predicate/complex-term. This includes:
- name¶
The name of the ASP predicate/complex-term. Empty if it is a tuple.
- is_tuple¶
Is the ASP predicate/complex-term a tuple.
- arity¶
Arity of the predicate/complex-term.
- clone(**kwargs)¶
Clone the object with some differences.
For any field name that is not one of the parameter keywords the clone keeps the same value. But for any field listed in the parameter keywords replace with specified new value.
- property raw¶
Returns the underlying clingo.Symbol object
- clorm.ComplexTerm¶
alias of
clorm.orm.core.Predicate
- clorm.simple_predicate(*args)¶
Factory function to define a predicate with only RawField arguments.
A helper factory function that takes a name and an arity and returns a predicate class that is suitable for unifying with predicate instances of that name and arity. It’s parameters are all specified as RawFields.
This function is useful for debugging ASP programs. There may be some auxillary predicates that you aren’t interested in extracting their values but instead you simply want to print them to the screen in some order.
The function must be called using positional arguments with either 2 or 3 arguments. For the 3 argument case a class name is specified for the name of the new predicate. For the 2 argument case an anonymous predicate class name is automatically generated.
- Parameters
subclass_name (optional) – new sub-class name (anonymous if none specified).
name – the name of the predicate to match against
arity – the arity for the predicate
Fact Bases and Queries¶
Predicate
instances correspond to facts. A FactBase
provides a container
for storing facts. It allows predicate fields to be indexed and provides a basic
query mechanism for accessing elements.
- class clorm.FactBase(facts=None, indexes=None)¶
A fact base is a container for facts (i.e., Predicate sub-class instances)
FactBase
can be behave like a specialisedset
object, but can also behave like a minimalist database. It stores facts forPredicate
types (where a predicate type loosely corresponds to a table in a database) and allows for certain fields to be indexed in order to perform more efficient queries.The initaliser can be given a collection of predicates. If it is passed another FactBase then it simply makes a copy (including the indexed fields).
FactBase also has a special mode when it is passed a functor instead of a collection. In this case it performs a delayed initialisation. This means that the internal data structures are only populated when the FactBase is actually used. This mode is particularly useful when extracting facts from models. Often a program will only want to keep the data from the final model (for example, with optimisation we often want the best model before a timeout). Delayed initialisation is useful will save computation as only the last model will be properly initialised.
- Parameters
facts ([Predicate]|FactBase|callable) – a list of facts (predicate instances), a fact base, or a functor that generates a list of facts. If a functor is passed then the fact base performs a delayed initialisation. If a fact base is passed and no index is specified then an index will be created matching in input fact base.
indexes (Field) – a list of fields that are to be indexed.
- add(arg)¶
Add a single fact or a collection of facts.
Because a
FactBase
can only holdPredicate
sub-class instances this member function has been overloaded to take either a singlePredicate
sub-class instance or a collection ofPredicate
sub-class instances.- Parameters
arg – a single fact or a collection of facts.
- asp_str(width=0, commented=False)¶
Return a string representation of the fact base that is suitable for adding to an ASP program
- clear()¶
Clear the fact base of all facts.
- copy()¶
Implements the set copy() function
- difference(*others)¶
Implements the set difference() function
- difference_update(*others)¶
Implements the set difference_update() function
- discard(arg)¶
Remove a fact from the fact base.
- facts()¶
Return all facts.
- intersection(*others)¶
Implements the set intersection() function
- intersection_update(*others)¶
Implements the set intersection_update() function
- pop()¶
Pop an element from the FactBase.
- query(*roots)¶
Define a query using the new Query API
Query
.The parameters consist of a predicates (or aliases) to query (like an SQL FROM clause).
- Parameters
*predicates – predicate or predicate aliases
- Returns
Returns a Query object for specifying a query.
- remove(arg)¶
Remove a fact from the fact base (raises an exception if no fact).
- select(root)¶
Define a select query using the old Query API.
Note
This interface will eventually be deprecated when the new
Query API
is finalised. The entry point to this Query API is through theFactBase.query()
method.- Parameters
predicate – The predicate to query.
- Returns
Returns a Select query object for specifying a query.
- symmetric_difference(other)¶
Implements the set symmetric_difference() function
- symmetric_difference_update(other)¶
Implements the set symmetric_difference_update() function
- union(*others)¶
Implements the set union() function
- update(*others)¶
Implements the set update() function
- property predicates¶
Return the list of predicate types that this fact base contains.
- class clorm.Placeholder¶
An abstract class for defining parameterised queries.
Currently, Clorm supports 4 placeholders: ph1_, ph2_, ph3_, ph4_. These correspond to the positional arguments of the query execute function call.
- class clorm.Select¶
An abstract class that defines the interface to original Query API.
Note
This interface will eventually be deprecated when the new
Query API
is finalised.Select
query objects cannot be constructed directly. Instead aSelect
object is returned by theFactBase.select()
function. Given aFactBase
objectfb
, a specification is of the form:query = fb.select(<predicate>).where(<expression>).order_by(<ordering>)
where
<predicate>
specifies the predicate type to search for,<expression>
specifies the search criteria and<ordering>
specifies a sort order when returning the results. Thewhere()
andorder_by()
clauses are omitted when not required.- abstract where(*expressions)¶
Set the select statement’s where clause.
The where clause consists of a set of boolean and comparison expressions. This expression specifies a search criteria for matching facts within the corresponding
FactBase
.Boolean expression are built from other boolean expression or a comparison expression. Comparison expressions are of the form:
<PredicatePath> <compop> <value>
where
<compop>
is a comparison operator such as==
,!=
, or<=
and<value>
is either a Python value or another predicate path object refering to a field of the same predicate or a placeholder.A placeholder is a special value that issubstituted when the query is actually executed. These placeholders are named
ph1_
,ph2_
,ph3_
, andph4_
and correspond to the 1st to 4th arguments of theget
,get_unique
orcount
function call.- Args:
expressions: one or more comparison expressions.
- Returns:
Returns a reference to itself.
- abstract order_by(*fieldorder)¶
Provide an ordering over the results.
- Parameters
fieldorder – an ordering over fields
- Returns
Returns a reference to itself.
- abstract get(*args, **kwargs)¶
Return all matching entries.
- get_unique(*args, **kwargs)¶
Return the unique matching entry (or raise an exception)
- count(*args, **kwargs)¶
Return the number of matches.
- class clorm.Delete¶
An abstract class that defines the interface to a original delete query API.
Note
This interface will eventually be deprecated when the new
Query API
is finalised.Delete
query objects cannot be constructed directly. Instead aDelete
object is returned by theFactBase.delete()
function. Given aFactBase
objectfb
, a specification is of the form:query = fb.delete(<predicate>).where(<expression>)
where
<predicate>
specifies the predicate type to search for,<expression>
specifies the search criteria. Thewhere()
clause can be omitted in which case all predicates of that type will be deleted.- abstract where(*expressions)¶
Set the select statement’s where clause.
See the documentation for
Select.where()
for further details.
- abstract execute(*args, **kwargs)¶
Function to execute the delete query
- class clorm.Query¶
An abstract class that defines the interface to the Clorm Query API v2.
Note
This new Query API replaces the old Select/Delete mechanism and offers many more features than the old API, especially allowing joins similar to an SQL join between tables.
This interface is complete and unlikely to change - however it is being left open for the moment in case there is strong user feedback.
Query
objects cannot be constructed directly.Instead a
Query
object is returned by theFactBase.query()
function. Queries can take a number of different forms but contain many of the components of a traditional SQL query. A predicate definition (as opposed to a predicate instance or fact) can be viewed as an SQL table and the parameters of a predicate can be viewed as the fields of the table.The simplest query must at least specify the predicate(s) to search for. This is specified as parameters to the
FactBase.query()
function. Relating this to a traditional SQL query, thequery
clause can be viewed as an SQLFROM
specification.The query is typicaly executed by iterating over the generator returned by the
Query.all()
end-point.from clorm import FactBase, Predicate, IntegerField, StringField class Option(Predicate): oid = IntegerField name = StringField cost = IntegerField cat = StringField class Chosen(Predicate): oid = IntegerField fb=FactBase([Option(1,"Do A",200,"foo"),Option(2,"Do B",300,"bar"), Option(3,"Do C",400,"foo"),Option(4,"Do D",300,"bar"), Option(5,"Do E",200,"foo"),Option(6,"Do F",500,"bar"), Chosen(1),Chosen(3),Chosen(4),Chosen(6)]) q1 = fb.query(Chosen) # Select all Chosen instances result = set(q1.all()) assert result == set([Chosen(1),Chosen(3),Chosen(4),Chosen(6)])
If there are multiple predicates involved in the search then the query must also contain a
Query.join()
clause to specify the predicates parameters/fields to join.q2 = fb.query(Option,Chosen).join(Option.oid == Chosen.oid)
Note
As an aside, while a
query
clause typically consists of predicates, it can also contain predicate aliases created through thealias()
function. This allows for queries with self joins to be specified.When a query contains multiple predicates the result will consist of tuples, where each tuple contains the facts matching the signature of predicates in the
query
clause. Mathematically the tuples are a subset of the cross-product over instances of the predicates; where the subset is determined by thejoin
clause.result = set(q2.all()) assert result == set([(Option(1,"Do A",200,"foo"),Chosen(1)), (Option(3,"Do C",400,"foo"),Chosen(3)), (Option(4,"Do D",300,"bar"),Chosen(4)), (Option(6,"Do F",500,"bar"),Chosen(6))])
A query can also contain a
where
clause as well as anorder_by
clause. When theorder_by
clause contains a predicate path then by default it is ordered in ascending order. However, this can be changed to descending order with thedesc()
function modifier.from clorm import desc q3 = q2.where(Option.cost > 200).order_by(desc(Option.cost)) result = list(q3.all()) assert result == [(Option(6,"Do F",500,"bar"),Chosen(6)), (Option(3,"Do C",400,"foo"),Chosen(3)), (Option(4,"Do D",300,"bar"),Chosen(4))]
The above code snippet highlights a feature of the query construction process. Namely, that these query construction functions can be chained and can also be used as the starting point for another query. Each construction function returns a modified copy of its parent. So in this example query
q3
is a modified version of queryq2
.Returning tuples of facts is often not the most convenient output format and instead you may only be interested in specific predicates or parameters within each fact tuple. For example, in this running example it is unnecessary to return the
Chosen
facts. To provide the output in a more useful format a query can also contain aselect
clause that specifies the items to return. Essentially, this specifies a _projection_ over the elements of the result tuple.q4 = q3.select(Option) result = list(q4.all()) assert result == [Option(6,"Do F",500,"bar"), Option(3,"Do C",400,"foo"), Option(4,"Do D",300,"bar")]
A second mechanism for accessing the data in a more convenient format is to use a
group_by
clause. In this example, we may want to aggregate all the chosen options, for example to sum the costs, based on their membership of the"foo"
and"bar"
categories. The Clorm query API doesn’t directly support aggregation functions, as you could do in SQL, so some additional Python code is required.q5 = q2.group_by(Option.cat).select(Option.cost) result = [(cat, sum(list(it))) for cat, it in q5.all()] assert result == [("bar",800), ("foo", 600)]
The above are not the only options for a query. Some other query modifies include:
Query.distinct()
to return distinct elements, andQuery.bind()
to bind the value of any placeholders in thewhere
clause to specific values.A query is executed using a number of end-point functions. As already shown the main end-point is
Query.all()
to return a generator for iterating over the results.Alternatively, if there is at least one element then to return the first result only (throwing an exception only if there are no elements) use the
Query.first()
method.Or if there must be exactly one element (and to throw an exception otherwise) use
Query.singleton()
.To count the elements of the result there is
Query.count()
.Finally to delete all matching facts from the underlying FactBase use
Query.delete()
.- abstract join(*expressions)¶
Specifying how the predicate/tables in the query are to be joined.
Joins are expressions that connect the predicates/tables of the query. They range from a pure SQL-like inner-join through to an unrestricted cross-product. The standard form is:
<PredicatePath> <compop> <PredicatePath>
with the full cross-product expressed using a function:
cross(<PredicatePath>,<PredicatePath>)
Every predicate/table in the query must be reachable to every other predicate/table through some form of join. For example, given predicate definitions
F
,G
,H
, each with a fieldanum
:query = fb.query(F,G,H).join(F.anum == G.anum,cross(F,H))
generates an inner join between
F
andG
, but a full cross-product betweenF
andH
.Finally, it is possible to perform self joins using the function
alias
that generates an alias for the predicate/table. For .. rubric:: Examplefrom clorm import alias
FA=alias(F)
query = fb.query(F,G,FA).join(F.anum == FA.anum,cross(F,G))
generates an inner join between
F
and itself, and a full cross-product betweenF
andG
.- Parameters
expressions – one or more join expressions.
- Returns
Returns the modified copy of the query.
- abstract where(*expressions)¶
Sets a list of query conditions.
The where clause consists of a single (or list) of simple/complex boolean and comparison expressions. This expression specifies a search criteria for matching facts within the corresponding
FactBase
.Boolean expression are built from other boolean expression or a comparison expression. Comparison expressions are of the form:
<PredicatePath> <compop> <value>
where
<compop>
is a comparison operator such as==
,!=
, or<=
and<value>
is either a Python value or another predicate path object refering to a field of the same predicate or a placeholder.A placeholder is a special value that allows queries to be parameterised. A value can be bound to each placeholder. These placeholders are named
ph1_
,ph2_
,ph3_
, andph4_
and correspond to the 1st to 4th arguments when thebind()
function is called. Placeholders also allow for named arguments using the “ph_(“<name>”) function.- Args:
expressions: one or more comparison expressions.
- Returns:
Returns the modified copy of the query.
- abstract order_by(*expressions)¶
Specify an ordering over the results.
- Parameters
field_order – an ordering over fields
- Returns
Returns the modified copy of the query.
- abstract group_by(*expressions)¶
Specify a grouping over the results.
The grouping specification is similar to an ordering specification but it modifies the behaviour of the query to return a pair of elements, where the first element of the pair is the group identifier (based on the specification) and the second element is an iterator over the matching elements.
When both a
group_by
andorder_by
clause is provided theorder_by
clause is used the sort the elements within each matching group.- Parameters
field_order – an ordering over fields to group by
- Returns
Returns the modified copy of the query.
- abstract select(*outsig)¶
Provides a projection over the query result tuples.
Mathematically the result tuples of a query are the cross-product over instances of the predicates. However, returning tuples of facts is often not the most convenient output format and instead you may only be interested in specific parameters/fields within each tuple of facts. The
select
clause specifies a _projection_ over each query result tuple.Note, each query result tuple is guaranteed to be distinct, since the query is a filtering over the cross-product of the predicate instances. However, the specification of a projection can result in information being discarded and can therefore cause the projected query results to no longer be distinct. To enforce uniqueness the
Query.distinct()
flag can be specified. Essentially this is the same as anSQL SELECT DISTINCT ...
statement.Note: when
Query.select()
is used with theQuery.delete()
end-point the select signature must specify predicates and not parameter/fields within the predicates.- Parameters
output_signature – the signature that defines the projection.
- Returns
Returns the modified copy of the query.
- abstract distinct()¶
Return only distinct elements in the query.
This flag is only meaningful when combined with a
Query.select()
clause that removes distinguishing elements from the tuples.- Returns
Returns the modified copy of the query.
- abstract bind(*args, **kwargs)¶
Bind placeholders to specific values.
If the
where
clause has placeholders then these placeholders must be bound to actual values before the query can be executed.- Parameters
*args – positional arguments corresponding to positional placeholders
**kwargs – named arguments corresponding to named placeholders
- Returns
Returns the modified copy of the query.
- abstract tuple()¶
Force returning a tuple even for singleton elements.
In the general case the output signature of a query is a tuple; consisting either of a tuple of facts or a tuple of parameters/fields if a
select
projection has been specified.However, if the output signature is a singleton tuple then by default the API changes its behaviour and removes the tuple, returning only the element itself. This typically provides a much more useful and intutive interface. For example, if you want to perform a sum aggregation over the results of a query, aggregating over the value of a specific parameter/field, then specifying just that parameter in the
select
clause allows you to simply pass the query generator to the standard Pythonsum()
function without needing to perform a list comprehension to extract the value to be aggregated.If there is a case where this default behaviour is not wanted then specifying the
tuple
flag forces the query to always return a tuple of elements even if the output signature is a singleton tuple.- Returns
Returns the modified copy of the query.
- abstract heuristic(join_order)¶
Allows the query engine’s query plan to be modified.
This is an advanced option that can be used if the query is not performing as expected. For multi-predicate queries the order in which the joins are performed can affect performance. By default the Query API will try to optimise this join order based on the
join
expressions; with predicates with more restricted joins being higher up in the join order.This join order can be controlled explicitly by the
fixed_join_order
heuristic function. Assuming predicate definitionsF
andG
the query:from clorm import fixed_join_order
query=fb.query(F,G).heuristic(fixed_join_order(G,F)).join(...)
forces the join order to first be the
G
predicate followed by theF
predicate.- Parameters
join_order – the join order heuristic
- Returns
Returns the modified copy of the query.
- abstract all()¶
Returns a generator that iteratively executes the query.
Note. This call doesn’t execute the query itself. The query is executed when iterating over the elements from the generator.
- Returns
Returns a generator that executes the query.
- abstract singleton()¶
Return the single matching element.
An exception is thrown if there is not exactly one matching element or a
group_by()
clause has been specified.- Returns
Returns the single matching element (or throws an exception)
- abstract count()¶
Return the number of matching element.
Typically the number of elements consist of the number of tuples produced by the cross-product of the predicates that match the criteria of the
join()
andwhere()
clauses.However, if a
select()
projection andunique()
flag is specified then thecount()
will reflect the modified the number of unique elements based on the projection of the query.Furthermore, if a
group_by()
clause is specified thencount()
returns a generator that iterates over pairs where the first element of the pair is the group identifier and the second element is the number of matching elements within that group.- Returns
Returns the number of matching elements
- abstract first()¶
Return the first matching element.
An exception is thrown if there are no one matching element or a
group_by()
clause has been specified.- Returns
Returns the first matching element (or throws an exception)
- abstract delete()¶
Delete matching facts from the
FactBase()
.In the simple case of a query with no joins then
delete()
simply deletes the matching facts. If there is a join then the matches consist of tuples of facts. In this casedelete()
will remove all facts from the tuple. This behaviour can be modified by using aselect()
projection clause that selects only specific predicates. Note: when combined withselect()
the output signature must specify predicates and not parameter/fields within predicates.An exception is thrown if a
group_by()
clause has been specified.- Returns
Returns the number of facts deleted.
- abstract query_plan(*args, **kwargs)¶
Return a query plan object outlining the query execution.
A query plan outlines the query will be executed; the order of table joins, the searches based on indexing, and how the sorting is performed. This is useful for debugging if the query is not behaving as expected.
Currently, there is no fixed specification for the query plan object. All the user can do is display it for reading and debugging purposes.
- Returns
Returns a query plan object that can be stringified.
- class clorm.PredicatePath(pathseq)¶
PredicatePath implements the intuitive query syntax.
Every defined
Predicate
sub-class has a correspondingPredicatePath
sub-class that mirrors its field definitions. This allows it to be used when specifying the components of a query; such as the sign and the fields or sub-fields of a predicate (eg.,Pred.sign
,Pred.a.b
orPred.a[0]
).When the API user refers to a field (or sign) of a Predicate sub-class they are redirected to the corresponding
PredicatePath
object of that predicate sub-class.While instances of this class (and sub-classes) are externally exposed through the API, users should not explicitly instantiate instances themselves.
Predicate path subclasses provide attributes and indexed items for refering to sub-paths. When a user specifies
Pred.a.b.c
thePredicate
sub-classPred
seemlessly passes off to an associatedPredicatePath
object, which then returns a path corresponding to the specifications.Fields can be specified either by name through a chain of attributes or using the array indexes. This is implemented in the overloaded
__getitem__
function which allows for name or positional argument specifications.The most important aspect of a predicate path object is that it overloads the boolean operators to return a comparison condition. This is what allows for query specifications such as
Pred.a.b == 2
orPred.a.b == ph1_
.Finally, because the name
meta
is a Clorm keyword and can’t be used as a field name it is used as a property referring to an internal class with functions for use by the internals of the library. API users should not use this property.
Query Support Functions¶
The following functions support the query specification.
- clorm.path(arg, exception=True)¶
Returns the
PredicatePath
corresponding to some component.This function is useful for users for the special case of referring to the
PredicatePath
that corresponding to aPredicate
object. For example to specify a comparison in a query to match a specific instance to some placeholder you need to reference the predicate using a path.Example:
from clorm import FactBase, Predicate, ConstantField, path class F(Predicate): a = ConstantField fb = FactBase([F("foo"),F("bar")]) qBad=fb.query(F).where(F == F("bar")) # This won't do what you expect qGood=fb.query(F).where(path(F) == F("bar"))
Note
The technical reason for not supporting the more intuitive syntax above is that it would require overloading the comparison operators of the predicate class itself; which would break the behaviour of Python in many other contexts.
- Returns
Returns a
PredicatePath
object corresponding to the input specification.
- clorm.alias(predicate, name=None)¶
Return an alias
PredicatePath
instance for aPredicate
sub-class.A predicate alias can be used to support self joins in queries. The alias has all the same fields (and sub-fields) as the “normal” path associated with the predicate.
For example, consider a simple (and not properly normalised) friend fact base with a predicate that uniquely identifies people and friends, by a id number, and you want to output the friend connections in an intuitive manner.
Example
from clorm import FactBase, Predicate, IntegerField, StringField, alias class F(Predicate): pid = IntegerField name = StringField fid = IntegerField fb=FactBase([F(1,"Adam",3),F(2,"Betty",4),F(3,"Carol",1),F(4,"Dan",2)]) FA = alias(F) q=fb.query(F,FA).join(F.pid == FA.fid).select(F.name,FA.name) for p,f in q.all(): print("Person {} => Friend {}".format(p,f))
- Returns
Returns an alias
PredicatePath
for the predicate.
- clorm.cross(*args)¶
Return a cross-product join condition
- clorm.ph_(value, *args, **kwargs)¶
A function for building new placeholders, either named or positional.
- clorm.not_(*conditions)¶
Return a boolean condition that is the negation of the input condition
- clorm.and_(*conditions)¶
Return a the conjunction of two of more conditions
- clorm.or_(*conditions)¶
Return the disjunction of two of more conditions
- clorm.in_(path, seq)¶
Return a query operator to test membership of an item in a collection
- clorm.notin_(path, seq)¶
Return a query operator to test non-membership of an item in a collection
Calling Python From an ASP Program¶
Clorm provides a number of decorators that can make it easier to call Python from within an ASP program. The basic idea is that Clorm provides all the information required to convert data between native Python types and clingo.Symbol objects. Therefore functions can be written by only dealing with Python data and the Clorm decorators will wrap these functions with the appropriate data conversions based on a given signature.
- clorm.make_function_asp_callable(*args)¶
A decorator for making a function callable from within an ASP program.
Can be called in a number of ways. Can be called as a decorator with or without arguments. If called with arguments then the arguments must correspond to a type cast signature.
A type cast signature specifies the type conversions required between a python function that is called from within an ASP program and a set of corresponding Python types.
A type cast signature is specified in terms of the fields that are used to define a predicate. It is a list of elements where the first n-1 elements correspond to type conversions for a functions inputs and the last element corresponds to the type conversion for a functions output.
- Parameters
sigs (*sigs) – A list of function signature elements.
[ (- Inputs. Match the sub-elements) – -1] define the input signature while the last element defines the output signature. Each input must be a a RawField (or sub-class).
Output (-) – Must be RawField (or sub-class) or a singleton list containing a RawField (or sub-class).
If no arguments are provided then the function signature is derived from the function annotations. The function annotations must conform to the signature above.
If called as a normal function with arguments then the last element must be the function to be wrapped and the previous elements conform to the signature profile.
- clorm.make_method_asp_callable(*args)¶
A decorator for making a member function callable from within an ASP program.
See
make_function_asp_callable
for details. The only difference is that the first element of the function is ignore as it is assumed to be theself
orcls
parameter.
It may also be useful to deal with a predeclared type cast signature.
- class clorm.TypeCastSignature(*sigs)¶
Defines a signature for converting to/from Clingo data types.
- Args:
sigs(*sigs): A list of signature elements.
Inputs. Match the sub-elements [:-1] define the input signature while the last element defines the output signature. Each input must be a RawField (or sub-class).
Output: Must be RawField (or sub-class) or a singleton list containing a RawField (or sub-class).
Example
import datetime class DateField(StringField): pytocl = lambda dt: dt.strftime("%Y%m%d") cltopy = lambda s: datetime.datetime.strptime(s,"%Y%m%d").date() drsig = TypeCastSignature(DateField, DateField, [DateField]) @drsig.make_clingo_wrapper def date_range(start, end): return [ start + timedelta(days=x) for x in range(0,end-start) ]
The function
date_range
that takes a start and end date and returns the list of dates within that range.When decorated with the signature it provides the conversion code so that the decorated function expects a start and end date encoded as Clingo.String objects (matching YYYYMMDD format) and returns a list of Clingo.String objects corresponding to the dates in that range.
- static is_return_element(se)¶
An output element must be an output field or a singleton iterable containing an output fields; where an output field is a RawField sub-class or tuple that recursively reduces to a RawField sub-class.
- wrap_function(fn)¶
Function wrapper that adds data type conversions for wrapped function.
- Parameters
fn – A function satisfing the inputs and output defined by the TypeCastSignature.
- wrap_method(fn)¶
Member function wrapper that adds data type conversions for wrapped member functions.
- Parameters
fn – A function satisfing the inputs and output defined by the TypeCastSignature.
From Clingo 5.4 onwards, the Clingo grounding function allows a context parameter to be specified. This parameter defines a context object for the methods that are called by ASP using the @-syntax.
- class clorm.ContextBuilder¶
Context builder simplifies the task of building grounding context for clingo. This is a new clingo feature for Clingo 5.4 where a context can be provided to the grounding function. The context encapsulates the external Python functions that can be called from within an ASP program.
ContextBuilder
allows arbitrary functions to be captured within a context and assigned a conversion signature. It also allows the function to be given a different name when called from within the context.The context builder’s
register
andregister_name
member functions can be called as decorators or as normal functions. A useful feature of these functions is that when called as decorators they do not wrap the original function but instead return the original function and only wrap the function when called from within the context. This is unlike themake_function_asp_callable
andmake_method_asp_callable
functions which when called as decorators will replace the original function with the wrapped version.Example:
The following nonsense ASP program contains embedded python with functions registered with the context builder (highlighting different ways the register functions can be called). A context object is then created by the context builder and used during grounding. It will produce the answer set:
f(5), g(6), h("abcd").
f(@addi(1,4)). g(@addi_alt(2,4)). h(@adds("ab","cd")). #script(python). from clorm import IntegerField,StringField,ContextBuilder IF=IntegerField SF=StringField cb=ContextBuilder() # Uses the function annotation to define the conversion signature @cb.register def addi(a : IF, b : IF) -> IF : return a+b # Register with a different name @cb.register_name("addi_alt") def add2(a : IF, b : IF) -> IF : return a+b # Register with a different name and override the signature in the # function annotation cb.register_name("adds", SF, SF, SF, addi) ctx=cb.make_context() def main(prg): prg.ground([("base",[])],context=ctx) prg.solve() #end.
- make_context(cls_name='Context')¶
Return a context object that encapsulates the registered functions
- register(*args)¶
Register a function with the context builder.
- Parameters
*args – the last argument must be the function to be registered. If there is more than one argument then the earlier arguments define the data conversion signature. If there are no earlier arguments then the signature is extracted from the function annotations.
- register_name(func_name, *args)¶
Register a function with assigning it a new name witin the context.
- Parameters
func_name – the new name for the function within the context.
*args – the last argument must be the function to be registered. If there is more than one argument then the earlier arguments define the data conversion signature. If there are no earlier arguments then the signature is extracted from the function annotations.
Integration with the Solver¶
To simplify the interaction with the Clingo solver, Clorm provides a clingo
replacement module that offers better integration with Clorm facts and fact
bases. This module simply wraps and extends a few key Clingo classes.
Instead of:
import clingo
use:
import clorm.clingo
For convenience the clingo.Control
class can also be monkey patched so that it can used seemlessly
with existing code bases.
from clorm import monkey; monkey.patch()
import clingo
Here we document only the extended classes and the user is referred to the Clingo API documentation for more details.
- class clorm.clingo.Control(*args, **kwargs)¶
Control object for the grounding/solving process.
Behaves like
clingo.Control
but with modifications to deal with Clorm facts and fact bases.Adds an additional parameter
unifier
to specify how any generated clingo models will be unified with the clorm Predicate definitions. The unifier can be specified as a list of predicates or as a SymbolPredicateUnifier object.An existing
clingo.Control
object can be passed using thecontrol_
parameter.Control object for the grounding/solving process.
- Parameters
arguments – Arguments to the grounder and solver.
logger – Function to intercept messages normally printed to standard error.
message_limit – The maximum number of messages passed to the logger.
Notes
Note that only gringo options (without –text) and clasp’s search options are supported. Furthermore, you must not call any functions of a Control object while a solve call is active.
- add(name: str, parameters: Sequence[str], program: str) None ¶
Extend the logic program with the given non-ground logic program in string form.
- Parameters
name – The name of program block to add.
parameters – The parameters of the program block to add.
program – The non-ground program in string form.
See also
- add_facts(facts)¶
Add facts to the control object. Note: facts must be added before grounding.
This function can take an arbitrary collection containing a mixture of
clorm.Predicate
andclingo.Symbol
objects. Aclorm.FactBase
is also a valid collection but it can only containclorm.Predicate
instances.- Parameters
facts – a collection of
clorm.Predicate
orclingo.Symbol
objects
- assign_external(external, truth)¶
Assign a truth value to an external fact (or collection of facts)
A fact can be a raw clingo.Symbol object, a clorm.Predicate instance, or a program literal (an int). If the external is a collection then the truth value is assigned to all elements in the collection.
This function extends
clingo.Control.release_external
.Assign a truth value to an external atom.
- Parameters
external – A symbol or program literal representing the external atom.
truth – A Boolean fixes the external to the respective truth value; and None leaves its truth value open.
See also
Control.release_external
,clingo.solving.SolveControl.symbolic_atoms
,clingo.symbolic_atoms.SymbolicAtom.is_external
Notes
The truth value of an external atom can be changed before each solve call. An atom is treated as external if it has been declared using an #external directive, and has not been released by calling Control.release_external or defined in a logic program with some rule. If the given atom is not external, then the function has no effect.
For convenience, the truth assigned to atoms over negative program literals is inverted.
- backend() clingo.backend.Backend ¶
Returns a Backend object providing a low level interface to extend a logic program.
See also
clingo.backend
- cleanup() None ¶
Cleanup the domain used for grounding by incorporating information from the solver.
This function cleans up the domain used for grounding. This is done by first simplifying the current program representation (falsifying released external atoms). Afterwards, the top-level implications are used to either remove atoms from the domain or mark them as facts.
See also
Notes
Any atoms falsified are completely removed from the logic program. Hence, a definition for such an atom in a successive step introduces a fresh atom.
With the current implementation, the function only has an effect if called after solving and before any function is called that starts a new step.
Typically, it is not necessary to call this function manually because automatic cleanups are enabled by default.
- get_const(name: str) Optional[clingo.symbol.Symbol] ¶
Return the symbol for a constant definition of form:
#const name = symbol.
- Parameters
name – The name of the constant to retrieve.
- Returns
- Return type
The function returns None if no matching constant definition exists.
- ground(parts: Sequence[Tuple[str, Sequence[clingo.symbol.Symbol]]], context: Any = None) None ¶
Ground the given list of program parts specified by tuples of names and arguments.
- Parameters
parts – List of tuples of program names and program arguments to ground.
context – A context object whose methods are called during grounding using the @-syntax (if omitted, those from the main module are used).
Notes
Note that parts of a logic program without an explicit #program specification are by default put into a program called base without arguments.
- interrupt() None ¶
Interrupt the active solve call.
Notes
This function is thread-safe and can be called from a signal handler. If no search is active, the subsequent call to Control.solve is interrupted. The result of the Control.solve method can be used to query if the search was interrupted.
- load(path: str) None ¶
Extend the logic program with a (non-ground) logic program in a file.
- Parameters
path – The path of the file to load.
- register_observer(observer: clingo.backend.Observer, replace: bool = False) None ¶
Registers the given observer to inspect the produced grounding.
- Parameters
observer – The observer to register. See below for a description of the requirede interface.
replace – If set to true, the output is just passed to the observer and nolonger to the underlying solver (or any previously registered observers).
See also
clingo.backend
- register_propagator(propagator: clingo.propagator.Propagator) None ¶
Registers the given propagator with all solvers.
- Parameters
propagator – The propagator to register.
See also
clingo.propagator
- release_external(external)¶
Release an external fact (or collection of facts)
A fact can be a raw clingo.Symbol object, a clorm.Predicate instance, or a program literal (an int). If the external is a collection then the truth value is assigned to all elements in the collection.
This function extends
clingo.Control.release_external
.Release an external atom represented by the given symbol or program literal.
This function causes the corresponding atom to become permanently false if there is no definition for the atom in the program. Otherwise, the function has no effect.
- Parameters
external – The symbolic atom or program atom to release.
Notes
If the program literal is negative, the corresponding atom is released.
Examples
The following example shows the effect of assigning and releasing and external atom.
>>> from clingo.symbol import Function >>> from clingo.control import Control >>> >>> ctl = Control() >>> ctl.add("base", [], "a. #external b.") >>> ctl.ground([("base", [])]) >>> ctl.assign_external(Function("b"), True) >>> print(ctl.solve(on_model=print)) b a SAT >>> ctl.release_external(Function("b")) >>> print(ctl.solve(on_model=print)) a SAT
- solve(*args, **kwargs)¶
Run the clingo solver.
This function extends
clingo.Control.solve()
in two ways:1) The
assumptions
argument is generalised so that in the list of argument-boolean pairs the argument can be be a clingo symbol, or clorm predicate instance, or a collection of clingo symbols or clorm predicates.2) It produces either a
clorm.clingo.SolveHandle
wrapper object or aclorm.clingo.Model
wrapper objects as appropriate (depending on theyield_
,async_
, andon_model
parameters).Starts a search.
- Parameters
assumptions – List of (atom, boolean) tuples or program literals (see clingo.symbolic_atoms.SymbolicAtom.literal) that serve as assumptions for the solve call, e.g., solving under assumptions [(Function(“a”), True)] only admits answer sets that contain atom a.
on_model – Optional callback for intercepting models. A clingo.solving.Model object is passed to the callback. The search can be interruped from the model callback by returning False.
on_unsat – Optional callback to intercept lower bounds during optimization.
on_statistics – Optional callback to update statistics. The step and accumulated statistics are passed as arguments.
on_finish – Optional callback called once search has finished. A clingo.solving.SolveResult also indicating whether the solve call has been intrrupted is passed to the callback.
on_core – Optional callback called with the assumptions that made a problem unsatisfiable.
yield – The resulting clingo.solving.SolveHandle is iterable yielding clingo.solving.Model objects.
async – The solve call and the method clingo.solving.SolveHandle.resume of the returned handle are non-blocking.
- Returns
The return value depends on the parameters. If either yield_ or
async_ is true, then a handle is returned. Otherwise, a
clingo.solving.SolveResult is returned.
See also
clingo.solving
Notes
If neither yield_ nor async_ is set, the function returns a clingo.solving.SolveResult right away.
In gringo or in clingo with lparse or text output enabled, this function just grounds and returns a clingo.solving.SolveResult where clingo.solving.SolveResult.unknown is true.
If this function is used in embedded Python code, you might want to start clingo using the –outf=3 option to disable all output from clingo.
Asynchronous solving is only available in clingo with thread support enabled. Furthermore, the on_model and on_finish callbacks are called from another thread. To ensure that the methods can be called, make sure to not use any functions that block Python’s GIL indefinitely.
This function as well as blocking functions on the clingo.solving.SolveHandle release the GIL but are not thread-safe.
- property configuration¶
Object to change the configuration.
- property control_¶
Returns the underlying clingo.Control object.
- property enable_cleanup¶
Whether to enable automatic calls to Control.cleanup.
- property enable_enumeration_assumption¶
Whether do discard or keep learnt information from enumeration modes.
If the enumeration assumption is enabled, then all information learnt from clasp’s various enumeration modes is removed after a solve call. This includes enumeration of cautious or brave consequences, enumeration of answer sets with or without projection, or finding optimal models; as well as clauses added with clingo.solving.SolveControl.add_clause.
Notes
Initially the enumeration assumption is enabled.
In general, the enumeration assumption should be enabled whenever there are multiple calls to solve. Otherwise, the behavior of the solver will be unpredictable because there are no guarantees which information exactly is kept. There might be small speed benefits when disabling the enumeration assumption for single shot solving.
- property is_conflicting¶
Whether the internal program representation is conflicting.
If this (read-only) property is true, solve calls return immediately with an unsatisfiable solve result.
Notes
Conflicts first have to be detected, e.g., initial unit propagation results in an empty clause, or later if an empty clause is resolved during solving. Hence, the property might be false even if the problem is unsatisfiable.
- property statistics¶
A dict containing solve statistics of the last solve call.
See also
clingo.statistics
Notes
The statistics correspond to the –stats output of clingo. The detail of the statistics depends on what level is requested on the command line. Furthermore, there are some functions like Control.release_external that start a new solving step resetting the current step statistics. It is best to access the statistics right after solving.
This property is only available in clingo.
- property symbolic_atoms¶
An object to inspect the symbolic atoms.
See also
clingo.symbolic_atoms
- property theory_atoms¶
An iterator over the theory atoms in a program.
See also
clingo.theory_atoms
- property unifier¶
Get/set the unifier.
Unifier can be specified as a SymbolPredicateUnifier or a collection of Predicates. Always returns a SymbolPredicateUnifier (or None).
- class clorm.clingo.Model(model, unifier=None)¶
Provides access to a model during a solve call.
Objects mustn’t be created manually. Instead they are returned by
clorm.clingo.Control.solve
callbacks.Behaves like
clingo.Model
but offers better integration with clorm facts and fact bases.Provides access to a model during a solve call and provides a SolveContext object to influence the running search.
Notes
The string representation of a model object is similar to the output of models by clingo using the default output.
Model objects cannot be constructed from Python. Instead they are obained during solving (see Control.solve). Furthermore, the lifetime of a model object is limited to the scope of the callback it was passed to or until the search for the next model is started. They must not be stored for later use.
- contains(fact)¶
Return whether the fact or symbol is contained in the model. Extends
clingo.Model.contains
to allow for clorm facts as well as a clingo symbols.Efficiently check if an atom is contained in the model.
- Parameters
atom – The atom to lookup.
- Returns
- Return type
Whether the given atom is contained in the model.
Notes
The atom must be represented using a function symbol.
- extend(symbols: Sequence[clingo.symbol.Symbol]) None ¶
Extend a model with the given symbols.
- Parameters
symbols – The symbols to add to the model.
Notes
This only has an effect if there is an underlying clingo application, which will print the added symbols.
- facts(*args, **kwargs)¶
Returns a FactBase containing the facts in the model that unify with the SymbolPredicateUnifier.
This function provides a wrapper around the
clingo.Model.symbols
functions, but instead of returning a list of symbols it returns a FactBase containing the facts represented asclorm.Predicate
sub-class instances.- Parameters
unifier (list | SymbolPredicateUnifier) – used to unify and instantiate FactBase (Default: passed via the constructor if specified in the clorm.clingo.Control object)
atoms – select all atoms in the model (Default: False)
terms – select all terms displayed with #show statements (Default: False)
shown – select all atoms and terms (Default: False)
raise_on_empty – raise a ValueError if the resulting FactBase is empty (Default: False)
- is_true(literal: int) bool ¶
Check if the given program literal is true.
- Parameters
literal – The given program literal.
- Returns
- Return type
Whether the given program literal is true.
- symbols(atoms: bool = False, terms: bool = False, shown: bool = False, csp: bool = False, theory: bool = False, complement: bool = False) List[clingo.symbol.Symbol] ¶
Return the list of atoms, terms, or CSP assignments in the model.
- Parameters
atoms – Select all atoms in the model (independent of #show statements).
terms – Select all terms displayed with #show statements in the model.
shown – Select all atoms and terms as outputted by clingo.
csp – Select all csp assignments (independent of #show statements).
theory – Select atoms added with Model.extend.
complement – Return the complement of the answer set w.r.t. to the atoms known to the grounder. (Does not affect csp assignments.)
- Returns
- Return type
The selected symbols.
Notes
Atoms are represented using functions (Symbol objects), and CSP assignments are represented using functions with name “$” where the first argument is the name of the CSP variable and the second its value.
- property context¶
Object that allows for controlling the running search.
- property cost¶
Return the list of integer cost values of the model.
The return values correspond to clasp’s cost output.
- property model_¶
Returns the underlying clingo.Model object.
- property number¶
The running number of the model.
- property optimality_proven¶
Whether the optimality of the model has been proven.
- property thread_id¶
The id of the thread which found the model.
- property type¶
The type of the model.
- class clorm.clingo.SolveHandle(handle, unifier=None)¶
Handle for solve calls.
Objects mustn’t be created manually. Instead they are returned by
clorm.clingo.Control.solve
.Behaves like
clingo.SolveHandle
but iterates overclorm.clingo.Model
objects.Handle for solve calls.
They can be used to control solving, like, retrieving models or cancelling a search.
See also
Notes
A SolveHandle is a context manager and must be used with Python’s with statement.
Blocking functions in this object release the GIL. They are not thread-safe though.
- cancel() None ¶
Cancel the running search.
See also
clingo.control.Control.interrupt
- core() List[int] ¶
The subset of assumptions that made the problem unsatisfiable.
- get() clingo.solving.SolveResult ¶
Get the result of a solve call.
If the search is not completed yet, the function blocks until the result is ready.
- model() Optional[clingo.solving.Model] ¶
Get the current model if there is any.
- resume() None ¶
Discards the last model and starts searching for the next one.
Notes
If the search has been started asynchronously, this function starts the search in the background.
- wait(timeout: Optional[float] = None) bool ¶
Wait for solve call to finish or the next result with an optional timeout.
If a timeout is given, the behavior of the function changes depending on the sign of the timeout. If a postive timeout is given, the function blocks for the given amount time or until a result is ready. If the timeout is negative, the function will block until a result is ready, which also corresponds to the behavior of the function if no timeout is given. A timeout of zero can be used to poll if a result is ready.
- Parameters
timeout – If a timeout is given, the function blocks for at most timeout seconds.
- Returns
- Return type
Indicates whether the solve call has finished or the next result is ready.
- property solvehandle_¶
Access the underlying clingo.SolveHandle object.
Experimental Features¶
The following are experimental features and may be modified or removed completely from the library in future versions.
JSON Encoding and Decoding¶
Note
Don’t use these function.I think converting to/from JSON would be better served by using a third-party library like Pydantic. One option for the future would be to look at ways of automatically generating Pydantic data models from Clorm data models and offering convenience functions for converting between the two.
Clorm allows clingo.Symbols, Predicates, and FactBases to be translated to/from JSON.
- class clorm.json.FactBaseCoder(predicates=[])¶
A JSON Encoder/Decoder for clingo.Symbols, predicate instances, and fact bases.
Provides a helper class for encoding and decoding facts to JSON. The predicates of interest are passed in the constructor or can be registered using a decorator.
- Parameters
predicates ([Predicate]) – a list of predicates to handle encoding/decoding
- decoder(obj)¶
JSON Decoder for clingo.Symbol, clorm.Predicate, and clorm.FactBase.
Call by overiding the
object_hook
argument for json.load(s)return json.dumps(obj, default=self.encoder)
- class Fun(Predicate):
aint = IntegerField()
fc = FactCoder(predicates=[Fun]) return json.loads(json_str, object_hook=fc.encoder)
- Parameters
json_object – a json encoded object
- dump(obj, fp, indent=None, sort_keys=False)¶
A convenience function for calling json.dump
- dumps(obj, indent=None, sort_keys=False)¶
A convenience function for calling json.dumps
- encoder(obj)¶
JSON Encoder for clingo.Symbol, clorm.Predicate, and clorm.FactBase.
Call by overiding the
default
argument for json.dump(s)- class Fun(Predicate):
aint = IntegerField()
fc = FactCoder(predicates=[Fun]) return json.dumps([Fun(aint=1), Fun(aint2)], default=fc.encoder)
- Parameters
obj – an object to encode as json
- load(fp)¶
A convenience function for calling json.load
- loads(json_str)¶
A convenience function for calling json.loads
- register(cls)¶
Decorator to register a Predicate sub-class with the FactBaseCoder
- clorm.json.symbol_encoder(s)¶
A JSON encoder for clingo.Symbol objects.
Example usage: sym = clingo.Function(“afact”, [clingo.Number(1)]) json_str = json.dumps(sym, default=encoder)
- Parameters
symbol (clingo.Symbol) – a symbol object
- clorm.json.symbol_decoder(obj)¶
A JSON Decoder for clingo.Symbol objects.
Example usage: symbol = json.loads(json, default=encoder)
- Parameters
obj – a JSON object