Gurddy Python package.
Project description
Gurddy
Gurddy is a lightweight Python package designed to model and solve Constraint Satisfaction Problems (CSP) and Linear Programming (LP) problems with ease. Built for researchers, engineers, and optimization enthusiasts, Gurddy provides a unified interface to define variables, constraints, and objectives—then leverages powerful solvers under the hood to deliver optimal or feasible solutions.
Features
- 🧩 CSP Support: Define discrete variables, domains, and logical constraints.
- 📈 LP Support: Formulate linear objectives and inequality/equality constraints.
- 🔌 Extensible Solver Backend: Integrates with industry-standard solvers (e.g., Gurobi, CBC, or GLPK via compatible interfaces).
- 📦 Simple API: Intuitive syntax for rapid prototyping and experimentation.
- 🧪 Type-Hinted & Tested: Robust codebase with unit tests and clear documentation.
Installation (PyPI)
Install the package from PyPI:
pip install gurddy
For LP/MIP examples you also need PuLP (the LP backend used by the built-in LPSolver):
pip install pulp
If you publish optional extras you may use something like pip install gurddy[lp] if configured; otherwise install pulp separately as shown above.
Usage — Core concepts
After installing from PyPI you can import the public API from the gurddy package. The library exposes a small Model/Variable/Constraint API used by both CSP and LP solvers.
- Model: container for variables, constraints, and objective. Use
Model(...)and thenaddVar,addConstraint,setObjectiveor callsolve()which will dispatch to the appropriate solver based onproblem_type. - Variable: create with
Model.addVar(name, low_bound=None, up_bound=None, cat='Continuous', domain=None); for CSP usedomain(tuple of ints), for LP use numeric bounds and category ('Continuous', 'Integer', 'Binary'). - Expression: arithmetic expressions are created implicitly by operations on
Variableobjects or explicitly viaExpression(variable_or_value). - Constraint types:
LinearConstraint,AllDifferentConstraint,FunctionConstraint.
Usage — CSP (example)
Simple CSP example (map to CSPSolver):
from gurddy.model import Model
from gurddy.variable import Expression
from gurddy.constraint import AllDifferentConstraint
# Build CSP model
model = Model('sudoku', problem_type='CSP')
# Add discrete variables with domains (1..9)
model.addVar('A1', domain=[1,2,3,4,5,6,7,8,9])
model.addVar('A2', domain=[1,2,3,4,5,6,7,8,9])
# Add AllDifferent constraint across a group
model.addConstraint(AllDifferentConstraint([model.variables['A1'], model.variables['A2']]))
# Solve (uses internal CSPSolver)
solution = model.solve()
print(solution) # dict of variable name -> assigned int, or None if unsatisfiable
Notes about CSP API
- CSPSolver automatically builds an internal graph of constraints and will attempt mask-based optimizations when domains are small contiguous integer sets (e.g., Sudoku 1..9).
- You can force the mask-optimized path by setting
solver.force_mask = Trueafter creating the solver (if you instantiateCSPSolverdirectly).
Usage — LP / MIP (example)
The LP solver wraps PuLP. A basic LP/MIP example:
from gurddy.model import Model
# Build an LP model
m = Model('demo', problem_type='LP')
# addVar(name, low_bound=None, up_bound=None, cat='Continuous')
x = m.addVar('x', low_bound=0, cat='Continuous')
y = m.addVar('y', low_bound=0, cat='Integer')
# Objective: maximize 3*x + 5*y
m.setObjective(x * 3 + y * 5, sense='Maximize')
# Add linear constraints (using Expression objects implicitly via Variable operations)
m.addConstraint((x * 2 + y * 1) <= 10)
# Solve (uses LPSolver which wraps PuLP)
sol = m.solve()
print(sol) # dict var name -> numeric value or None
Advanced LP demo
See examples/optimized_lp.py (simple demo) and examples/advanced_lp.py (LP relaxation vs MIP, timings, simple sensitivity analysis).
Developer notes
- The CSP code includes several internal optimizations: precomputed support masks, mask-based AC-3, and an optional AllDifferent matching propagation for small groups to strengthen pruning.
- The LP solver uses PuLP. If you want to use another solver backend (ORTOOLS, Gurobi), you can either modify
src/gurddy/solver/lp_solver.pyto wrap that backend or add a new solver class and dispatch viaModel.solve().
Running tests
Run unit tests with pytest:
python -m pytest
Contributing
PRs welcome. If you add a new solver backend, please include configuration and a small example demonstrating usage.
API Reference (concise)
This section lists the most commonly used classes and functions with signatures and short descriptions.
Model
-
Model(name: str = "Model", problem_type: str = "LP")
- Container for variables, constraints, objective and solver selection.
- Attributes: variables: Dict[str, Variable], constraints: List[Constraint], objective: Optional[Expression], sense: str
-
addVar(name: str, low_bound: Optional[float] = None, up_bound: Optional[float] = None, cat: str = 'Continuous', domain: Optional[list] = None) -> Variable
- Create and register a Variable. For CSP use
domain(list/tuple of ints). For LP use numeric bounds andcat.
- Create and register a Variable. For CSP use
-
addVars(names: List[str], **kwargs) -> Dict[str, Variable]
- Convenience to create multiple variables with the same kwargs.
-
addConstraint(constraint: Constraint, name: Optional[str] = None) -> None
- Register a Constraint object (LinearConstraint, AllDifferentConstraint, FunctionConstraint).
-
setObjective(expr: Expression, sense: str = "Maximize") -> None
- Set the objective expression and sense for LP problems.
-
solve() -> Optional[Dict[str, Union[int, float]]]
- Dispatch to the appropriate solver (CSPSolver or LPSolver) and return a mapping from variable name to value, or None if unsatisfiable/no optimal found.
Variable
- Variable(name: str, low_bound: Optional[float] = None, up_bound: Optional[float] = None,
cat: str = 'Continuous', domain: Optional[list] = None)
- Represents a decision variable. For CSP set
domain(discrete values). For LP set numeric bounds andcatin {'Continuous','Integer','Binary'}. - Supports arithmetic operator overloads to build
Expressionobjects (e.g.,x * 3 + y).
- Represents a decision variable. For CSP set
Expression
- Expression(term: Union[Variable, int, float, Expression])
- Arithmetic expression type used to build linear objectives and constraints.
- Operators: +, -, *, / with scalars; comparisons (==, <=, >=, <, >) produce
LinearConstraintinstances.
Constraint types
-
LinearConstraint(expr: Expression, sense: str)
- General linear constraint wrapper (sense in {'<=','>=','==', '!='}).
-
AllDifferentConstraint(vars: List[Variable])
- Global constraint enforcing all variables in the list take pairwise distinct values (used primarily for CSPs).
-
FunctionConstraint(func: Callable[[int,int], bool], vars: Tuple[Variable, ...])
- Custom binary (or n-ary) constraint defined by a Python callable.
Solvers
-
class CSPSolver
- CSPSolver(model: Model)
- Attributes: mask_threshold: int (domain size under which mask optimization is used), force_mask: bool
- Methods: solve() -> Optional[Dict[str, int]] (returns assignment mapping or None)
-
class LPSolver
- LPSolver(model: Model)
- Methods: solve() -> Optional[Dict[str, float]] (returns variable values mapping or None). Uses PuLP by default; requires
pulpinstalled.
Notes
- The API intentionally keeps model construction separate from solver execution. Use
Model.solve()for convenience or instantiate solver classes directly for advanced control (e.g., changeCSPSolver.force_mask). - For more examples see
examples/optimized_csp.py,examples/optimized_lp.py, andexamples/advanced_lp.py.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gurddy-0.1.3.tar.gz.
File metadata
- Download URL: gurddy-0.1.3.tar.gz
- Upload date:
- Size: 19.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60326534dad5d0413360ba7453fa741179ab6d3ade7aaaf730b476c4b7a54df5
|
|
| MD5 |
29ecbc5b12f6867269635e158f177b08
|
|
| BLAKE2b-256 |
1151162e3a500cbccda15fcf26e49dc836553eede994f336cf69e3ebd7b05381
|
File details
Details for the file gurddy-0.1.3-py3-none-any.whl.
File metadata
- Download URL: gurddy-0.1.3-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30a8a1d60e949c71e3b9bcedf8cb344b689c1b60389c86e704a18b6b11215a06
|
|
| MD5 |
7d0cad615cb17a5970a3bf7494278a2e
|
|
| BLAKE2b-256 |
dbc2243b74516edd8a24bf47f13f058d72ef845ef7427b2ccfd0287aa50a6c68
|