Skip to content

Fix #449: [Model] ConjunctiveBooleanQuery#689

Open
GiggleLiu wants to merge 6 commits intomainfrom
issue-449-conjunctive-boolean-query
Open

Fix #449: [Model] ConjunctiveBooleanQuery#689
GiggleLiu wants to merge 6 commits intomainfrom
issue-449-conjunctive-boolean-query

Conversation

@GiggleLiu
Copy link
Contributor

Summary

Add the Conjunctive Boolean Query (CBQ) problem model — a classical NP-complete satisfaction problem from database theory (Garey & Johnson A4 SR31). Given a finite domain, relations, and an existentially quantified conjunctive query, determine whether the query is satisfiable.

Fixes #449

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

❌ Patch coverage is 97.92746% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.05%. Comparing base (dfcc313) to head (7d438ed).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/models/misc/conjunctive_boolean_query.rs 96.26% 4 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main     #689    +/-   ##
========================================
  Coverage   97.04%   97.05%            
========================================
  Files         284      286     +2     
  Lines       38037    38230   +193     
========================================
+ Hits        36914    37103   +189     
- Misses       1123     1127     +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@GiggleLiu
Copy link
Contributor Author

Implementation Summary

Changes

  • src/models/misc/conjunctive_boolean_query.rs — New model file with Relation, QueryArg, ConjunctiveBooleanQuery types, Problem/SatisfactionProblem trait impls, declare_variants!, ProblemSchemaEntry, and example-db spec
  • src/unit_tests/models/misc/conjunctive_boolean_query.rs — 9 unit tests (basic, evaluate yes/no, out-of-range, wrong-length, brute-force, unsatisfiable, serialization, paper example)
  • src/models/misc/mod.rs — Module registration and example-db chain
  • src/models/mod.rs, src/lib.rs — Re-exports
  • problemreductions-cli/src/cli.rs — New flags: --domain-size, --relations, --conjuncts-spec
  • problemreductions-cli/src/commands/create.rs — Full pred create ConjunctiveBooleanQuery support with relation/conjunct parsing
  • src/example_db/fixtures/examples.json — Regenerated with CBQ example
  • docs/paper/reductions.typ — Problem definition entry with data-driven example
  • docs/paper/references.bib — Added Chandra & Merlin 1977, Gottlob et al. 2002, Kolaitis & Vardi 1998

Deviations from Plan

  • None

Open Questions

  • None

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Conjunctive Boolean Query (CBQ) satisfaction problem model to the misc model set, including CLI instance construction support, example-db fixtures, tests, and paper documentation updates.

Changes:

  • Introduces ConjunctiveBooleanQuery model (+ schema registration, variants, example-db spec, and tests).
  • Extends pred create to construct CBQ instances from --domain-size, --relations, and --conjuncts-spec.
  • Updates example-db fixtures and the paper (definition section + references) to include CBQ.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/models/misc/conjunctive_boolean_query.rs New CBQ model type, schema entry, evaluation logic, variants, and example-db builder.
src/models/misc/mod.rs Wires CBQ module + re-exports (including CbqRelation, QueryArg) and example-db specs.
src/models/mod.rs Re-exports CBQ types at the top-level models module.
src/lib.rs Exposes CBQ types in the public prelude.
src/unit_tests/models/misc/conjunctive_boolean_query.rs Adds unit tests for evaluation, brute-force solving, and serialization.
problemreductions-cli/src/cli.rs Adds pred create flags for CBQ.
problemreductions-cli/src/commands/create.rs Implements CBQ parsing/creation in the CLI.
src/example_db/fixtures/examples.json Adds a canonical CBQ model fixture entry (and includes an unrelated witness tweak).
docs/paper/reductions.typ Adds CBQ definition section with a worked example loaded from fixtures.
docs/paper/references.bib Adds CBQ-related references (Chandra & Merlin, Gottlob et al., Kolaitis & Vardi).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +696 to +723
@article{chandra1977,
author = {Ashok K. Chandra and Philip M. Merlin},
title = {Optimal Implementation of Conjunctive Queries in Relational Data Bases},
journal = {Proceedings of the 9th Annual ACM Symposium on Theory of Computing (STOC)},
pages = {77--90},
year = {1977},
doi = {10.1145/800105.803397}
}

