Experimental Features
Warning
The following are experimental features that shouldn’t be considered part of the official Clorm API. It is not meant to be used and mostly for exploring and developing ideas.
Reusable Components
This is a work in progress
The goal is to slowly build up a comprehensive set of Clorm components (definitions and functions) that could be used to build readable ASP programs that can be easily integrated into Python applications.
Library components that are currently in the works:
date: Contains definitions and functions for dealing with dates and enumerated dates.
timeslot: This library will help to deal with blocks of time; for example dividing a day into 15 minute blocks.
JSON Encoding and Decoding
Clorm provides functions for encoding and decoding facts as JSON. The motivation is to be able to pass around facts between different processes. For example, you may want to generate a problem instance as part of a main web application but then pass off the problem instance to a worker processes that actually calls the solver.
Note
The JSON encoding of the clingo.Symbol objects generated here is not the same
as running clingo with the --outf=2
argument. The output here is intended
as an format for passing around facts between processes and not to be
particularly human readable. In contrast the clingo output in more human
readable but would require parsing to regenerate the original symbol objects.
The FactBaseCoder
class is a helper class to be able to encode/decode JSON for
particular Predicate sub-classes. The predicates can be supplied at
construction.
from clorm import Predicate
from clorm.json import FactBaseCoder
class Afact(Predicate):
aint: int
astr: str
fb_coder = FactBaseCoder([Afact])
Alternatively, the FactBaseCoder
can also be used as a decorator to register
predicates.
from clorm import Predicate
from clorm.json import FactBaseCoder
fb_coder = FactBaseCoder()
class Fun(Predicate):
aint: int
astr: str
class Tup(Predicate, name=""):
aint: int
astr: str
@fb_coder.register
class Afact(Predicate):
aint: int
afun: Fun
@fb_coder.register
class Bfact(Predicate):
astr: str
atup: Tup
Once the fact coder has been created and the appropriate predicates registered,
it then provides encoder
and decoder
member functions that can be used
with the standard Python JSON functions.
Assuming the above code:
import json
afact1 = Afact(aint=10, afun=Fun(aint=1, astr="a"))
afact2 = Afact(aint=20, afun=Fun(aint=2, astr="b"))
bfact1 = Bfact(astr="aa", atup=Tup(aint=1, astr="a"))
bfact2 = Bfact(astr="bb", atup=Tup(aint=2, astr="b"))
json_str = json.dumps([afact1,afact2,bfact1,bfact2], default=fb_coder.encoder)
facts = json.loads(json_str, object_hook=fb_coder.decoder)
As a convenience the fact coder provides member functions: dump
, dumps
,
load
, loads
that call the respective json functions with the appropriate
encoder and decoder functions. So the above calls to the json functions can be
simplified to:
json_str = fb_coder.dumps([afact1,afact2,bfact1,bfact2])
facts = fb_coder.loads(json_str)