A complete system for generation, solving, explanation, and evaluation of "Padlock Challenge" logic puzzles.
📄 Supplementary material for the paper "A Neuro-Symbolic Framework for Logic Puzzle Solving: Pseudo-Boolean Reasoning with LLM-Based Explanations" — Bruno Cesar Ribas, Razer A. N. R. Montaño, Fabiano Silva, and Gabriel Tiveron — accepted at BRACIS 2026 (Brazilian Conference on Intelligent Systems).
This repository hosts the code, puzzle instances, prompts, generated explanations, and evaluation data used in the paper. A fully worked end-to-end example (structured clues → PB solver → solution-grounded analysis → exact prompts → real LLM output) is in
WORKED_EXAMPLE.md.
- Overview
- Repository Structure
- Prerequisites
- The Puzzle
- Module: enunciados/
- Module: formuleitor/
- Module: evaluation/
- Experiment Pipeline
- Quick Start
- Full Examples
- Troubleshooting
- References
This project implements an end-to-end research pipeline:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Instance │───▶│ Solving │───▶│ Explanation │───▶│ Evaluation │
│ Generation │ │ (PB Solver) │ │ (LLMs) │ │ (Human + │
│ │ │ │ │ │ │ Automatic) │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
- Generation: Creates puzzle instances with guaranteed unique solutions
- Solving: Encodes as Pseudo-Boolean formulas and solves with
clasp - Explanation: Generates natural language explanations via LLMs
- Evaluation: HTML forms for human evaluation + automatic verifier
.
├── README.md # This file
├── enunciados/ # Puzzle instances (.in files)
│ ├── imprimeitor.sh # Formats puzzles for human-readable display
│ ├── exemplo-2n.in # Example puzzle (2 digits)
│ ├── escape-3n.in # Puzzle with 3 digits
│ ├── padlock-4n.in # Puzzle with 4 digits
│ ├── genereitor-5n.in # Puzzle with 5 digits
│ └── ...
├── formuleitor/ # Solver engine and generators
│ ├── formuleitor.sh # Puzzle → PB formula encoder
│ ├── formuleitor-funcs.sh # Encoder helper functions
│ ├── interpreteitor.sh # Decodes clasp output → solution
│ ├── ambigueitor.sh # Checks ambiguity (multiple solutions)
│ ├── contasolucao.sh # Counts total number of solutions
│ ├── traceitor.sh # Generates deduction trace (JSON)
│ ├── explicaitor.sh # Full LLM explanation pipeline
│ ├── explicaitor-offline.sh # Generates prompt for manual LLM use
│ ├── benchmark-explicaitor.sh # Runs batch explanations
│ ├── instance-generators.py # Instance generators (Python)
│ ├── llm/
│ │ ├── explicaitor.py # Python backend for LLM calls
│ │ └── prompt-template.txt # Prompt template
│ └── cfiles/
│ ├── casual_generator.py # Casual generator (C + Python)
│ ├── latin_square_genereitor.py # Latin square generator
│ ├── genereitor_bruteforce.py # Brute force generator
│ └── imprimeitor.py # Python formatter
├── evaluation/ # Explanation evaluation
│ ├── generate-evaluation.sh # Form generation orchestrator
│ ├── generate-evaluation.py # Individual HTML form generator
│ ├── generate-evaluation-survey.py # Multi-puzzle survey generator
│ ├── collect-responses.py # Response collector and analyzer
│ ├── analyze-results.py # Statistical analysis and LaTeX tables
│ ├── explanations/ # Generated explanations (JSONs)
│ ├── analysis.json # Analysis results
│ └── instrucoes-uso.txt # Usage instructions
└── pipeline-experiment.py # Automated experiment pipeline
| Tool | Purpose | Installation |
|---|---|---|
| bash ≥ 4.0 | Shell scripts | Included in Linux/macOS |
| Python ≥ 3.8 | Generators, evaluation, pipeline | apt install python3 |
| clasp | Pseudo-Boolean/ASP solver | apt install clasp or potassco.org |
| Tool | Purpose | Installation |
|---|---|---|
| openai (Python) | GPT-4/5 API | pip install openai |
| anthropic (Python) | Claude API | pip install anthropic |
| ollama | Local LLMs (Llama, etc.) | ollama.com |
| requests (Python) | Ollama communication | pip install requests |
# OpenAI
export OPENAI_API_KEY="sk-..."
# Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
# Ollama (no variable needed, just needs to be running)
ollama serve &
ollama pull llama3.2# Check clasp
clasp --version
# Check Python
python3 --version
# Check optional dependencies
python3 -c "import openai; print('OpenAI OK')"
python3 -c "import anthropic; print('Anthropic OK')"
curl -s http://localhost:11434/api/tags | python3 -m json.toolThe "Padlock Challenge" is a logic puzzle where the player must discover a secret code from clues. Each clue provides a guess along with three pieces of information:
- How many digits are correct (present in the code)
- How many are in the right place (correct position)
- How many are in the wrong place (present but in a different position)
3 ← number of digits in the code (holes)
5 ← number of clues
682 1 1 0 ← guess: 682, 1 correct, 1 in right place, 0 in wrong place
614 1 0 1 ← guess: 614, 1 correct, 0 in right place, 1 in wrong place
206 2 0 2 ← guess: 206, 2 correct, 0 in right place, 2 in wrong place
738 0 0 0 ← guess: 738, nothing correct
780 1 0 1 ← guess: 780, 1 correct, 0 in right place, 1 in wrong place
Each clue line follows the format:
<guess> <correct_count> <right_place_count> <wrong_place_count>
Contains ready-made puzzle instances and a formatter.
Formats a .in file for friendly human-readable display (in Portuguese).
Usage:
cd enunciados/
bash imprimeitor.sh < exemplo-2n.inOutput:
Menos de 5% acertam esse desafio!
Qual é a senha do 🔒 ?
O cadeado possui um senha com 2 dígitos não repetidos
Temos as seguintes dicas:
57 1 corretos, mas no lugar errado.
15 1 corretos, e no lugar certo.
83 nada está correto
File naming convention:
- The suffix indicates size:
*-2n.in= 2 digits,*-3n.in= 3 digits, etc. - The prefix indicates origin:
escape,padlock,mathway, etc.
Core solver engine. Encodes puzzles as Pseudo-Boolean formulas and solves them with clasp.
Encodes a .in puzzle into a Pseudo-Boolean formula (OPB format).
Usage:
cd formuleitor/
bash formuleitor.sh < ../enunciados/escape-3n.inWhat it does:
- Reads the
.infile (holes + clues) - Creates boolean variables
x_{digit}_{position}for every possible combination - Generates constraints:
- Exactly 1 digit per position
- For each clue: constraints for correct-in-right-place and correct-in-any-place
- Digits absent from all clues cannot be in the solution
- Outputs the formula in OPB format (readable by
clasp)
Typical pipeline (solve a puzzle):
cd formuleitor/
# Encode → solve → interpret
bash formuleitor.sh < ../enunciados/escape-3n.in > /tmp/formula.opb
clasp /tmp/formula.opb > /tmp/solution.clasp
bash interpreteitor.sh ../enunciados/escape-3n.in < /tmp/solution.claspFunction library used by formuleitor.sh. Not meant to be executed directly.
Available functions:
| Function | Description |
|---|---|
push_constraint |
Adds a constraint to the formula |
push_comment |
Adds a comment to the formula |
printformula |
Prints the complete OPB formula |
getvarnumber |
Returns the variable index for a (digit, position) pair |
generate_combinations |
Generates number combinations (helper) |
Decodes clasp output into a human-readable solution.
Usage:
cd formuleitor/
bash formuleitor.sh < ../enunciados/escape-3n.in > /tmp/formula.opb
clasp /tmp/formula.opb | bash interpreteitor.sh ../enunciados/escape-3n.inOutput:
0 4 2
Arguments:
$1: original problem file (needed to reconstruct the variable map)stdin: clasp output
Checks whether a puzzle has multiple solutions and lists all of them.
Usage:
cd formuleitor/
bash ambigueitor.sh ../enunciados/escape-3n.inOutput (unique solution):
Base solution:
0 4 2
Checking for aditional solutions...
Removing x43
Removing x101
Removing x22
Aditional solutions count: 0
Output (ambiguous solution):
Base solution:
1 2 3
Checking for aditional solutions...
Removing x11
4 2 3
Removing x22
1 5 3
Aditional solutions count: 2
How it works:
- Finds a base solution
- For each true variable, forces it to false and re-solves
- If a new solution is found, counts it as additional
- Reports the total extra solution count
Counts the total number of solutions using clasp 0 (enumerate all models).
Usage:
cd formuleitor/
bash contasolucao.sh ../enunciados/escape-3n.inOutput:
Models : 1
Note: More efficient than
ambigueitor.shwhen only the count is needed.
Generates a complete deduction trace in JSON format.
Usage:
cd formuleitor/
bash traceitor.sh ../enunciados/escape-3n.inOutput (JSON):
{
"status": "SATISFIABLE",
"holes": 3,
"solution": "042",
"solution_array": [0, 4, 2],
"clues": [
{
"id": 0,
"guess": "682",
"feedback": {
"correct": 1,
"well_placed": 1,
"wrong_placed": 0
},
"analysis": {
"digits_in_solution": ["2"],
"well_placed": ["2:2"],
"wrong_placed": [],
"eliminated": ["6", "8"]
}
}
],
"deduction_summary": {
"eliminated_digits": [1, 3, 5, 6, 7, 8, 9],
"solution_digits": [0, 4, 2]
}
}Key fields:
analysis.eliminated: digits from the guess that are NOT in the solutionanalysis.well_placed: correct digits in the right position ("digit:position")analysis.wrong_placed: correct digits in wrong position ("digit:guess_pos->real_pos")
Arguments:
$1: problem file$2(optional): file with clasp output (if omitted, runs the solver internally)
Full pipeline: trace → prompt → LLM → natural language explanation.
Usage:
cd formuleitor/
bash explicaitor.sh ../enunciados/escape-3n.in
bash explicaitor.sh ../enunciados/escape-3n.in --theme spy
bash explicaitor.sh ../enunciados/escape-3n.in --theme fantasy --level partial
bash explicaitor.sh ../enunciados/escape-3n.in --jsonParameters:
| Parameter | Values | Default | Description |
|---|---|---|---|
--theme |
neutral, spy, fantasy, scifi |
neutral |
Thematic style of the explanation |
--level |
full, partial, minimal |
full |
Level of detail |
--json |
(flag) | off | JSON output instead of text |
Themes:
- neutral: Educational logic tutor
- spy: Spy agency analyst decoding an intercepted transmission
- fantasy: Ancient wizard deciphering magical runes
- scifi: Starship computer analyzing alien sequences
Internal pipeline:
puzzle.in → traceitor.sh → JSON → explicaitor.py → LLM API → explanation
Requires: At least one LLM backend configured (OpenAI, Anthropic, or Ollama).
Generates only the prompt for manual use with any LLM (ChatGPT web, Claude web, etc.).
Usage:
cd formuleitor/
bash explicaitor-offline.sh ../enunciados/escape-3n.in > prompt.txt
# Copy the contents of prompt.txt into your preferred LLM
cat prompt.txtUseful when:
- No API key is configured
- You want to use an LLM's web interface
- You want to manually customize the prompt
Runs explanations in batch for all instances and all themes.
Usage:
cd formuleitor/
bash benchmark-explicaitor.shWhat it does:
- Iterates over all
*.infiles in../enunciados/ - For each instance, generates an explanation with every theme (
neutral,spy,fantasy,scifi) - Saves results to
./results/
Instance generator with guaranteed unique solution. Implements 3 strategies.
Basic usage:
cd formuleitor/
# Casual generator (recommended)
python3 instance-generators.py --generator casual --holes 4 --clues 5
# Latin square generator
python3 instance-generators.py --generator latin --holes 5 --clues 6
# Custom alphabet
python3 instance-generators.py --generator casual --holes 4 \
--alphabet alphanumeric --alphabet-size 20 --clues 6
# Generate multiple instances
python3 instance-generators.py --generator casual --holes 4 \
--count 10 --output-dir ./instances --format both
# Comparative benchmark of generators
python3 instance-generators.py --benchmark --repetitions 5Generation strategies:
| Strategy | Description | Speed | Recommendation |
|---|---|---|---|
bruteforce |
Completely random clues and feedback | Very slow | Comparison only |
casual |
Picks secret, generates correct feedback, validates uniqueness | Fast | General use |
latin |
Uses Latin square structure for more diverse guesses | Fast | Larger puzzles |
Full parameters:
| Parameter | Description | Default |
|---|---|---|
--generator, -g |
Strategy: bruteforce, casual, latin |
casual |
--holes, -H |
Number of positions in the code | 3 |
--clues, -c |
Initial number of clues to generate | 5 |
--alphabet, -a |
Alphabet type | digits |
--alphabet-size, -s |
Limit alphabet size | (full type) |
--no-repetition |
Disallow repeated digits | off |
--count, -n |
Number of instances to generate | 1 |
--output, -o |
Output file path | stdout |
--output-dir |
Directory for multiple instances | — |
--format, -f |
Format: in, json, both |
in |
--max-attempts |
Maximum generation attempts | 100 |
--seed |
Seed for reproducibility | random |
--solver |
Solver command | clasp |
--verbose, -v |
Detailed progress | off |
--benchmark, -b |
Comparative benchmark mode | off |
--repetitions, -r |
Benchmark repetitions | 5 |
Alphabet types:
| Type | Symbols | Size |
|---|---|---|
digits |
0-9 |
10 |
lowercase |
a-z |
26 |
uppercase |
A-Z |
26 |
letters |
a-zA-Z |
52 |
alphanumeric |
0-9a-zA-Z |
62 |
alphanumeric_lower |
0-9a-z |
36 |
alphanumeric_upper |
0-9A-Z |
36 |
Uniqueness guarantee: All strategies use clasp 2 (search for up to 2 models) to verify uniqueness in a single solver call.
Python backend for LLM-based explanation generation. Called by explicaitor.sh but can also be used directly.
Direct usage:
cd formuleitor/
# Via pipe from traceitor
bash traceitor.sh ../enunciados/escape-3n.in | \
python3 llm/explicaitor.py --theme neutral --level full
# With trace file
python3 llm/explicaitor.py --trace trace.json --theme spy --output jsonParameters:
| Parameter | Description | Default |
|---|---|---|
--trace, -t |
Path to trace JSON (or stdin) | stdin |
--theme |
Theme: neutral, spy, fantasy, scifi |
neutral |
--level |
Detail: full, partial, minimal |
full |
--output, -o |
Format: json, text |
text |
Automatic backend detection: Tries OpenAI → Anthropic → Ollama, in order, using the first one available.
Alternative generators that depend on a C executable (padlock_challenge).
Guided random generator that uses the C solver for validation.
cd formuleitor/cfiles/
python3 casual_generator.py 4 15 # 4 digits, 15-symbol dictionaryLatin square generator using the C solver.
cd formuleitor/cfiles/
python3 latin_square_genereitor.py 4 15Pure brute force generator (very slow).
cd formuleitor/cfiles/
python3 genereitor_bruteforce.pyPython puzzle formatter with terminal colors.
cd formuleitor/cfiles/
python3 imprimeitor.py < ../teste.inNote: The generators in
cfiles/require thepadlock_challengeexecutable compiled separately. The recommended main generator isinstance-generators.py.
Tools for human and automatic evaluation of explanations.
Shell orchestrator for evaluation form generation.
Usage:
cd evaluation/
# Demo mode (generates example)
bash generate-evaluation.sh
# Single instance
bash generate-evaluation.sh --instance ../enunciados/escape-3n.in
# Batch (all instances)
bash generate-evaluation.sh --batch
# With specific language and themes
bash generate-evaluation.sh --batch --lang pt --themes "neutral spy"Parameters:
| Parameter | Description |
|---|---|
--batch, -b |
Process all instances in ../enunciados/ |
--instance, -i |
Process a specific instance |
--lang, -l |
Language: en or pt |
--themes, -t |
Themes (space-separated) |
--output, -o |
Output directory |
Generates individual HTML forms for explanation evaluation.
Usage:
cd evaluation/
# Demo mode
python3 generate-evaluation.py
# Single instance
python3 generate-evaluation.py \
--instance ../enunciados/escape-3n.in \
--explanation ./explanations/escape-3n_neutral.json \
--output-dir ./forms --lang en
# Batch
python3 generate-evaluation.py \
--instances-dir ../enunciados \
--explanations-dir ./explanations \
--output-dir ./forms \
--lang en --themes neutral spy fantasy scifiEvaluation criteria (1–5 scale):
- Correctness — Are the deduction steps valid?
- Completeness — Are all important steps included?
- Clarity — Is the explanation easy to understand?
- Usefulness — Would it be useful as a hint in a game?
Additional questions:
- Theme appropriateness (only for non-neutral themes)
- "Would you use this in a game?" (yes/no)
- Free-text comments
Output: Interactive HTML forms with:
- Puzzle and solution display
- Clickable Likert scale
- JSON export (copy, download, or email)
- Index page with links to all forms
- CSV for Google Forms import
Generates a complete multi-puzzle survey in a single HTML page.
Usage:
cd evaluation/
# Demo
python3 generate-evaluation-survey.py --output survey.html --lang en
# With real instances
python3 generate-evaluation-survey.py \
--instances-dir ../enunciados \
--explanations-dir ./explanations \
--output survey.html \
--lang en \
--themes neutral spy fantasySurvey features:
- Dot navigation between puzzles
- Real-time progress (answered / skipped / remaining)
- Option to skip puzzles
- Hidden solution (hover/tap to reveal)
- Review screen before finishing
- Full JSON export
- Keyboard shortcuts (← → Enter)
- Mobile responsive
Expected explanation JSON format:
{
"solution": "042",
"explanation": "Step 1: ..."
}Naming convention:
The script looks for explanations matching the pattern: {puzzle_name}_{theme}.json
Example: for escape-3n.in with theme neutral, it looks for escape-3n_neutral.json.
Collects, consolidates, and analyzes responses from evaluation forms.
Usage:
cd evaluation/
# Process specific files
python3 collect-responses.py \
--input response1.json response2.json \
--output results.csv
# Process entire directory
python3 collect-responses.py \
--input-dir ./responses \
--output results.csv
# Full analysis
python3 collect-responses.py \
--input-dir ./responses \
--output results.csv \
--output-json analysis.json \
--output-latex tables.tex \
--summaryAccepted input formats:
- Multi-puzzle survey JSON (with
metaandevaluations) - Individual evaluation JSON (with
instance_idandcorrectness) - List of evaluations
Output:
| File | Description |
|---|---|
results.csv |
All evaluations in tabular format |
analysis.json |
Statistics by criterion, theme, evaluator, and instance |
tables.tex |
Paper-ready LaTeX tables |
Generated statistics:
- Mean, standard deviation, min, max, median
- Grouping by theme, evaluator, and instance
- "Would use in game" rate
In-depth statistical analysis for paper inclusion.
Usage:
cd evaluation/
python3 analyze-results.py \
--input results.csv \
--output-latex tables.tex \
--output-summary summary.txtGenerates:
- Formatted LaTeX tables (overall and by theme)
- Summary text for the results section
- Best/worst criterion identification
Unified script that runs the complete research experiment.
Overview:
Step 1: Generate 50 instances (10 × 5 sizes, via Latin square)
↓
Step 2: Submit to 3 LLMs × 2 conditions = 300 explanations
↓
Step 3: Automatically verify all explanations
python3 pipeline-experiment.py --generate- Generates 50 instances: 10 for each
$H \in {3, 4, 5, 6, 7}$ - Alphabet: digits 0–9 (
$|\Sigma| = 10$ ) - Strategy: Latin square
- Guarantees unique solution with
clasp 2 - Fixed seed for reproducibility
Output:
experiment/
├── instances/
│ ├── H3_inst01.in # Puzzle file
│ ├── H3_inst01.json # Metadata
│ ├── H3_inst02.in
│ └── ...
├── traces/
│ ├── H3_inst01_trace.json # Deduction trace
│ └── ...
└── instances_manifest.json # Manifest with all instances
# Dry run (tests prompts without calling LLMs)
python3 pipeline-experiment.py --submit --dry-run
# Real submission
python3 pipeline-experiment.py --submitConfigured LLMs:
| ID | Backend | Model |
|---|---|---|
gpt-4o-mini |
OpenAI | gpt-4o-mini |
claude-3-haiku |
Anthropic | claude-3-haiku-20240307 |
llama3.2 |
Ollama | llama3.2 |
Experimental conditions:
| Condition | Description |
|---|---|
grounded |
Prompt includes complete solver trace (eliminated digits, well-placed, etc.) |
ungrounded |
Prompt includes only the puzzle and the solution (no trace) |
Features:
- Automatic resume (progress tracking in
submission_progress.json) - Rate limiting (1s between calls)
- Automatic backend availability detection
- Error handling with logging
Output:
experiment/
└── explanations/
├── H3_inst01_gpt-4o-mini_grounded.json
├── H3_inst01_gpt-4o-mini_ungrounded.json
├── H3_inst01_claude-3-haiku_grounded.json
└── ... (300 files)
python3 pipeline-experiment.py --verifyChecks performed (regex + keyword matching):
| Check | Method | Metrics |
|---|---|---|
| Solution digits | Searches for contextual mention of each digit | Coverage (recall) |
| Eliminations | Extracts digits the explanation claims to eliminate; compares with trace | Precision and recall |
| Clue references | Detects mentions by number or by the clue's guess | Coverage |
| Final answer | Extracts final numeric sequence; compares with solution | Correct/incorrect |
| Positioning | Extracts "position X = digit Y" claims; validates | List of correct/incorrect |
Regex patterns used:
- Eliminations:
eliminat|remov|discard|rule out|not in|cannot be|nada.*correto|... - References:
clue|dica|hint|tip #?\d+ - Final answer:
solution|answer|code is|: \d{2,10}and**\d{2,10}** - Positioning:
position \d is \dand variations
Composite scores:
Correctness (0–1):
- 30% elimination precision
- 40% final answer correct
- 30% positional precision
Completeness (0–1):
- 30% solution digit coverage
- 30% elimination recall
- 20% clue reference coverage
- 20% final answer present
Output:
experiment/
├── verification/
│ ├── H3_inst01_gpt-4o-mini_grounded_verification.json
│ └── ...
└── results/
├── verification_results.csv # All verifications (tabular)
├── verification_summary.json # Aggregated statistics
├── verification_detailed.json # Full detailed results
└── verification_tables.tex # LaTeX tables for the paper
# All steps at once
python3 pipeline-experiment.py --all
# With custom seed
python3 pipeline-experiment.py --all --seed 123Edit EXPERIMENT_CONFIG at the top of the script:
EXPERIMENT_CONFIG = {
"holes_values": [3, 4, 5, 6, 7], # Code sizes
"instances_per_holes": 10, # Instances per size
"alphabet_size": 10, # Alphabet size
"alphabet": list(string.digits), # Symbols
"llm_models": [ # LLMs to use
{"id": "gpt-5.4", "backend": "openai", "model_name": "gpt-5.4"},
{"id": "claude-3-haiku", "backend": "anthropic", "model_name": "claude-3-haiku-20240307"},
{"id": "llama3.2", "backend": "ollama", "model_name": "llama3.2"},
],
"conditions": ["grounded", "ungrounded"],
"temperature": 0.7,
"max_tokens": 3000,
"seed": 42,
}cd formuleitor/
bash formuleitor.sh < ../enunciados/escape-3n.in > /tmp/f.opb
clasp /tmp/f.opb | bash interpreteitor.sh ../enunciados/escape-3n.incd formuleitor/
bash ambigueitor.sh ../enunciados/escape-3n.incd formuleitor/
python3 instance-generators.py -g casual -H 4 -c 6 -o new_puzzle --format bothcd formuleitor/
# With LLM
bash explicaitor.sh ../enunciados/escape-3n.in --theme neutral
# Without LLM (generates prompt for manual use)
bash explicaitor-offline.sh ../enunciados/escape-3n.in > prompt.txtcd evaluation/
python3 generate-evaluation-survey.py \
--instances-dir ../enunciados \
--explanations-dir ./explanations \
--output survey.html --lang en
# Open survey.html in a browsercd evaluation/
python3 collect-responses.py \
--input-dir ./responses \
--output results.csv \
--output-json analysis.json \
--output-latex tables.tex \
--summarypython3 pipeline-experiment.py --all# 1. Generate puzzle
cd formuleitor/
python3 instance-generators.py \
--generator latin \
--holes 4 \
--clues 6 \
--output ../enunciados/my_puzzle \
--format both
# 2. Verify uniqueness
bash contasolucao.sh ../enunciados/my_puzzle.in
# 3. Display
bash ../enunciados/imprimeitor.sh < ../enunciados/my_puzzle.in
# 4. Generate trace
bash traceitor.sh ../enunciados/my_puzzle.in > /tmp/trace.json
# 5. Generate explanation
bash explicaitor.sh ../enunciados/my_puzzle.in --theme neutral# 1. Generate explanations for all instances
cd formuleitor/
for f in ../enunciados/*.in; do
name=$(basename "$f" .in)
echo "Processing: $name"
bash explicaitor.sh "$f" --json > \
../evaluation/explanations/${name}_neutral.json
done
# 2. Generate survey
cd ../evaluation/
python3 generate-evaluation-survey.py \
--instances-dir ../enunciados \
--explanations-dir ./explanations \
--output survey.html \
--lang en \
--themes neutral
# 3. Open in browser and evaluate
xdg-open survey.html # Linux
open survey.html # macOS
# 4. After collecting responses (JSONs saved by the survey)
python3 collect-responses.py \
--input-dir ./responses \
--output results.csv \
--output-json analysis.json \
--output-latex tables.tex \
--summary# Deterministic generation
python3 pipeline-experiment.py --generate --seed 42
# Submission (can be resumed if interrupted)
python3 pipeline-experiment.py --submit
# Verification
python3 pipeline-experiment.py --verify
# Results will be in experiment/results/
cat experiment/results/verification_summary.json | python3 -m json.toolERROR: 'clasp' not found. Install clasp.
Solution:
# Ubuntu/Debian
sudo apt install clasp
# macOS (Homebrew)
brew install clasp
# Or compile from source:
# https://github.com/potassco/claspError: No LLM backend available.
Solution: Configure at least one backend:
# Option 1: OpenAI
export OPENAI_API_KEY="sk-..."
pip install openai
# Option 2: Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
pip install anthropic
# Option 3: Ollama (free, local)
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.2Unsupported parameter: 'max_tokens' is not supported with this model.
Use 'max_completion_tokens' instead.
Solution: The pipeline-experiment.py already handles this case automatically. If using explicaitor.py directly, update the call_openai function to use max_completion_tokens for GPT-5+/o1/o3/o4 models.
ERROR: No valid instances found!
Solution: Verify that explanation JSON files follow the naming pattern:
explanations/{puzzle_name}_{theme}.json
And that each file contains at least:
{"solution": "042", "explanation": "...text..."}If the solver returns UNSATISFIABLE, the clues are inconsistent. Check:
- Is the
.infile well-formatted? - Are the correct/position counts coherent?
- Use
ambigueitor.shfor diagnostics.
For large puzzles (
- Increase the timeout in
pipeline-experiment.py(thetimeoutvariable insubprocess.runcalls) - Reduce the alphabet size
- Use fewer clues (the solver is faster with fewer constraints)
If you use this material, please cite the paper:
- Ribas, B. C., Montaño, R. A. N. R., Silva, F., & Tiveron, G. (2026). A Neuro-Symbolic Framework for Logic Puzzle Solving: Pseudo-Boolean Reasoning with LLM-Based Explanations. In: Proceedings of the Brazilian Conference on Intelligent Systems (BRACIS 2026). To appear.
Key references cited in the paper (see the paper's bibliography for the full list):
- clasp (PB solver used here): Gebser, M., Kaufmann, B., & Schaub, T. (2012). Conflict-driven answer set solving: From theory to practice. Artificial Intelligence, 187, 52–89. potassco.org
- Pseudo-Boolean constraints / SAT: Biere, A., Heule, M., van Maaren, H., & Walsh, T. (eds.) (2021). Handbook of Satisfiability (2nd ed.). IOS Press.
- Mastermind (related code-breaking puzzle): Knuth, D. E. (1977). The Computer as Master Mind. Journal of Recreational Mathematics, 9(1), 1–6.
- Neuro-Symbolic AI: Garcez, A. d'Avila, & Lamb, L. C. (2023). Neurosymbolic AI: The 3rd Wave. Artificial Intelligence Review, 56(11), 12387–12406.