def eval_term_sym(s: str) -> Symbol: """ Evaluate the given theory term and return its string representation. """ ctl = Control() ctl.add( "base", [], f""" #theory test {{ t {{ + : 3, unary; - : 3, unary; ? : 3, unary; ? : 3, binary, left; ** : 2, binary, right; * : 1, binary, left; / : 1, binary, left; \\ : 1, binary, left; + : 0, binary, left; - : 0, binary, left }}; &a/0 : t, head }}. &a {{{s}}}. """) ctl.ground([("base", [])]) for x in ctl.theory_atoms: return evaluate(x.elements[0].terms[0]) assert False
def _incremental(ctl: Control): ctl.add('step0', [], 'a :- b. b :- a. {a;b}.') ctl.ground([('step0', [])]) ctl.solve() ctl.add('step1', [], 'c :- d. d :- c. {c;d}.') ctl.ground([('step1', [])]) ctl.solve()
def test_basic_example(): "Example taken from clingo module documentation: https://potassco.org/clingo/python-api/5.5/clingo/index.html" from clingo.symbol import Number from clingo.control import Control class Context: def inc(self, x): return Number(x.number + 1) def seq(self, x, y): return [x, y] def on_model(m): print(repr(m), m, dir(m)) assert False, "Clingo module seems to have python support. Some test on the output model are to be done (just be sure there is a `a` atom). Model: " + repr( m) assert clyngor.have_python_support() ctl = Control() try: ctl.add("base", [], "a. #script(python) #end.") except RuntimeError as err: # case where python support is not implemented assert err.args == ( '<block>:1:4-25: error: python support not available\n', ) assert not clyngor.have_python_support() else: # python support available ctl.ground([("base", [])], context=Context()) ctl.solve(on_model=on_model)
def main(self, ctl: Control, files: Sequence[str]): ''' Register the difference constraint propagator, and then ground and solve. ''' ctl.register_propagator(self._propagator) ctl.add("base", [], THEORY) if not files: files = ["-"] self._rewrite(ctl, files) ctl.ground([("base", [])]) if self._minimize is None: ctl.solve(on_model=self._propagator.on_model) else: ctl.add("bound", ["b", "v"], "&diff(head) { v-0 } <= b.") while cast(SolveResult, ctl.solve(on_model=self._on_model)).satisfiable: print("Found new bound: {}".format(self._bound)) if self._bound is None: break ctl.ground([ ("bound", [Number(cast(int, self._bound) - 1), self._minimize]) ]) if self._bound is not None: print("Optimum found")
def reify_program(prg: str, calculate_sccs: bool = False, reify_steps: bool = False) -> List[Symbol]: ''' Reify the given program and return the reified symbols. Parameters ---------- prg The program to reify in form of a string. calculate_sccs Whether to calculate SCCs of the reified program. reify_steps Whether to add a step number to the reified facts. Returns ------- A list of symbols containing the reified facts. ''' ret: List[Symbol] = [] ctl = Control() reifier = Reifier(ret.append, calculate_sccs, reify_steps) ctl.register_observer(reifier) ctl.add("base", [], prg) ctl.ground([('base', [])]) if calculate_sccs and not reify_steps: reifier.calculate_sccs() return ret
def main(self, ctl: Control, files: Sequence[str]): ''' The main function implementing incremental solving. ''' if not files: files = ["-"] for file_ in files: ctl.load(file_) ctl.add("check", ["t"], "#external query(t).") conf = self._conf step = 0 ret: Optional[SolveResult] = None while ((conf.imax is None or step < conf.imax) and (ret is None or step < conf.imin or ((conf.istop == "SAT" and not ret.satisfiable) or (conf.istop == "UNSAT" and not ret.unsatisfiable) or (conf.istop == "UNKNOWN" and not ret.unknown)))): parts = [] parts.append(("check", [Number(step)])) if step > 0: ctl.release_external(Function("query", [Number(step - 1)])) parts.append(("step", [Number(step)])) else: parts.append(("base", [])) ctl.ground(parts) ctl.assign_external(Function("query", [Number(step)]), True) ret, step = cast(SolveResult, ctl.solve()), step + 1
def _assume(ctl: Control): ctl.add("base", [], '{a;b}.') ctl.ground([('base', [])]) lit_a = cast(SymbolicAtom, ctl.symbolic_atoms[Function("a")]).literal lit_b = cast(SymbolicAtom, ctl.symbolic_atoms[Function("b")]).literal ctl.solve(assumptions=[lit_a, lit_b]) ctl.solve(assumptions=[-lit_a, -lit_b])
def approximate(self, prg: str, expected_res): ''' Auxiliary function to test approximate. ''' ctl = Control() ctl.add("base", [], prg) ctl.ground([("base", [])]) res = approximate(ctl) if res: sorted_res = (sorted([str(s) for s in res[0]]), sorted([str(s) for s in res[1]])) else: sorted_res = None self.assertEqual(sorted_res, expected_res)
def main(self, ctl: Control, files: Sequence[str]): ''' Main function implementing branch and bound optimization. ''' if not files: files = ["-"] for file_ in files: ctl.load(file_) ctl.add("bound", ["b"], ":- #sum { V,I: _minimize(V,I) } >= b.") ctl.ground([("base", [])]) while cast(SolveResult, ctl.solve(on_model=self._on_model)).satisfiable: print("Found new bound: {}".format(self._bound)) ctl.ground([("bound", [Number(cast(int, self._bound))])]) if self._bound is not None: print("Optimum found")
def __call__(self, ctl: Control): ctl.add('base', [], self._prg) # nocoverage ctl.ground([('base', [])]) # nocoverage ctl.solve() # nocoverage