@article{gottlob2002,
author = {Georg Gottlob and Nicola Leone and Francesco Scarcello},
title = {Hypertree Decompositions and Tractable Queries},
journal = {Journal of Computer and System Sciences},
volume = {64},
number = {3},
pages = {579--627},
year = {2002},
doi = {10.1006/jcss.2001.1809}
}

@incollection{kolaitis1998,
author = {Phokion G. Kolaitis and Moshe Y. Vardi},
title = {Conjunctive-Query Containment and Constraint Satisfaction},
booktitle = {Proceedings of the 17th ACM SIGACT-SIGMOD-SIGART Symposium on Principles of Database Systems (PODS)},
pages = {205--213},
year = {1998},
doi = {10.1145/275487.275511}
}
Comment on lines +1564 to +1641
// Parse relations: "arity:t1,t2|t3,t4;arity:t5,t6,t7|t8,t9,t10"
let relations: Vec<CbqRelation> = relations_str
.split(';')
.map(|rel_str| {
let rel_str = rel_str.trim();
let (arity_str, tuples_str) = rel_str.split_once(':').ok_or_else(|| {
anyhow::anyhow!(
"Invalid relation format: expected 'arity:tuples', got '{rel_str}'"
)
})?;
let arity: usize = arity_str
.trim()
.parse()
.map_err(|e| anyhow::anyhow!("Invalid arity '{arity_str}': {e}"))?;
let tuples: Vec<Vec<usize>> = tuples_str
.split('|')
.map(|t| {
t.trim()
.split(',')
.map(|v| {
v.trim()
.parse::<usize>()
.map_err(|e| anyhow::anyhow!("Invalid tuple value: {e}"))
})
.collect::<Result<Vec<_>>>()
})
.collect::<Result<Vec<_>>>()?;
Ok(CbqRelation { arity, tuples })
})
.collect::<Result<Vec<_>>>()?;
// Parse conjuncts: "rel_idx:arg1,arg2;rel_idx:arg1,arg2,arg3"
let mut num_vars_inferred: usize = 0;
let conjuncts: Vec<(usize, Vec<QueryArg>)> = conjuncts_str
.split(';')
.map(|conj_str| {
let conj_str = conj_str.trim();
let (idx_str, args_str) = conj_str.split_once(':').ok_or_else(|| {
anyhow::anyhow!(
"Invalid conjunct format: expected 'rel_idx:args', got '{conj_str}'"
)
})?;
let rel_idx: usize = idx_str.trim().parse().map_err(|e| {
anyhow::anyhow!("Invalid relation index '{idx_str}': {e}")
})?;
let query_args: Vec<QueryArg> = args_str
.split(',')
.map(|a| {
let a = a.trim();
if let Some(rest) = a.strip_prefix('v') {
let v: usize = rest.parse().map_err(|e| {
anyhow::anyhow!("Invalid variable index '{rest}': {e}")
})?;
if v + 1 > num_vars_inferred {
num_vars_inferred = v + 1;
}
Ok(QueryArg::Variable(v))
} else if let Some(rest) = a.strip_prefix('c') {
let c: usize = rest.parse().map_err(|e| {
anyhow::anyhow!("Invalid constant value '{rest}': {e}")
})?;
Ok(QueryArg::Constant(c))
} else {
Err(anyhow::anyhow!(
"Invalid query arg '{a}': expected vN (variable) or cN (constant)"
))
}
})
.collect::<Result<Vec<_>>>()?;
Ok((rel_idx, query_args))
})
.collect::<Result<Vec<_>>>()?;
(
ser(ConjunctiveBooleanQuery::new(
domain_size,
relations,
num_vars_inferred,
conjuncts,
))?,
Comment on lines +1578 to +1590
let tuples: Vec<Vec<usize>> = tuples_str
.split('|')
.map(|t| {
t.trim()
.split(',')
.map(|v| {
v.trim()
.parse::<usize>()
.map_err(|e| anyhow::anyhow!("Invalid tuple value: {e}"))
})
.collect::<Result<Vec<_>>>()
})
.collect::<Result<Vec<_>>>()?;
Comment on lines +212 to +219
let tuple: Vec<usize> = args
.iter()
.map(|arg| match arg {
QueryArg::Variable(i) => config[*i],
QueryArg::Constant(c) => *c,
})
.collect();
self.relations[*rel_idx].tuples.contains(&tuple)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Model] ConjunctiveBooleanQuery

2 participants