from abc import ABC, abstractmethod
from typing import Iterable, Optional
from .pindakaas import (
CNFInner,
Encoder,
Formula,
Lit,
VarRange,
WCNFInner,
_wrap_encode_constraint,
)
Constraint = Formula
class ClauseDatabase(ABC):
def __iadd__(self, constraint: Constraint):
self.add_encoding(constraint)
return self
@abstractmethod
def add_clause(self, clause: Iterable[Lit]):
...
def add_encoding(
self,
constraint: Constraint,
encoder: Optional[Encoder] = None,
conditions: Optional[Iterable[Lit]] = None,
):
_wrap_encode_constraint(self, constraint, encoder, conditions)
def new_var(self):
r = self.new_var_range(1)
assert r.start() == r.end()
return r.start()
def new_vars(self, n: int) -> Iterable[Lit]:
return self.new_var_range(n)
@abstractmethod
def new_var_range(self, n: int) -> VarRange:
...
class CNF(ClauseDatabase):
_inner: CNFInner
def __init__(self):
self._inner = CNFInner()
def add_clause(self, clause: Iterable[Lit]):
return self._inner.add_clause(iter(clause))
def add_encoding(
self,
constraint: Constraint,
encoder: Optional[Encoder] = None,
conditions: Optional[Iterable[Lit]] = None,
):
conditions = list(conditions) if conditions is not None else []
return self._inner.add_encoding(constraint, encoder, conditions)
def clauses(self) -> Iterable[list[Lit]]:
return self._inner.clauses()
def new_var_range(self, n: int) -> VarRange:
return self._inner.new_var_range(n)
def to_dimacs(self) -> str:
return self._inner.to_dimacs()
def variables(self) -> Iterable[Lit]:
return self._inner.variables()
class WCNF(CNF):
_inner: WCNFInner
def __init__(self):
self._inner = WCNFInner()
def add_weighted_clause(self, clause: Iterable[Lit], weight: int):
return self._inner.add_weighted_clause(iter(clause), weight)
def weighted_clauses(self) -> Iterable[tuple[Optional[int], list[Lit]]]:
return self._inner.weighted_clauses()