---
kind: concept
slug: constraint-satisfaction
title: Constraint satisfaction
summary: >-
  Model finite-domain problems as variables, domains and rules, then let a solver find assignments that meet every rule, or optimise one quantity. Covers the Python-embedded route that compiles to the XCSP3 format and the choice of solver backend. One source so far: a library guide with no benchmarks.
tags: [constraint-programming, combinatorial-optimization, modeling]
papers: ["2009.00326"]
related: [constrained-conditional-models]
status: draft
updated_at: 2026-10-18
---

## Overview

A constraint satisfaction problem (CSP) gives each unknown a finite domain of
values and a set of rules that the values must jointly obey. A solution is an
assignment that breaks no rule. A constraint optimisation problem (COP) adds
one quantity to minimise or maximise [arxiv:2009.00326 §2.2] [arxiv:2009.00326 §2.3].
The author states the problem; a solver does the search [arxiv:2009.00326 intro].

The only source on this page so far is the PyCSP3 user guide. It documents one
toolchain, reports no benchmark results and does not survey the field. The
page therefore describes that toolchain and its stated limits.

## Variants

### Python-embedded model compiled to XCSP3

Variables, domains, rules and an optional objective are written as Python code.
Instance data sits in a separate JSON file. The model and data compile to an
XCSP3 XML instance, which a solver reads [arxiv:2009.00326 §5.1]. The guide's
worked examples use this route. Card: [PyCSP3: Modeling Combinatorial Constrained Problems in Python](/papers/2009.00326).

### Solver backend chosen at solve time

The compiled instance is passed to a backend. The guide names ACE as the
default and Choco as the other constant [arxiv:2009.00326 §6.1]. Options are a
string passed through to the solver. The guide does not say which backend to
prefer for which constraint form [arxiv:2009.00326 §6.1]. The card for the
same paper records bugs that the repository's tests report for both backends.
Check a backend against the form you need before relying on it. Card:
[PyCSP3: Modeling Combinatorial Constrained Problems in Python](/papers/2009.00326).

## When to use which

| Situation | Use | Why |
|---|---|---|
| Model and data should stay apart, and any supporting solver should read one standard file | Python-embedded model compiled to XCSP3 | The workflow keeps modelling, data and solving as separate steps [arxiv:2009.00326 §5.1] |
| Every solution, or a set number of them, is needed from Python | Solver piloting with the solution count set | Covered in [arxiv:2009.00326 §6.2] |
| An unsatisfiable model must be explained | Unsatisfiable-core extraction | Enabled with `extraction=True` [arxiv:2009.00326 §6.4] |
| Choosing a solver or estimating run time for a model class | Not answered by this source | The guide reports no run times or solver rankings [arxiv:2009.00326 intro] |
| Variables with real-valued or unbounded domains | Outside the stated scope | Only finite integer and symbolic domains can be declared [arxiv:2009.00326 §2.2] |

## Implementation sketch

Language-agnostic outline of the common core. The steps follow the guide's
workflow; the names are placeholders.

```pseudocode
# Declare each unknown with a finite domain: range, set or symbols  [§2.2]
variables = declare_variables(domains)

# Post rules that every solution must satisfy; calls may repeat  [§2.2]
post_constraints(rules)

# Optionally name one quantity to minimise or maximise  [§2.3]
set_objective(term)

# Compile model and data into a standard instance file  [§5.1]
instance = compile_model(model_file, data_file)

# Run a backend on the instance and read its status  [§5.2] [§6.1]
status = run_solver(instance, backend="ACE")

# Read values only when the status reports an answer  [§5.2]
if status in {SAT, OPTIMUM}:
    answers = read_values(variables)
```

Status values in the guide are UNSAT, SAT, OPTIMUM, UNKNOWN and CORE [arxiv:2009.00326 §5.2].

## Contradictions

- **Solver backends.** The guide's introduction names Picat and CP-SAT as
  solvers that read the XCSP3 instance [arxiv:2009.00326 intro]. The card
  for this paper checked the repository the guide points to and found
  backends for ACE, Choco and two other solvers, but none for Picat or CP-SAT.
  The card did not confirm whether an external route reaches them. Card:
  [PyCSP3: Modeling Combinatorial Constrained Problems in Python](/papers/2009.00326).
- **Model count.** The arXiv abstract says "more than 50" illustrative models.
  The guide's own abstract says "more than 60" [arxiv:2009.00326 intro].
  The card follows the guide. Card:
  [PyCSP3: Modeling Combinatorial Constrained Problems in Python](/papers/2009.00326).
- **Indexing flag.** The guide spells the flag `-dontadjustindexing`
  [arxiv:2009.00326 §3.2]. The repository registers `dont_adjust_indexing`.
  The card did not run the compiler, so the accepted spelling is unverified.

## Papers

- [PyCSP3: Modeling Combinatorial Constrained Problems in Python](/papers/2009.00326): a Python layer that compiles finite-domain models to XCSP3 and runs ACE or Choco; a user guide with no benchmark results.
