Source code for clinguin.server.application.backends.clingodl_backend
"""
Module that contains the ClingoDL Backend.
"""
import textwrap
from clingo.ast import ProgramBuilder, parse_files
from clingo.script import enable_python
from clingodl import ClingoDLTheory
from clinguin.server.application.backends.clingo_backend import (
ClingoBackend,
)
from clinguin.utils.annotations import extends
enable_python()
# pylint: disable=attribute-defined-outside-init
[docs]class ClingoDLBackend(ClingoBackend):
"""
Backend that allows programs using clingodl theory atoms as input.
It also includes the assignment in the domain state.
"""
# ---------------------------------------------
# Setups
# ---------------------------------------------
@extends(ClingoBackend)
def _init_command_line(self):
"""
Sets the dl configuration
"""
super()._init_command_line()
dl_config = (
[a.split("=") for a in self._args.dl_config] if self._args.dl_config else []
)
self._dl_conf = [(a[0], a[1]) for a in dl_config]
@extends(ClingoBackend)
def _init_interactive(self):
"""
Initializes the list of the assignments
Attributes:
_assignment (List[Tuple[str, int]]): The list of assignments
"""
super()._init_interactive()
self._assignment = []
@extends(ClingoBackend)
def _init_ds_constructors(self):
super()._init_ds_constructors()
self._add_domain_state_constructor("_ds_assign")
@extends(ClingoBackend)
def _create_ctl(self):
"""
Registers the ClingoDLTheory.
"""
super()._create_ctl()
self._theory = ClingoDLTheory()
for k, v in self._dl_conf:
self._theory.configure(k, v)
self._theory.register(self._ctl)
@extends(ClingoBackend)
def _load_file(self, f):
"""
Uses the program builder to rewrite the theory atoms.
"""
with ProgramBuilder(self._ctl) as bld:
parse_files([f], lambda ast: self._theory.rewrite_ast(ast, bld.add))
@extends(ClingoBackend)
def _outdate(self):
"""
Sets the assignment to empty.
"""
super()._outdate()
self._assignment = []
# ---------------------------------------------
# Solving
# ---------------------------------------------
@extends(ClingoBackend)
def _prepare(self):
"""
Prepares the theory before solving
"""
# pylint: disable=attribute-defined-outside-init
self._theory.prepare(self._ctl)
@extends(ClingoBackend)
def _on_model(self, model):
"""
Sets the assignment from the model
"""
super()._on_model(model)
self._theory.on_model(model)
# pylint: disable=attribute-defined-outside-init
self._assignment = list(
(key, val) for key, val in self._theory.assignment(model.thread_id)
)
# ---------------------------------------------
# Class methods
# ---------------------------------------------
@classmethod
@extends(ClingoBackend)
def register_options(cls, parser):
"""
Adds the `dl-config` option.
"""
ClingoBackend.register_options(parser)
parser.add_argument(
"--dl-config",
help=textwrap.dedent(
"""\
Clingo-dl options list of <parameter>=<value>.
"""
),
nargs="*",
)
# ---------------------------------------------
# Domain state
# ---------------------------------------------
@property
def _ds_assign(self):
"""
Adds program with assignments
Includes predicate ``_clinguin_assign/2`` with the assignments.
"""
if not self._ui_uses_predicate("_clinguin_assign", 2):
return "% NOT USED\n"
prg = ""
for key, val in self._assignment:
prg += f"_clinguin_assign({key},{val})."
return prg