neorusticus 0.1.3

A Prolog implementation in Rust with enhanced error handling
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
![NeoRusticus](assets/neorusticus-social-preview-github-1200x630.png)

[![Crates.io](https://img.shields.io/crates/v/neorusticus.svg)](https://crates.io/crates/neorusticus)
[![Documentation](https://docs.rs/neorusticus/badge.svg)](https://docs.rs/neorusticus)
[![Build Status](https://github.com/fermatrox/neorusticus/workflows/CI/badge.svg)](https://github.com/fermatrox/neorusticus/actions)
[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](https://github.com/fermatrox/neorusticus#license)

A modern Prolog implementation in Rust with enhanced error handling, comprehensive built-ins, and developer-friendly features.

## Why "NeoRusticus"?


The name **NeoRusticus** carries deep meaning that reflects the project's philosophy and aspirations:

### **Neo** - Modern Innovation


The "Neo" prefix represents the modern, experimental approach to logic programming. It suggests evolution beyond traditional Prolog into areas like:

- Probabilistic reasoning
- Constraint logic programming
- AI-assisted development methodologies
- Integration with modern computational paradigms

### **Rusticus** - Classical Foundations


"Rusticus" has multiple layers of meaning:

**Historical Depth**: References **Junius Rusticus**, the Stoic philosopher and teacher of Marcus Aurelius. This connection is perfect for logic programming, which has deep philosophical roots in formal reasoning and logical inference—core concepts in Stoic philosophy.

**Earthy Practicality**: In Latin, "rusticus" means "of the countryside"—practical, grounded, and unpretentious. This fits both Rust's earthy, no-nonsense approach to systems programming and the project's focus on building something genuinely useful rather than merely academic.

**Academic Gravitas**: The name sounds scholarly and distinctive, appropriate for a serious exploration of language implementation and logic programming concepts.

**Experimental Spirit**: The "rough around the edges" connotation captures the experimental nature of this AI-assisted development project—it's a work in progress, a learning journey, not a polished commercial product.

Together, **NeoRusticus** embodies the vision of bringing classical logic programming wisdom into the modern era through Rust's safety and performance, while remaining open to experimental evolution.

## The Logo


The **Psi (Ψ)** symbol serves as Neorusticus's logo, chosen for its rich symbolic meaning:

### **Mind & Consciousness**


Psi represents the mind, consciousness, and mental processes—perfect for a system that performs logical reasoning and artificial intelligence.

### **Computational Logic**


In computer science and AI, Psi often symbolizes intelligent systems, logical inference, and computational thinking.

### **Classical Foundation**


The symbol's Greek origins echo the classical foundations of logic (Aristotle, Stoics) while the clean, geometric form represents modern computational precision.

### **Transcendent Potential**


The elevated, distinctive shape suggests rising above traditional limitations—fitting for a project that might evolve beyond conventional Prolog into experimental territories.

The Psi symbol perfectly captures Neorusticus's essence: a bridge between ancient wisdom and modern innovation, between human reasoning and artificial intelligence, between classical logic and experimental possibilities.

## Project Goals


Neorusticus serves multiple ambitious goals that go beyond just building another Prolog implementation:

### **Learn Rust Through Real-World Application**


Rather than learning Rust through tutorials and toy examples, this project explores advanced Rust concepts—pattern matching, error handling, lifetimes, zero-cost abstractions, and memory safety—through a substantial, practical implementation. Every design decision provides deep insights into what makes Rust unique for systems programming.

### **Deep Understanding of Prolog Implementation**


Building a complete Prolog interpreter from scratch—lexer, parser, unification algorithm, and execution engine—provides intimate knowledge of how logic programming languages work. This includes understanding SLD resolution, backtracking, cut operations, and the subtleties of variable scoping and renaming.

### **Flexible Framework for Future Exploration**


Neorusticus is designed as a foundation for exploring advanced logic programming concepts and experimental features. The modular architecture allows for future expansion into areas like:

- Constraint Logic Programming (CLP)
- Tabled resolution and memoization
- Probabilistic logic programming
- Integration with machine learning systems
- Novel optimization techniques
- Educational tools and visualizations

### **AI-Assisted Development Experiment**


This project serves as a comprehensive case study in AI-assisted software development, with AI tools playing dual roles:

- **Expert Advisor**: Providing architectural guidance, best practices, algorithm explanations, and design recommendations
- **Code Developer**: Generating implementations, writing tests, debugging issues, and refactoring code

The goal is to evaluate how effectively AI can contribute to complex software projects when working with a technical leader who provides direction, requirements, and quality oversight. This collaboration model represents a new paradigm in software development that's worth studying and documenting.

This multi-faceted approach makes Neorusticus both a learning vehicle and a research platform, demonstrating the potential of combining human expertise with AI capabilities to tackle ambitious technical projects.

## Features


- **Complete Prolog syntax** - Facts, rules, queries with proper operator precedence
-**Rich built-in predicates** - Arithmetic, type checking, list operations, and control flow
-**Enhanced error handling** - Detailed error messages with suggestions for typos
-**Stack overflow protection** - Configurable limits to prevent runaway recursion
-**Interactive REPL** - Command-line interface for experimenting with Prolog
-**Variable renaming** - Proper scoping and conflict resolution
-**Anonymous variables** - ISO-compliant handling where each `_` is distinct
-**Cut operation** - Full support for controlling backtracking with `!`
-**List processing** - Built-in predicates for working with lists
-**Type safety** - Comprehensive type checking predicates
-**Comprehensive test suite** - Extensive tests covering all functionality

## Installation


Add this to your `Cargo.toml`:

```toml
[dependencies]
neorusticus = "0.1.0"
```

Or install the CLI tool:

```bash
cargo install neorusticus
```

## Quick Start


### Library Usage


```rust
use neorusticus::PrologEngine;

fn main() {
    let mut engine = PrologEngine::new();

    // Add some facts
    engine.parse_and_add("parent(tom, bob).").unwrap();
    engine.parse_and_add("parent(bob, ann).").unwrap();
    engine.parse_and_add("parent(ann, sue).").unwrap();

    // Add a rule
    engine.parse_and_add("grandparent(X, Z) :- parent(X, Y), parent(Y, Z).").unwrap();

    // Query the database
    let solutions = engine.parse_query("grandparent(tom, sue).").unwrap();
    println!("Solutions found: {}", solutions.len());

    // Query with variables
    let solutions = engine.parse_query("grandparent(tom, X).").unwrap();
    engine.print_solutions(&solutions, &["X".to_string()]);
}
```

### Interactive REPL


```bash
cargo run --example interactive
```

```prolog
=== Neorusticus Prolog Interactive Shell ===
Enter Prolog clauses (ending with .) or queries (ending with ? or .)
Type 'help' for commands, 'quit' to exit.

?- parent(tom, bob).
true.

?- parent(tom, X).
X = bob.

?- X is 2 + 3 * 4.
X = 14.

?- append([1, 2], [3, 4], X).
X = [1, 2, 3, 4].

?- help
Commands:
  help    - Show this help message
  quit    - Exit the shell
  stats   - Show engine statistics
  clear   - Clear the database
```

## Documentation


### Built-in Predicates


#### Arithmetic Operations


```prolog
?- X is 2 + 3 * 4.     % X = 14 (respects precedence)
?- 5 > 3.              % true
?- 10 =:= 5 + 5.       % true (arithmetic equality)
?- 7 =\= 3.            % true (arithmetic inequality)
```

#### List Operations


```prolog
?- append([1, 2], [3, 4], X).    % X = [1, 2, 3, 4]
?- member(2, [1, 2, 3]).         % true
?- length([a, b, c], X).         % X = 3
```

#### Type Checking


```prolog
?- var(X).             % true (X is uninstantiated)
?- atom(hello).        % true
?- number(42).         % true
?- compound(f(x)).     % true
```

#### Anonymous Variables


```prolog
% Each _ is automatically renamed to a unique variable
?- test(_, _, _).      % Internally becomes test(_G1, _G2, _G3)

% Named underscore variables are preserved
?- foo(_temp, _).      % _temp stays as _temp, _ becomes _G1

% Useful for pattern matching when you don't care about some values
?- member(2, [1, _, 3]).   % Matches lists with any value in middle position
```

#### Control Flow


```prolog
% Cut operation prevents backtracking
max(X, Y, X) :- X >= Y, !.
max(X, Y, Y).

?- max(5, 3, Z).       % Z = 5 (doesn't try second clause)
```

### Advanced Features


#### Error Handling with Suggestions


```prolog
?- lentgh([1, 2, 3], X).
Error: Undefined predicate: lentgh/2. Did you mean: length/2

?- appendd([1], [2], X).
Error: Undefined predicate: appendd/3. Did you mean: append/3
```

#### Stack Overflow Protection


```rust
let mut engine = PrologEngine::with_config(100, 50); // max solutions, max stack depth
engine.parse_and_add("infinite(X) :- infinite(X).").unwrap();

// This will error instead of hanging:
let result = engine.parse_query("infinite(test).");
// Error: Stack overflow (depth 50) in predicate: infinite/1
```

## Configuration


### Engine Limits


```rust
use neorusticus::PrologEngine;

// Create engine with custom limits
let mut engine = PrologEngine::with_config(
    1000,  // Maximum solutions
    200,   // Maximum stack depth
);

// Or adjust limits later
engine.set_max_solutions(500);
engine.set_max_stack_depth(100);
```

### Error Handling


```rust
use neorusticus::PrologEngine;

let mut engine = PrologEngine::new();

match engine.parse_and_add("invalid syntax here") {
    Ok(()) => println!("Added successfully"),
    Err(e) => {
        engine.print_error(&e);  // Pretty-printed error with context
    }
}
```

## Examples


The `examples/` directory contains several demonstration programs:

### Basic Usage


```bash
cargo run --example basic_usage
```

Demonstrates core functionality with error handling.

### Arithmetic Operations


```bash
cargo run --example arithmetic
```

Shows arithmetic predicates, functions, and mathematical sequences.

### Interactive Shell


```bash
cargo run --example interactive
```

Full-featured REPL for experimenting with Prolog.

## Running Tests


```bash
# Run all tests

cargo test

# Run with output

cargo test -- --nocapture

# Run specific test module

cargo test engine::tests

# Run integration tests

cargo test --test error_tests
```

## Architecture


Neorusticus is built with a modular architecture:

- **`lexer`** - Tokenizes Prolog source code with position tracking
- **`parser`** - Recursive descent parser with operator precedence
- **`ast`** - Abstract syntax tree types for terms and clauses
- **`unification`** - Robinson's unification algorithm with occurs check
- **`engine`** - Core execution engine with SLD resolution
- **`builtins`** - Built-in predicates for arithmetic, lists, and control
- **`error`** - Comprehensive error types with suggestions
- **`utils`** - Utility functions for pretty printing and analysis

## Prolog Syntax Supported


### Facts and Rules


```prolog
% Facts
parent(tom, bob).
likes(mary, wine).

% Rules
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
happy(X) :- likes(X, wine).
```

### Data Types


```prolog
% Atoms
hello
'quoted atom'

% Numbers
42
-17

% Variables
X
_anonymous
CamelCase

% Lists
[]
[1, 2, 3]
[H|T]
[1, 2, 3|Rest]

% Compound Terms
foo(bar, baz)
person(name(john, doe), age(25))
```

### Operators


```prolog
% Arithmetic
X is 2 + 3 * 4    % Precedence: *, +
Y is (2 + 3) * 4  % Parentheses override

% Comparison
5 > 3             % Greater than
X =:= Y + 1       % Arithmetic equality
A = B             % Unification

% Built-in Functions
abs(-5)           % Absolute value
max(3, 7)         % Maximum
min(10, 5)        % Minimum
```

## Performance


Neorusticus is designed for correctness and safety first, with reasonable performance:

- **Memory safe** - No unsafe code, all memory managed by Rust
- **Stack overflow protection** - Configurable limits prevent runaway recursion
- **Efficient unification** - Optimized Robinson's algorithm
- **Minimal allocations** - Reuses data structures where possible

Benchmarks (on modern hardware):

- Simple queries: ~1-10μs
- Complex recursive queries: ~100μs-1ms
- Large fact databases: Scales linearly

## Contributing


This project is primarily a **personal learning experiment** and **AI-assisted development study**. As such, I'm not accepting direct code contributions at this time, as the goal is to evaluate how effectively complex software can be developed through AI collaboration.

However, other types of contributions are very welcome and valuable:

### **Ideas and Suggestions**


- Feature ideas for future exploration
- Architectural improvements
- Performance optimization suggestions
- Ideas for experimental Prolog features
- Suggestions for AI development methodology improvements

### **Bug Reports**


- Detailed bug reports with reproduction steps
- Edge cases that break the engine
- Parser or lexer issues
- Documentation errors or unclear explanations

### **Discussions**


- Feedback on implementation approaches
- Discussions about Prolog language features
- Thoughts on AI-assisted development process
- Ideas for research directions or extensions

### **Documentation and Examples**


- Suggestions for better documentation
- Ideas for additional examples
- Educational use cases
- Tutorial improvements

### **Testing and Validation**


- Testing the engine with complex Prolog programs
- Validation against standard Prolog behavior
- Performance benchmarking
- Compatibility testing

Please open **GitHub Issues** for any of the above! I'm particularly interested in:

- Feedback on the AI-assisted development approach
- Ideas for experimental features to explore
- Educational use cases and examples
- Any bugs or limitations you discover

### Development Philosophy


This project serves as a case study in AI-human collaboration for complex software development. The development process intentionally relies on AI tools as both advisor and code developer, with human oversight providing direction, requirements, and quality control. This approach aims to evaluate the current capabilities and limitations of AI-assisted development for substantial technical projects.

If you're interested in similar experiments or want to discuss the methodology, I'd love to hear from you!

## Project Status


Neorusticus is in active development. Current status:

- **Core Prolog functionality** - Complete
-**Built-in predicates** - Comprehensive set available
-**Error handling** - Robust with helpful messages
-**Test coverage** - Extensive test suite
- 🚧 **Performance optimization** - Ongoing
- 🚧 **Advanced features** - Planned (constraints, tabling)
- 📋 **Standard library** - Planned (more built-ins)

## Roadmap


### Version 0.2.0


- [ ] Definite Clause Grammars (DCG) support
- [ ] More list processing predicates
- [ ] Improved performance with term indexing
- [ ] Module system

### Version 0.3.0


- [ ] Constraint Logic Programming (CLP)
- [ ] Tabled resolution for better termination
- [ ] Debugging and tracing facilities
- [ ] Integration with external databases

## Related Projects


- **SWI-Prolog** - The most popular Prolog implementation
- **GNU Prolog** - Fast, standard-compliant Prolog
- **Tau Prolog** - Prolog in JavaScript
- **Scryer Prolog** - Modern Prolog in Rust (different approach)

## Acknowledgments


- The Prolog community for decades of research and development
- The Rust community for excellent tooling and libraries
- Warren's Abstract Machine (WAM) for inspiring efficient Prolog implementation

## Citation


If you use Neorusticus in academic work, please cite:

```bibtex
@software{neorusticus,
  author = {Jonas Forsman},
  title = {Neorusticus: A Modern Prolog Implementation in Rust},
  year = {2025},
  url = {https://github.com/fermatrox/neorusticus}
}
```

## License


Licensed under either of

- Apache License, Version 2.0
  ([LICENSE-APACHE]LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license
  ([LICENSE-MIT]LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

## Contribution


Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.