Nelumbo

June 24, 2026 ยท View on GitHub

Nelumbo

Logic Meta Language

  • Fast logic Reasoning
  • Define and parse Syntaxes
  • Define and execute Semantics
  • Define and run Tests
  • IDE integration using LSP
  • Lightweight Language Workbench

Requirements for Nelumbo

  • Suitable for formalization of, for example, complex tax laws and clinical knowledge
  • Semantically rich and proven consistent
  • Direct support for predicate logic by reasoning over incomplete facts and falsehoods
  • Fully declarative, hence, no over-specification
  • Strongly typed for more consistency and extensibility
  • Performant by binding variables based on navigating relations only
  • Easily extensible and integrable with the use of native classes
  • Full editor support in any IDE using the Language Server Protocol

Syntax

Types

  Smart   :: Object
  Living  :: Object
  LLM     :: Smart
  Person  :: Smart, Living
  Male    :: Person
  Female  :: Person

Patterns

  Integer ::= <NUMBER>                         // 10
  Integer ::= <Integer> - <Integer>  #40,      // 5-7
              <Integer> + <Integer>  #40,      // 5+7
                        - <Integer>  #80,      // -7
              fib(<Integer>)                   // fib(100)
                              
  Repetion    ::= { <(> <Integer> <,> , <)*> }  // {3,5,7}
  Option      ::= <(> super <)?> fast           // fast, super fast
  Alternation ::= <(> A <|> B <|> C <)>         // A, B, C

Semantics

Variables

  Integer a, b, c
  Person  x, y, z 

Rules

  a<=b    <=>  a<b | a=b
  
  |a|=b   <=>  b=a   if a>=0,
               b=-a  if a<0
 
  descendant(x)=z <=> child(x)=z |
                      E[y](descendant(x)=y & child(y)=z)

Running

Queries

  a+11=21   ?     // [(a=10)][..]

Testing

  a+11=21   ?   [(a=10)][..]
  |a|=10    ?   [(a=-10),(a=10)][(a=0),..]

Proof

  a+11=21
    a+11=21 <=> add(a,11,21)
      add(c,11,21) [(c=10)][..]
    c+11=21 [(c=10)][..]
  a+11=21 [(a=10)][..]

Native Semantics

Declaration

  private Boolean ::= add(<Integer>,<Integer>,<Integer>)
                      @org.modelingvalue.nelumbo.integers.Integers

Java Code

The logic is a @NelumboMethod whose name and parameter count match the functor (the preferred style; see docs/guides/native-cookbook.md). Each bound argument arrives as its typed NInteger, each unbound one as null:

 @NelumboMethod
 protected InferResult add(NInteger addend1, NInteger addend2, NInteger sum) {
    if (nrOfUnbound() > 1) {
        return unknown();
    }
    BigInteger a1 = addend1 == null ? null : addend1.value();
    BigInteger a2 = addend2 == null ? null : addend2.value();
    BigInteger s  = sum     == null ? null : sum.value();
    if (a1 != null && a2 != null) {
        BigInteger r = a1.add(a2);
        if (s != null) {
            return r.equals(s) ? factCC() : falsehoodCC();
        } else {
            return set(2, NInteger.of(r)).factCI();
        }
    } else if (a1 != null && s != null) {
        return set(1, NInteger.of(s.subtract(a1))).factCI();
    } else if (a2 != null && s != null) {
        return set(0, NInteger.of(s.subtract(a2))).factCI();
    } else {
        return unknown();
    }
}

Fibonacci Example

  Integer ::= fib(<Integer>)

  Integer n, f

  fib(n)=f <=> f=n                 if n<=1,
               f=fib(n-1)+fib(n-2) if n>1  
    
  fib(0)=f       ? [(f=0)][..]
  fib(1)=f       ? [(f=1)][..]
  fib(5)=f       ? [(f=5)][..]
  fib(100)=f     ? [(f=36#22r8fozas3n8w3)][..]
  fib(1000)=f    ? [(f=36#18nrvsuayughau0blk8aylvbyaqwiaqba77rdsgscn5hzwgbgaws8i8svp4xdmoo82plxiyogd5iaj1cspez8zfeio92a76t9n1frssxklr92wyyxm8r903o1ofgncikuggcwnf)][..]


Literals

  Male    ::= Hendrik, Bernhard, Claus, Willem
  Female  ::= Wilhelmina, Juliana, Beatrix, Maxima, Amalia
  
  Integer ::= <NUMBER>    @org.modelingvalue.nelumbo.integers.Integer

Functions

  Integer ::= <Integer> -  <Integer>  #40,
              <Integer> +  <Integer>  #40

  a+b=c  <=>  add(a,b,c)
  a-b=c  <=>  add(c,b,a)

FactTypes and Facts

  FactType  ::= pc(<Person>,<Person>)   // parent-child

  // Facts
  pc(Beatrix, Willem)
  pc(Claus, Willem)
  pc(Willem, Amalia)
  pc(Maxima, Amalia)

Predicates

  Boolean ::= <Integer> "<=" <Integer>  #30
                    
  a<=b    <=>  a<b | a=b

OperatorMeaning
::Type
::=Pattern
<=>Rule

Demo

LIVE


Plans

  • Namespaces
  • Generics (type arguments)
  • Lists and Sets
  • Language pattern transformations
  • LSP (also on WEB)
  • Reactive update execution semantics
  • Deprecation and migration support
  • ....

Contributing


Q&A