Nelumbo documentation
Nelumbo is a declarative logic programming language that you extend from inside the language. You define the syntax and semantics of your language in a .nl file, and the same file runs and tests it. Because Nelumbo reasons about facts and falsehoods as peers, it has genuine logical negation — not Prolog's negation-as-failure — and produces results as a two-sided [facts][falsehoods] structure.
Status: Nelumbo is at an early stage of development. Some features are still evolving; where that matters, individual pages note it.
This folder contains the user documentation. For the project overview, build instructions, and release notes, see the repository README. For the presentation-deck version of this material, see NELUMBO.md.
The levels
Nelumbo is built in levels, and each piece of syntax belongs to exactly one of them. The reference is organised the same way, so you can always tell where a construct comes from.
Java core bootstrap grammar, reasoner, natives
└─ nelumbo.lang import nelumbo.lang
└─ nelumbo.logic import nelumbo.logic
└─ nelumbo.integers
└─ nelumbo.strings, nelumbo.rationals, nelumbo.collections, nelumbo.datetime
- Java core. The tokenizer, the reasoner,
@-bound natives, and a small bootstrap grammar that exists only to loadlang.nl. nelumbo.lang. The syntax for declaring syntax: types (::), patterns (::=), named patterns, variables, scope blocks, visibility, precedence, and::>transformations.nelumbo.logic. Three-valued logic:Boolean, the connectives, quantifiers, equality, and the statements that drive execution (fact,<=>,?).- Packages. Integers, rationals, strings, collections and date-times. Import the ones you need.
Importing a level brings in everything above it in the diagram, so import nelumbo.integers also gives you nelumbo.logic and nelumbo.lang. That is why most files start with a single package import.
Start here
- Reading a query and test — the first thing to read. Without this, every
.nlfile in the repo is unreadable because every example ends with tests in the? [facts][falsehoods]notation. - Your first program — line-by-line walkthrough of
fibonacci.nl, exercising imports, patterns, rules with guards, and tests.
Thirty minutes with those two pages is enough to open any .nl file in the repo and follow what's going on.
Reading paths
Different readers want different things. Pick the path that matches your goal.
"I want to understand what Nelumbo is and why."
- Reading a query and test — the language's headline feature, three-valued logic
- Architecture — how Nelumbo is layered — Java core →
nelumbo.lang→nelumbo.logic→ optional packages → user code - Bootstrap grammar — the only syntax written in Java, and why it exists
- Three-valued logic — the semantic foundation, with truth tables
nelumbo.lang— the.nlfile that declares the whole syntax, including::,::=,::>, and the pattern meta-grammarnelumbo.logic— the.nlfile that declaresBoolean, the connectives, equality, and thefact/<=>/?statement forms
"I want to write my own DSL using Nelumbo."
- The starting pair above, then
- Grammar, Statements and Operators — reference
- Writing rules —
<=>, guards, merging, contradictions - Language transformations — the
::>mechanism for defining new keywords (status: under construction) - Writing your own module — packaging a reusable library
"I want to extend Nelumbo with a new primitive in Java."
- Architecture — understand the layering first
- Native API — the
Predicate,InferResult,infer()surface - Native classes catalogue — what's already shipped
- Native cookbook — five recipes with complete skeletons
"I want to read the shipped modules to learn idiom."
- Standard library tour — all seven modules in dependency order
nelumbo.langandnelumbo.logic, then the packagesintegers,rationals,strings,collections,datetime— per-module reference
"I need to look something up."
Jump straight to the reference sections below, starting at Reference: Core. Everything in reference/ is organised as a lookup, not a read-through.
Full table of contents
Getting started
Reference: Core
The Java level. Always present.
- Bootstrap grammar — the syntax hardcoded in Java so that
lang.nlcan be loaded - Native API — implementing predicates in Java
- Native classes catalogue — every shipped
@-bound class
Reference: Lang
nelumbo.lang, the syntax for declaring syntax.
nelumbo.lang— the module: token types, object hierarchy, pattern meta-grammar, top-level statements- Grammar — types, patterns, variables, scope blocks,
::> - Built-in tokens and pattern holes —
<NUMBER>,<STRING>,<Variable>, etc. - Precedence and associativity — the
#Nsystem - Visibility —
private,hidden,visible, and scope blocks
Reference: Logic
nelumbo.logic, three-valued logic and the statements that drive execution.
nelumbo.logic— the module: Boolean, connectives, quantifiers, equality- Statements — facts, queries and tests
- Operators — the logical operators and
fact/<=>/? - Writing rules —
<=>, guards, merging, contradictions - Three-valued logic — truth tables and identities
- Test expression semantics — formal definition of when a test passes
Reference: Packages
Optional. Each one imports nelumbo.logic, directly or through nelumbo.integers.
nelumbo.integers— arbitrary-precision integer arithmeticnelumbo.rationals— exact rationalsnelumbo.strings— strings, concatenation, conversionnelumbo.collections— genericSet<E>andList<E>, set-builder notation, and operations (cardinality, membership, subset, union/intersection/difference, concatenation, indexing)nelumbo.datetime— ISO 8601 dates, times, date-times, and durations
Reference: Tooling
- Formatting — the canonical whitespace layout the LSP formatter produces
Guides
Task-oriented how-tos.
- Standard library tour — reading all seven stdlib modules in order
- Writing your own module — packaging a reusable library
- Language transformations — the
::>meta-feature (under construction) - Native cookbook — recipes for writing Java natives
Explanation
Background and design.
Map of the example files
The .nl files under src/main/resources/org/modelingvalue/nelumbo/examples/ are the canonical worked examples. A short guide to what's in each:
| File | What it demonstrates |
|---|---|
fibonacci.nl |
Integer arithmetic, recursive rule with guards, basic tests |
family.nl |
Types, subtypes, Boolean, literal enumerations, ancestor/descendant recursion |
friends.nl |
Mutually-recursive relations, symmetric + transitive closure |
even.nl |
Simplest useful predicate using an existential quantifier |
max.nl, ternary.nl |
Generic types (Type T), conditional expressions, user-defined operators |
power.nl, maxFib.nl |
Composed recursive definitions |
belasting.nl |
Natural-language DSL (Dutch tax rules) using multi-word pattern syntax |
transformation.nl, deHet.nl |
Language transformations with ::> — defining new top-level keywords |
scoping.nl, hidden.nl |
Scope blocks and hidden-variable patterns |
whoIs.nl |
Importing a user-written module (not just stdlib) |
queryOnly.nl |
Bare queries without [..][..] — useful during development |
*Assignment.nl |
"Fill in the rules" exercise versions of the corresponding examples |
Map of the test files
The *Test.nl files under src/main/resources/org/modelingvalue/nelumbo/tests/ are executable specifications — useful to skim for corner cases:
| File | What it specifies |
|---|---|
logicTest.nl |
The three-valued logic truth tables |
integersTest.nl, rationalsTest.nl, stringsTest.nl, collectionsTest.nl |
Per-stdlib-module behaviour for each data type |
datetimeTest.nl |
Every datetime operator and the parse-time edge cases |
langTest.nl |
Smoke test that imports nelumbo.lang on its own |
A note on conventions used in the docs
..is the incompleteness marker — it means "this side of the result may have more bindings than are listed." It is never called a wildcard because it doesn't match values. Inside a collection ({Juliana,..}) it marks that set or list as open.- Facts (left bracket) and falsehoods (right bracket) are the two sides of every query result.
- In-language extensions (rules, transformations, modules) are distinguished from host-language extensions (Java natives bound with
@). The docs use these terms consistently. - Cross-references in every page point to other pages when a topic is covered in more depth elsewhere. If you follow the links, you end up with a coherent tour of the language.
Feedback and contributing
The documentation is new and will have errors. Corrections and suggestions are welcome via the GitHub issue tracker. The source files for the docs are under docs/ in the repository.