sat-dependency-resolver 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sat_dependency_resolver-0.1.5/LICENSE +21 -0
- sat_dependency_resolver-0.1.5/PKG-INFO +629 -0
- sat_dependency_resolver-0.1.5/README.md +591 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver/__init__.py +5 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver/ai_agent.py +62 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver/api.py +48 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver/encoder.py +131 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver/resolver.py +158 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver.egg-info/PKG-INFO +629 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver.egg-info/SOURCES.txt +13 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver.egg-info/dependency_links.txt +1 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver.egg-info/requires.txt +9 -0
- sat_dependency_resolver-0.1.5/sat_dependency_resolver.egg-info/top_level.txt +1 -0
- sat_dependency_resolver-0.1.5/setup.cfg +4 -0
- sat_dependency_resolver-0.1.5/setup.py +36 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Apollo87z
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,629 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sat-dependency-resolver
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: Universal dependency resolver using SAT solvers
|
|
5
|
+
Home-page: https://github.com/Apollo87z/sat-dependency-resolver
|
|
6
|
+
Author: Shehan Horadagoda
|
|
7
|
+
Author-email: shehan87h@gmail.com
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: python-sat>=0.1.7.dev18
|
|
21
|
+
Requires-Dist: requests>=2.27.0
|
|
22
|
+
Provides-Extra: api
|
|
23
|
+
Requires-Dist: flask>=2.0.0; extra == "api"
|
|
24
|
+
Provides-Extra: ai
|
|
25
|
+
Requires-Dist: anthropic>=0.18.0; extra == "ai"
|
|
26
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == "ai"
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: author-email
|
|
29
|
+
Dynamic: classifier
|
|
30
|
+
Dynamic: description
|
|
31
|
+
Dynamic: description-content-type
|
|
32
|
+
Dynamic: home-page
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: provides-extra
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
Dynamic: requires-python
|
|
37
|
+
Dynamic: summary
|
|
38
|
+
|
|
39
|
+
<div align="center">
|
|
40
|
+
|
|
41
|
+
<img src="https://i.ibb.co/BVCc4tG7/image-2.jpg" alt="SAT Dependency Resolver Banner" width="100%" />
|
|
42
|
+
|
|
43
|
+
<br/>
|
|
44
|
+
<br/>
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# SAT Dependency Resolver
|
|
49
|
+
|
|
50
|
+
### Universal dependency resolution using Boolean Satisfiability (SAT) solvers
|
|
51
|
+
|
|
52
|
+
[](https://pypi.org/project/sat-dependency-resolver/)
|
|
53
|
+
[](https://www.python.org/downloads/)
|
|
54
|
+
[](https://opensource.org/licenses/MIT)
|
|
55
|
+
[](https://sat-dependency-resolver-ae207ddb503e.herokuapp.com)
|
|
56
|
+
|
|
57
|
+
[Live Demo](https://sat-dependency-resolver-ae207ddb503e.herokuapp.com) โข [Installation](#-installation) โข [Quick Start](#-quick-start) โข [API Reference](#-api-reference) โข [Examples](#-examples)
|
|
58
|
+
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## ๐ฏ Overview
|
|
64
|
+
|
|
65
|
+
SAT Dependency Resolver is a **lightweight, mathematically precise tool** that solves any dependency problem using Boolean Satisfiability (SAT) solvers.
|
|
66
|
+
|
|
67
|
+
**It answers the question:**
|
|
68
|
+
> Given these goals/requirements and these available options with their dependencies, is there a valid combination?
|
|
69
|
+
> - โ
**If yes**: Show one (or more valid solutions)
|
|
70
|
+
> - โ **If no**: Prove it's impossible and explain why (with optional AI help)
|
|
71
|
+
|
|
72
|
+
### Why SAT?
|
|
73
|
+
|
|
74
|
+
- **Guaranteed correctness** โ Finds a solution if one exists, or proves none does (no heuristics)
|
|
75
|
+
- **Universal** โ Not limited to software packages. Works for courses, books, hardware, teams, recipes, scheduling, and more
|
|
76
|
+
- **Fast & lightweight** โ Built on PySAT + Glucose3 solver
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## โจ Features
|
|
81
|
+
|
|
82
|
+
| Feature | Description |
|
|
83
|
+
|---------|-------------|
|
|
84
|
+
| **SAT-based exact solving** | Uses Glucose3 solver for exhaustive, provably correct results |
|
|
85
|
+
| **Conflict detection** | Clear, human-readable explanations of incompatibilities |
|
|
86
|
+
| **AI recommendations** | Optional Claude AI suggestions for constraint relaxations or fixes |
|
|
87
|
+
| **Flexible constraints** | Supports `"any"`, `==`, `>=`, `<=`, `>`, `<`, comma-separated ranges |
|
|
88
|
+
| **REST API** | Simple JSON POST endpoint โ call from any language/tool |
|
|
89
|
+
| **Python library** | Import and use directly in your Python code |
|
|
90
|
+
| **Live demo** | Try instantly at [Heroku](https://sat-dependency-resolver-ae207ddb503e.herokuapp.com) |
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## ๐ฆ Installation
|
|
95
|
+
|
|
96
|
+
### Option 1: Install from PyPI (Recommended)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Basic installation
|
|
100
|
+
pip install sat-dependency-resolver
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Option 2: Install from Source
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Clone the repository
|
|
108
|
+
git clone https://github.com/Apollo87z/sat-dependency-resolver.git
|
|
109
|
+
cd sat-dependency-resolver
|
|
110
|
+
|
|
111
|
+
# Create virtual environment (recommended)
|
|
112
|
+
python -m venv venv
|
|
113
|
+
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
114
|
+
|
|
115
|
+
# Install dependencies
|
|
116
|
+
pip install -r requirements.txt
|
|
117
|
+
|
|
118
|
+
# Install in development mode
|
|
119
|
+
pip install -e .
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## ๐ Quick Start
|
|
125
|
+
|
|
126
|
+
### Using as a Python Library
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from sat_dependency_resolver import DependencyResolver
|
|
130
|
+
|
|
131
|
+
# Define your requirements
|
|
132
|
+
requirements = {
|
|
133
|
+
"django": ">=4.0"
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# Define available packages with their dependencies
|
|
137
|
+
available_packages = {
|
|
138
|
+
"django": [
|
|
139
|
+
{"version": "4.0", "requires": {"sqlparse": ">=0.3"}},
|
|
140
|
+
{"version": "4.1", "requires": {"sqlparse": ">=0.4"}},
|
|
141
|
+
],
|
|
142
|
+
"sqlparse": [
|
|
143
|
+
{"version": "0.3", "requires": {}},
|
|
144
|
+
{"version": "0.4", "requires": {}},
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
# Solve
|
|
149
|
+
resolver = DependencyResolver()
|
|
150
|
+
result = resolver.solve(requirements, available_packages)
|
|
151
|
+
|
|
152
|
+
# Check result
|
|
153
|
+
if result.is_satisfiable:
|
|
154
|
+
print(f"โ
Solution found: {result.solution}")
|
|
155
|
+
# Output: โ
Solution found: {'django': '4.1', 'sqlparse': '0.4'}
|
|
156
|
+
else:
|
|
157
|
+
print(f"โ No solution. Conflicts: {result.conflicts}")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Using the REST API
|
|
161
|
+
|
|
162
|
+
#### Start the API Server (Local)
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
# If installed from PyPI
|
|
166
|
+
python -m sat_dependency_resolver.api
|
|
167
|
+
|
|
168
|
+
# Or if cloned from source
|
|
169
|
+
python run_api.py
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
API will be available at `http://localhost:8091`
|
|
173
|
+
|
|
174
|
+
#### Make a Request
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
curl -X POST http://localhost:8091/resolve \
|
|
178
|
+
-H "Content-Type: application/json" \
|
|
179
|
+
-d '{
|
|
180
|
+
"requirements": {"django": ">=4.0"},
|
|
181
|
+
"available_packages": {
|
|
182
|
+
"django": [
|
|
183
|
+
{"version": "4.0", "requires": {"sqlparse": ">=0.3"}},
|
|
184
|
+
{"version": "4.1", "requires": {"sqlparse": ">=0.4"}}
|
|
185
|
+
],
|
|
186
|
+
"sqlparse": [
|
|
187
|
+
{"version": "0.3", "requires": {}},
|
|
188
|
+
{"version": "0.4", "requires": {}}
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
}'
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Response:**
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"satisfiable": true,
|
|
198
|
+
"solution": {
|
|
199
|
+
"django": "4.1",
|
|
200
|
+
"sqlparse": "0.4"
|
|
201
|
+
},
|
|
202
|
+
"conflicts": []
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## ๐ Use Cases
|
|
209
|
+
|
|
210
|
+
### Software Package Management
|
|
211
|
+
Resolve version conflicts for Python, npm, Cargo, RubyGems, etc.
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
requirements = {
|
|
215
|
+
"package-a": "==1.0",
|
|
216
|
+
"package-b": "==2.0"
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Course Prerequisites
|
|
221
|
+
Plan your academic path with prerequisite constraints.
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
requirements = {
|
|
225
|
+
"machine-learning": ">=1.0"
|
|
226
|
+
}
|
|
227
|
+
available_packages = {
|
|
228
|
+
"machine-learning": [{
|
|
229
|
+
"version": "1.0",
|
|
230
|
+
"requires": {
|
|
231
|
+
"linear-algebra": ">=1.0",
|
|
232
|
+
"calculus": ">=1.0",
|
|
233
|
+
"python": ">=1.0"
|
|
234
|
+
}
|
|
235
|
+
}],
|
|
236
|
+
# ... other courses
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Book Series / Reading Order
|
|
241
|
+
Find valid reading sequences for book series.
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
requirements = {
|
|
245
|
+
"lotr-return-of-king": "any"
|
|
246
|
+
}
|
|
247
|
+
available_packages = {
|
|
248
|
+
"lotr-return-of-king": [{
|
|
249
|
+
"version": "1.0",
|
|
250
|
+
"requires": {
|
|
251
|
+
"lotr-two-towers": ">=1.0"
|
|
252
|
+
}
|
|
253
|
+
}],
|
|
254
|
+
"lotr-two-towers": [{
|
|
255
|
+
"version": "1.0",
|
|
256
|
+
"requires": {
|
|
257
|
+
"lotr-fellowship": ">=1.0"
|
|
258
|
+
}
|
|
259
|
+
}],
|
|
260
|
+
# ... other books
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Hardware Compatibility
|
|
265
|
+
Check if PC parts are compatible.
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
requirements = {
|
|
269
|
+
"gpu": "rtx-4090",
|
|
270
|
+
"cpu": "i9-13900k"
|
|
271
|
+
}
|
|
272
|
+
available_packages = {
|
|
273
|
+
"gpu": [{
|
|
274
|
+
"version": "rtx-4090",
|
|
275
|
+
"requires": {
|
|
276
|
+
"psu": ">=850w",
|
|
277
|
+
"pcie": ">=4.0"
|
|
278
|
+
}
|
|
279
|
+
}],
|
|
280
|
+
# ... other components
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## ๐ API Reference
|
|
287
|
+
|
|
288
|
+
### Base URLs
|
|
289
|
+
|
|
290
|
+
- **Live (Production)**: `https://sat-dependency-resolver-ae207ddb503e.herokuapp.com`
|
|
291
|
+
- **Local Development**: `http://localhost:8091`
|
|
292
|
+
|
|
293
|
+
### Endpoints
|
|
294
|
+
|
|
295
|
+
#### `GET /health`
|
|
296
|
+
Check if the API is running.
|
|
297
|
+
|
|
298
|
+
**Response:**
|
|
299
|
+
```json
|
|
300
|
+
{
|
|
301
|
+
"status": "ok",
|
|
302
|
+
"message": "SAT Dependency Resolver API"
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
#### `GET /info`
|
|
307
|
+
Get API information and version.
|
|
308
|
+
|
|
309
|
+
**Response:**
|
|
310
|
+
```json
|
|
311
|
+
{
|
|
312
|
+
"name": "SAT Dependency Resolver",
|
|
313
|
+
"version": "0.1.1",
|
|
314
|
+
"description": "Universal dependency resolver using SAT solvers"
|
|
315
|
+
}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
#### `POST /resolve`
|
|
319
|
+
Resolve dependencies and return a solution or conflicts.
|
|
320
|
+
|
|
321
|
+
**Headers:**
|
|
322
|
+
- `Content-Type: application/json` (required)
|
|
323
|
+
- `X-API-Key: sk-ant-...` (optional, required only if `use_ai: true`)
|
|
324
|
+
|
|
325
|
+
**Request Body:**
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"requirements": {
|
|
329
|
+
"package-name": "constraint"
|
|
330
|
+
},
|
|
331
|
+
"available_packages": {
|
|
332
|
+
"package-name": [
|
|
333
|
+
{
|
|
334
|
+
"version": "1.0.0",
|
|
335
|
+
"requires": {
|
|
336
|
+
"dependency": "constraint"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
},
|
|
341
|
+
"use_ai": false
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
**Constraint Syntax:**
|
|
346
|
+
- `"any"` โ No restriction
|
|
347
|
+
- `"==1.2.3"` โ Exact version
|
|
348
|
+
- `">=1.0"` โ Greater than or equal
|
|
349
|
+
- `"<=2.0"` โ Less than or equal
|
|
350
|
+
- `">1.5"` โ Greater than
|
|
351
|
+
- `"<2.0"` โ Less than
|
|
352
|
+
- `">=1.0,<2.0"` โ Range (comma = AND)
|
|
353
|
+
|
|
354
|
+
**Response (Success):**
|
|
355
|
+
```json
|
|
356
|
+
{
|
|
357
|
+
"satisfiable": true,
|
|
358
|
+
"solution": {
|
|
359
|
+
"package-name": "1.0.0",
|
|
360
|
+
"dependency": "2.0.0"
|
|
361
|
+
},
|
|
362
|
+
"conflicts": []
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**Response (Conflict):**
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"satisfiable": false,
|
|
370
|
+
"solution": null,
|
|
371
|
+
"conflicts": [
|
|
372
|
+
"package-a requires dependency==1.0 but package-b requires dependency==2.0"
|
|
373
|
+
],
|
|
374
|
+
"recommendation": "Try relaxing constraint on dependency to >=1.0,<3.0"
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
380
|
+
## ๐งช Examples
|
|
381
|
+
|
|
382
|
+
### Example 1: Basic Resolution
|
|
383
|
+
|
|
384
|
+
```python
|
|
385
|
+
from sat_dependency_resolver import DependencyResolver
|
|
386
|
+
|
|
387
|
+
requirements = {"A": ">=2.0"}
|
|
388
|
+
available_packages = {
|
|
389
|
+
"A": [
|
|
390
|
+
{"version": "1.0", "requires": {}},
|
|
391
|
+
{"version": "2.0", "requires": {"B": ">=1.0"}},
|
|
392
|
+
{"version": "3.0", "requires": {"B": ">=2.0"}}
|
|
393
|
+
],
|
|
394
|
+
"B": [
|
|
395
|
+
{"version": "1.0", "requires": {}},
|
|
396
|
+
{"version": "2.0", "requires": {}}
|
|
397
|
+
]
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
resolver = DependencyResolver()
|
|
401
|
+
result = resolver.solve(requirements, available_packages)
|
|
402
|
+
print(result.solution)
|
|
403
|
+
# Output: {'A': '3.0', 'B': '2.0'}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Example 2: Conflict Detection
|
|
407
|
+
|
|
408
|
+
```python
|
|
409
|
+
requirements = {
|
|
410
|
+
"package-a": "==1.0",
|
|
411
|
+
"package-b": "==1.0"
|
|
412
|
+
}
|
|
413
|
+
available_packages = {
|
|
414
|
+
"package-a": [
|
|
415
|
+
{"version": "1.0", "requires": {"shared": "==1.0"}}
|
|
416
|
+
],
|
|
417
|
+
"package-b": [
|
|
418
|
+
{"version": "1.0", "requires": {"shared": "==2.0"}}
|
|
419
|
+
],
|
|
420
|
+
"shared": [
|
|
421
|
+
{"version": "1.0", "requires": {}},
|
|
422
|
+
{"version": "2.0", "requires": {}}
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
resolver = DependencyResolver()
|
|
427
|
+
result = resolver.solve(requirements, available_packages)
|
|
428
|
+
print(f"Satisfiable: {result.is_satisfiable}")
|
|
429
|
+
print(f"Conflicts: {result.conflicts}")
|
|
430
|
+
# Output: Satisfiable: False
|
|
431
|
+
# Conflicts: ["can't resolve - probably circular deps or version mismatch"]
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Example 3: Using AI Recommendations
|
|
435
|
+
|
|
436
|
+
```python
|
|
437
|
+
from sat_dependency_resolver import DependencyResolver
|
|
438
|
+
|
|
439
|
+
requirements = {"django": ">=5.0"} # No version 5.0 available
|
|
440
|
+
available_packages = {
|
|
441
|
+
"django": [
|
|
442
|
+
{"version": "4.0", "requires": {}},
|
|
443
|
+
{"version": "4.1", "requires": {}}
|
|
444
|
+
]
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
resolver = DependencyResolver()
|
|
448
|
+
result = resolver.solve(
|
|
449
|
+
requirements,
|
|
450
|
+
available_packages,
|
|
451
|
+
use_ai=True,
|
|
452
|
+
api_key="sk-ant-your-key-here"
|
|
453
|
+
)
|
|
454
|
+
|
|
455
|
+
if not result.is_satisfiable:
|
|
456
|
+
print(f"AI Recommendation: {result.recommendation}")
|
|
457
|
+
# Output: AI suggestions for fixing the constraint
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
### Example 4: REST API with curl
|
|
461
|
+
|
|
462
|
+
**Successful Resolution:**
|
|
463
|
+
```bash
|
|
464
|
+
curl -X POST http://localhost:8091/resolve \
|
|
465
|
+
-H "Content-Type: application/json" \
|
|
466
|
+
-d '{
|
|
467
|
+
"requirements": {"python": ">=3.8"},
|
|
468
|
+
"available_packages": {
|
|
469
|
+
"python": [
|
|
470
|
+
{"version": "3.8", "requires": {}},
|
|
471
|
+
{"version": "3.9", "requires": {}},
|
|
472
|
+
{"version": "3.10", "requires": {}}
|
|
473
|
+
]
|
|
474
|
+
}
|
|
475
|
+
}'
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
**With Conflicts:**
|
|
479
|
+
```bash
|
|
480
|
+
curl -X POST http://localhost:8091/resolve \
|
|
481
|
+
-H "Content-Type: application/json" \
|
|
482
|
+
-d '{
|
|
483
|
+
"requirements": {
|
|
484
|
+
"app": "==1.0"
|
|
485
|
+
},
|
|
486
|
+
"available_packages": {
|
|
487
|
+
"app": [
|
|
488
|
+
{"version": "1.0", "requires": {"lib": "==1.0"}},
|
|
489
|
+
{"version": "2.0", "requires": {"lib": "==2.0"}}
|
|
490
|
+
],
|
|
491
|
+
"lib": [
|
|
492
|
+
{"version": "2.0", "requires": {}}
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
}'
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
---
|
|
499
|
+
|
|
500
|
+
## ๐งช Running Tests
|
|
501
|
+
|
|
502
|
+
### Basic Test Suite
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
# Run quick tests
|
|
506
|
+
python tests/test_quick.py
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Create Your Own Test
|
|
510
|
+
|
|
511
|
+
Create `test_custom.py`:
|
|
512
|
+
|
|
513
|
+
```python
|
|
514
|
+
from sat_dependency_resolver import DependencyResolver
|
|
515
|
+
|
|
516
|
+
def test_my_scenario():
|
|
517
|
+
requirements = {
|
|
518
|
+
"my-package": ">=1.0"
|
|
519
|
+
}
|
|
520
|
+
available_packages = {
|
|
521
|
+
"my-package": [
|
|
522
|
+
{"version": "1.0", "requires": {}}
|
|
523
|
+
]
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
resolver = DependencyResolver()
|
|
527
|
+
result = resolver.solve(requirements, available_packages)
|
|
528
|
+
|
|
529
|
+
assert result.is_satisfiable == True
|
|
530
|
+
assert "my-package" in result.solution
|
|
531
|
+
print("โ
Test passed!")
|
|
532
|
+
|
|
533
|
+
if __name__ == "__main__":
|
|
534
|
+
test_my_scenario()
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
Run it:
|
|
538
|
+
```bash
|
|
539
|
+
python test_custom.py
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## ๐ง Development
|
|
545
|
+
|
|
546
|
+
### Project Structure
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
sat-dependency-resolver/
|
|
550
|
+
โโโ sat_dependency_resolver/
|
|
551
|
+
โ โโโ __init__.py # Package exports
|
|
552
|
+
โ โโโ encoder.py # SAT encoding logic
|
|
553
|
+
โ โโโ resolver.py # Main resolver
|
|
554
|
+
โ โโโ api.py # Flask REST API
|
|
555
|
+
โ โโโ ai_agent.py # AI recommendations (optional)
|
|
556
|
+
โโโ examples/
|
|
557
|
+
โ โโโ basic_usage.py
|
|
558
|
+
โ โโโ courses.py
|
|
559
|
+
โ โโโ api_example.sh
|
|
560
|
+
โโโ tests/
|
|
561
|
+
โ โโโ test_quick.py
|
|
562
|
+
โโโ run_api.py # API entry point
|
|
563
|
+
โโโ requirements.txt
|
|
564
|
+
โโโ setup.py
|
|
565
|
+
โโโ README.md
|
|
566
|
+
โโโ LICENSE
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
### Running Locally
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
# Clone and setup
|
|
573
|
+
git clone https://github.com/Apollo87z/sat-dependency-resolver.git
|
|
574
|
+
cd sat-dependency-resolver
|
|
575
|
+
python -m venv venv
|
|
576
|
+
source venv/bin/activate
|
|
577
|
+
pip install -e ".[api,ai]"
|
|
578
|
+
|
|
579
|
+
# Run API
|
|
580
|
+
python run_api.py
|
|
581
|
+
|
|
582
|
+
# Run tests
|
|
583
|
+
python tests/test_quick.py
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## ๐ค Contributing
|
|
589
|
+
|
|
590
|
+
Contributions are welcome! Here's how:
|
|
591
|
+
|
|
592
|
+
1. Fork the repository
|
|
593
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
594
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
595
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
596
|
+
5. Open a Pull Request
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## ๐ License
|
|
601
|
+
|
|
602
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## ๐ Support
|
|
607
|
+
|
|
608
|
+
- **Issues**: [GitHub Issues](https://github.com/Apollo87z/sat-dependency-resolver/issues)
|
|
609
|
+
- **Discussions**: [GitHub Discussions](https://github.com/Apollo87z/sat-dependency-resolver/discussions)
|
|
610
|
+
- **Author**: [@Apollo87z](https://github.com/Apollo87z)
|
|
611
|
+
- **Email**: shehan87h@gmail.com
|
|
612
|
+
|
|
613
|
+
---
|
|
614
|
+
|
|
615
|
+
## ๐ Acknowledgments
|
|
616
|
+
|
|
617
|
+
- Built with [PySAT](https://pysathq.github.io/) and Glucose3 solver
|
|
618
|
+
- Optional AI powered by [Anthropic Claude](https://www.anthropic.com/)
|
|
619
|
+
- Inspired by the need for universal, mathematically sound dependency resolution
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
<div align="center">
|
|
624
|
+
|
|
625
|
+
**Made by [Shehan Horadagoda](https://github.com/Apollo87z)**
|
|
626
|
+
|
|
627
|
+
โญ Star this repo if you find it useful!
|
|
628
|
+
|
|
629
|
+
</div>
|