Skip to content

Commit c0c4831

Browse files
committed
Add basics of stellogen
1 parent 4958b56 commit c0c4831

File tree

1 file changed

+387
-0
lines changed

1 file changed

+387
-0
lines changed

docs/basics.md

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

0 commit comments

Comments
 (0)