|  | 
|  | 1 | +# Learn Stellogen | 
|  | 2 | + | 
|  | 3 | +> **Disclaimer**: This document was written with the assistance of Claude Code and represents exploratory research and analysis. The content may contain inaccuracies or misinterpretations and should not be taken as definitive statements about the Stellogen language implementation. | 
|  | 4 | +
 | 
|  | 5 | +Stellogen is an experimental, logic-agnostic programming language built on **term unification**. Instead of types or fixed logic, programs and meaning are expressed with the same raw material. | 
|  | 6 | + | 
|  | 7 | +This guide walks you through the basics. | 
|  | 8 | + | 
|  | 9 | +--- | 
|  | 10 | + | 
|  | 11 | +## Comments | 
|  | 12 | + | 
|  | 13 | +```stellogen | 
|  | 14 | +' single line | 
|  | 15 | +
 | 
|  | 16 | +''' | 
|  | 17 | +multi | 
|  | 18 | +line | 
|  | 19 | +''' | 
|  | 20 | +``` | 
|  | 21 | + | 
|  | 22 | +## Terms and Unification | 
|  | 23 | + | 
|  | 24 | +A **term** is either: | 
|  | 25 | + | 
|  | 26 | +* A variable: starts with uppercase (`X`, `Y`, `Var`). | 
|  | 27 | +* A function: a sequence beginning with a lowercase or special symbol, followed by terms (`(f a X)`). | 
|  | 28 | + | 
|  | 29 | +Examples: | 
|  | 30 | + | 
|  | 31 | +```stellogen | 
|  | 32 | +X | 
|  | 33 | +(f X) | 
|  | 34 | +(h a X) | 
|  | 35 | +(add X Y Z) | 
|  | 36 | +``` | 
|  | 37 | + | 
|  | 38 | +**Unification** = finding substitutions that make two terms identical. | 
|  | 39 | + | 
|  | 40 | +```stellogen | 
|  | 41 | +''' | 
|  | 42 | +(f X)  ~  (f (h a))    =>  {X := (h a)} | 
|  | 43 | +(f X)  ~  X            =>  ❌ (circular) | 
|  | 44 | +(f X)  ~  (g X)        =>  ❌ (different heads) | 
|  | 45 | +''' | 
|  | 46 | +``` | 
|  | 47 | + | 
|  | 48 | +**All Stellogen expressions are actually terms.** | 
|  | 49 | + | 
|  | 50 | +--- | 
|  | 51 | + | 
|  | 52 | +## Syntactic sugar | 
|  | 53 | + | 
|  | 54 | +### Omission | 
|  | 55 | + | 
|  | 56 | +A constant can be written without parentheses: `f` instead of `(f)`. | 
|  | 57 | + | 
|  | 58 | +### Cons lists | 
|  | 59 | + | 
|  | 60 | +```stellogen | 
|  | 61 | +[a b c] | 
|  | 62 | +``` | 
|  | 63 | + | 
|  | 64 | +means | 
|  | 65 | + | 
|  | 66 | +```stellogen | 
|  | 67 | +(%cons a (%cons b %nil)) | 
|  | 68 | +``` | 
|  | 69 | + | 
|  | 70 | +The empty list is `[]` (denoting the constant `%nil`). | 
|  | 71 | + | 
|  | 72 | +### Stacks | 
|  | 73 | + | 
|  | 74 | +```stellogen | 
|  | 75 | +<a b c> | 
|  | 76 | +``` | 
|  | 77 | + | 
|  | 78 | +is an interactive application representing | 
|  | 79 | + | 
|  | 80 | +```stellogen | 
|  | 81 | +(a (b c)) | 
|  | 82 | +``` | 
|  | 83 | + | 
|  | 84 | +### Groups | 
|  | 85 | + | 
|  | 86 | +``` | 
|  | 87 | +{ a b c } | 
|  | 88 | +``` | 
|  | 89 | + | 
|  | 90 | +means | 
|  | 91 | + | 
|  | 92 | +``` | 
|  | 93 | +(%group a b c) | 
|  | 94 | +``` | 
|  | 95 | + | 
|  | 96 | +### Special operators | 
|  | 97 | + | 
|  | 98 | +Some special operators are written as prefix of the expression: | 
|  | 99 | + | 
|  | 100 | +```stellogen | 
|  | 101 | +#(f X) | 
|  | 102 | +#[(f X)] | 
|  | 103 | +@(f X) | 
|  | 104 | +@[(f X)] | 
|  | 105 | +``` | 
|  | 106 | + | 
|  | 107 | +### Macros | 
|  | 108 | + | 
|  | 109 | +It is possible to declare aliases for expressions: | 
|  | 110 | + | 
|  | 111 | +```stellogen | 
|  | 112 | +(new-declaration (spec X Y) (:= X Y)) | 
|  | 113 | +``` | 
|  | 114 | + | 
|  | 115 | +after this declaration, `(spec X Y)` stands for `(:= X Y)`. | 
|  | 116 | + | 
|  | 117 | +--- | 
|  | 118 | + | 
|  | 119 | +## Rays | 
|  | 120 | + | 
|  | 121 | +A **ray** is a term with polarity: | 
|  | 122 | + | 
|  | 123 | +* `(+f X)` → positive | 
|  | 124 | +* `(-f X)` → negative | 
|  | 125 | +* `(f X)`  → neutral (does not interact) | 
|  | 126 | + | 
|  | 127 | +Two rays interact if they have opposite polarities **and** their terms unify: | 
|  | 128 | + | 
|  | 129 | +```stellogen | 
|  | 130 | +''' | 
|  | 131 | +(+f X)   ~   (-f (h a))    =>  {X := (h a)} | 
|  | 132 | +(+f X)   ~   (+f a)        =>  ❌ (same polarity) | 
|  | 133 | +''' | 
|  | 134 | +``` | 
|  | 135 | + | 
|  | 136 | +--- | 
|  | 137 | + | 
|  | 138 | +## Stars and Constellations | 
|  | 139 | + | 
|  | 140 | +* A **star** is a cons list of rays: | 
|  | 141 | + | 
|  | 142 | +  ```stellogen | 
|  | 143 | +  [(+f X) (-f (h a)) (+g Y)] | 
|  | 144 | +  ``` | 
|  | 145 | + | 
|  | 146 | +  Empty star: `[]` | 
|  | 147 | + | 
|  | 148 | +* A **constellation** is a group of stars `{ }`: | 
|  | 149 | + | 
|  | 150 | +  ```stellogen | 
|  | 151 | +  { (+f X) (-f X) (+g a) } | 
|  | 152 | +  ``` | 
|  | 153 | + | 
|  | 154 | +  Empty constellation: `{}` | 
|  | 155 | + | 
|  | 156 | +Variables are local to each star. | 
|  | 157 | + | 
|  | 158 | +--- | 
|  | 159 | + | 
|  | 160 | +## Execution by Fusion | 
|  | 161 | + | 
|  | 162 | +Execution = stars interacting through **fusion** (Robinson’s resolution rule). | 
|  | 163 | + | 
|  | 164 | +When rays unify: | 
|  | 165 | + | 
|  | 166 | +* They disappear (consumed). | 
|  | 167 | +* Their substitution applies to the rest of the star. | 
|  | 168 | +* Stars merge. | 
|  | 169 | + | 
|  | 170 | +Example of constellation: | 
|  | 171 | + | 
|  | 172 | +```stellogen | 
|  | 173 | +{ [(+f X) X] [(-f a)] } | 
|  | 174 | +``` | 
|  | 175 | + | 
|  | 176 | +Fusion along two matching rays: `[(+f X) X]` with `[(-f a)]` → `{X := a}` | 
|  | 177 | +Result: `a` | 
|  | 178 | + | 
|  | 179 | +--- | 
|  | 180 | + | 
|  | 181 | +## Focus and Action/State | 
|  | 182 | + | 
|  | 183 | +During execution, we separate stars into *actions* and *states*. | 
|  | 184 | + | 
|  | 185 | +State stars are marked with `@`. | 
|  | 186 | +They are the “targets” for interaction. | 
|  | 187 | + | 
|  | 188 | +```stellogen | 
|  | 189 | +{ [+a b] @[-c d] } | 
|  | 190 | +``` | 
|  | 191 | + | 
|  | 192 | +Execution duplicates actions and fuses them with state stars until no more interactions are possible. | 
|  | 193 | +The result is a new constellation, like the “normal form” of computation. | 
|  | 194 | + | 
|  | 195 | +--- | 
|  | 196 | + | 
|  | 197 | +## Defining Constellations | 
|  | 198 | + | 
|  | 199 | +You can give names to constellations with the `:=` operator: | 
|  | 200 | + | 
|  | 201 | +```stellogen | 
|  | 202 | +(:= a) | 
|  | 203 | +(:= x {[+a] [-a b]}) | 
|  | 204 | +(:= z (-f X)) | 
|  | 205 | +``` | 
|  | 206 | + | 
|  | 207 | +Delimiters can be omitted when it is obvious that a single ray or star is defined. | 
|  | 208 | + | 
|  | 209 | +You can refer to identifiers with `#`: | 
|  | 210 | + | 
|  | 211 | +```stellogen | 
|  | 212 | +(:= y #x) | 
|  | 213 | +(:= union1 { #x #y #z })   ' unions constellations | 
|  | 214 | +``` | 
|  | 215 | + | 
|  | 216 | +Unlike functions, order does not matter. | 
|  | 217 | + | 
|  | 218 | +You can focus all stars of a constellation with `@`: | 
|  | 219 | + | 
|  | 220 | +```stellogen | 
|  | 221 | +(:= f @{ [a] [b] [c] }) | 
|  | 222 | +``` | 
|  | 223 | + | 
|  | 224 | +--- | 
|  | 225 | + | 
|  | 226 | +## Inequality Constraints | 
|  | 227 | + | 
|  | 228 | +Add constraints with `[ some star || (!= X1 Y1) ... (!= Xn Yn)]`: | 
|  | 229 | + | 
|  | 230 | +```stellogen | 
|  | 231 | +(:= ineq { | 
|  | 232 | +  [(+f a)] | 
|  | 233 | +  [(+f b)] | 
|  | 234 | +  @[(-f X) (-f Y) (r X Y) || (!= X Y)]}) | 
|  | 235 | +``` | 
|  | 236 | + | 
|  | 237 | +where several equality constraints can be chained after `||`. | 
|  | 238 | + | 
|  | 239 | +This prevents `X` and `Y` from unifying to the same concrete value. | 
|  | 240 | + | 
|  | 241 | +--- | 
|  | 242 | + | 
|  | 243 | +## Pre-execution | 
|  | 244 | + | 
|  | 245 | +You can precompute expressions: | 
|  | 246 | + | 
|  | 247 | +```stellogen | 
|  | 248 | +(:= x [(+f X) X]) | 
|  | 249 | +(:= y (-f a)) | 
|  | 250 | +(:= ex (interact @#x #y)) ' normal execution | 
|  | 251 | +(:= ex (fire @#x #y))     ' actions are used exactly once | 
|  | 252 | +``` | 
|  | 253 | + | 
|  | 254 | +This evaluates and stores the resulting constellation. | 
|  | 255 | + | 
|  | 256 | +--- | 
|  | 257 | + | 
|  | 258 | +## Let's write a program | 
|  | 259 | + | 
|  | 260 | +A program consists in a series of commands. | 
|  | 261 | + | 
|  | 262 | +### Commands | 
|  | 263 | + | 
|  | 264 | +* **Show without execution**: | 
|  | 265 | + | 
|  | 266 | +  ```stellogen | 
|  | 267 | +  (show { [+a] [-a b] }) | 
|  | 268 | +  ``` | 
|  | 269 | + | 
|  | 270 | +* **Show with execution**: | 
|  | 271 | + | 
|  | 272 | +  ```stellogen | 
|  | 273 | +  <show interact { [+a] [-a b] }> | 
|  | 274 | +  ``` | 
|  | 275 | + | 
|  | 276 | +### Example | 
|  | 277 | + | 
|  | 278 | +```stellogen | 
|  | 279 | +(:= add { | 
|  | 280 | +  [(+add 0 Y Y)] | 
|  | 281 | +  [(-add X Y Z) (+add (s X) Y (s Z))]}) | 
|  | 282 | +
 | 
|  | 283 | +' 2 + 2 = R | 
|  | 284 | +(:= query [(-add <s s 0> <s s 0> R) R]) | 
|  | 285 | +
 | 
|  | 286 | +(show (interact #add @#query)) | 
|  | 287 | +``` | 
|  | 288 | + | 
|  | 289 | +--- | 
|  | 290 | + | 
|  | 291 | +## Logic Programming | 
|  | 292 | + | 
|  | 293 | +Constellations can act like logic programs (à la Prolog). | 
|  | 294 | + | 
|  | 295 | +### Facts | 
|  | 296 | + | 
|  | 297 | +```stellogen | 
|  | 298 | +(+childOf a b) | 
|  | 299 | +(+childOf a c) | 
|  | 300 | +(+childOf c d) | 
|  | 301 | +``` | 
|  | 302 | + | 
|  | 303 | +### Rule | 
|  | 304 | + | 
|  | 305 | +```stellogen | 
|  | 306 | +{ (-childOf X Y) (-childOf Y Z) (+grandParentOf Z X) } | 
|  | 307 | +``` | 
|  | 308 | + | 
|  | 309 | +### Query | 
|  | 310 | + | 
|  | 311 | +```stellogen | 
|  | 312 | +[(-childOf X b) (res X)] | 
|  | 313 | +``` | 
|  | 314 | + | 
|  | 315 | +### Putting it together | 
|  | 316 | + | 
|  | 317 | +```stellogen | 
|  | 318 | +(:= knowledge { | 
|  | 319 | +  [(+childOf a b)] | 
|  | 320 | +  [(+childOf a c)] | 
|  | 321 | +  [(+childOf c d)] | 
|  | 322 | +  [(-childOf X Y) (-childOf Y Z) (+grandParentOf Z X)] | 
|  | 323 | +}) | 
|  | 324 | +
 | 
|  | 325 | +(:= query [(-childOf X b) (res X)]) | 
|  | 326 | +<show interact { #knowledge @#query }> | 
|  | 327 | +``` | 
|  | 328 | + | 
|  | 329 | +This asks: *Who are the children of `b`?* | 
|  | 330 | + | 
|  | 331 | +--- | 
|  | 332 | + | 
|  | 333 | +## Expect assertion | 
|  | 334 | + | 
|  | 335 | +``` | 
|  | 336 | +(== x y) | 
|  | 337 | +``` | 
|  | 338 | + | 
|  | 339 | +does nothing if `x` and `y` are equal or fails with an error when they are different. | 
|  | 340 | + | 
|  | 341 | +--- | 
|  | 342 | + | 
|  | 343 | +## Processes | 
|  | 344 | + | 
|  | 345 | +A **process** chains constellations step by step: | 
|  | 346 | + | 
|  | 347 | +```stellogen | 
|  | 348 | +(:= c (process | 
|  | 349 | +  (+n0 0)                 'base constellation | 
|  | 350 | +  [(-n0 X) (+n1 (s X))]   'interacts with previous | 
|  | 351 | +  [(-n1 X) (+n2 (s X))])) 'interacts with previous | 
|  | 352 | +(show #c) | 
|  | 353 | +``` | 
|  | 354 | + | 
|  | 355 | +It’s similar to tactics in proof assistants (Rocq) or imperative programs that update state. | 
|  | 356 | + | 
|  | 357 | +--- | 
|  | 358 | + | 
|  | 359 | +## Types as Sets of Tests | 
|  | 360 | + | 
|  | 361 | +In Stellogen, **types are sets of tests** that a constellation must pass to be of that type. | 
|  | 362 | + | 
|  | 363 | +For example, we define a type for natural numbers: | 
|  | 364 | + | 
|  | 365 | +```stellogen | 
|  | 366 | +(new-declaration (spec X Y) (:= X Y)) | 
|  | 367 | +(spec nat { | 
|  | 368 | +  [(-nat 0) ok]              ' test 1 | 
|  | 369 | +  [(-nat (s N)) (+nat N)]})  ' test 2 | 
|  | 370 | +``` | 
|  | 371 | + | 
|  | 372 | +A constellation must pass **all tests** to be considered of type `nat`. | 
|  | 373 | + | 
|  | 374 | +We then define the behavior of type assertions with a macro: | 
|  | 375 | + | 
|  | 376 | +```stellogen | 
|  | 377 | +(new-declaration (:: Tested Test) | 
|  | 378 | +  (== @(interact @#Tested #Test) ok)) | 
|  | 379 | +``` | 
|  | 380 | + | 
|  | 381 | +It says that a `Tested` is of type `Test` when their interaction with focus on `Tested` is equal to `ok`. | 
|  | 382 | + | 
|  | 383 | +A constellation can have one or several types: | 
|  | 384 | + | 
|  | 385 | +```stellogen | 
|  | 386 | +(:: 2 nat) | 
|  | 387 | +(:: 2 otherType) | 
|  | 388 | +(:: 2 otherType2) | 
|  | 389 | +``` | 
0 commit comments