Source code for prodigy.pgcl.pysmt.context
# pylint: disable=broad-exception-raised # style as taken over from probably
"""
-------------------
Translation Context
-------------------
The translation of pGCL programs to pySMT requires a few details to be known:
How to translate variables to pySMT, how to handle infinities, and so on. The
:py:class:`TranslationContext` handles all that.
"""
from typing import Dict, Optional
import attr
from pysmt.fnode import FNode
from pysmt.shortcuts import Symbol
from pysmt.typing import BOOL, INT, REAL
from prodigy.pgcl.ast import BoolType, NatType, Program, RealType, Type, Var
def _translate_type(typ: Type):
if isinstance(typ, BoolType):
return BOOL
elif isinstance(typ, NatType):
# pylint: disable=fixme
return INT # TODO: return bounds?
elif isinstance(typ, RealType):
return REAL
raise Exception("unreachable")
[docs]
@attr.s(init=False)
class TranslationContext:
"""
Context used for translation of pGCL parts.
"""
variables: Dict[Var, FNode] = attr.ib()
infinity: FNode = attr.ib()
id_subst: Dict[FNode, FNode] = attr.ib()
def __init__(self,
variables: Dict[Var, FNode],
infinity: Optional[FNode] = None,
id_subst: Optional[Dict[FNode, FNode]] = None):
if infinity is None:
infinity = Symbol("_infinity", REAL)
if id_subst is None:
id_subst = {var: var for var in variables.values()}
self.variables = variables
self.infinity = infinity
self.id_subst = id_subst
[docs]
@staticmethod
def from_program(program: Program) -> "TranslationContext":
"""
Create a new TranslationContext from a pGCL program's declared
variables.
"""
variables = {
var: Symbol(var, _translate_type(typ))
for var, typ in program.variables.items()
}
return TranslationContext(variables)