Fact Utils#

Generating facts in the expected format can be tedious. To make it easier to put data into and get data our of Draco, we provide an API to convert nested data to facts and vice versa.

Available functions#

class draco.fact_utils.FactKind(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

The kind of ASP fact.

Attributes:
ENTITY:

a nested entity (“is a” relationship)

ATTRIBUTE:

an attribute (value)

draco.fact_utils.answer_set_to_dict(answer_set, root=ROOT)#

A generic decoder that converts an answer set into a nested data structure. The inverse of this function is dict_to_facts.

Return type:

Mapping

draco.fact_utils.collect_children(name, collector)#

Helper function to collect the children for a name into a dictionary.

draco.fact_utils.dict_to_facts(data, path=(), parent=ROOT, id_generator=None)#

A generic encoder for dictionaries as answer set programming facts.

The encoder can convert dictionaries as well as lists (generating identifiers as numbers).

The inverse of this function is answer_set_to_dict.

Return type:

list[str]

draco.fact_utils.get_value(symbol)#

Get the value of a Clingo symbol.

draco.fact_utils.make_fact(kind, values=[])#

Create an ASP fact from a list of values. The function generates either attribute or entity facts.

Return type:

str

Usage Example#

from pprint import pprint

from draco import answer_set_to_dict, dict_to_facts, run_clingo
facts = dict_to_facts(
    {
        "mark": "bar",
        "encoding": [
            {"channel": "x", "field": "condition"},
            {"channel": "y", "aggregate": "count"},
        ],
    }
)
facts
['attribute(mark,root,bar).',
 'entity(encoding,root,0).',
 'attribute((encoding,channel),0,x).',
 'attribute((encoding,field),0,condition).',
 'entity(encoding,root,1).',
 'attribute((encoding,channel),1,y).',
 'attribute((encoding,aggregate),1,count).']
# we can run Clingo and convert the model back into the nested representation

for model in run_clingo(facts):
    answer_set = model.answer_set
    print(answer_set)
    pprint(answer_set_to_dict(answer_set))
[attribute(mark,root,bar), attribute((encoding,channel),0,x), attribute((encoding,field),0,condition), attribute((encoding,channel),1,y), attribute((encoding,aggregate),1,count), entity(encoding,root,0), entity(encoding,root,1)]
{'encoding': [{'channel': 'x', 'field': 'condition'},
              {'aggregate': 'count', 'channel': 'y'}],
 'mark': 'bar'}