2026-03-11 10:24:56 +01:00

8.6 KiB

Geolog DSL Structure

This directory contains example .geolog files that use a richer DSL than the minimal .chase script language in examples/scripts/.

This README summarizes the Geolog DSL structure as it appears in the examples in this directory. It should be read as a practical, example-driven reference, not as a formal or complete language specification.

At a Glance

  • Top-level declarations are theory and instance.
  • The main kind of type is Sort.
  • Symbols can denote sorts, constants, functions, predicates, or nested instances.
  • Axioms use sequent-style syntax: premise |- conclusion.
  • Instance bodies can be plain literals (= { ... }) or chase blocks (= chase { ... }).
  • Function application is postfix, and qualified names use /.

Informal File Shape

file := { comment | theory_decl | instance_decl }

comment := // ...

theory_decl :=
  theory theory_params? Name {
    theory_item*
  }

instance_decl :=
  instance Name : theory_app = {
    instance_item*
  }

  | instance Name : theory_app = chase {
      instance_item*
    }

In practice, a file is usually a sequence of theory declarations followed by one or more example instances.

Top-Level Declarations

theory

A theory introduces sorts, symbols, and axioms.

theory Graph {
  V : Sort;
  Edge : [src: V, tgt: V] -> Prop;
}

Theories may also be parameterized.

theory (X : Sort) (Y : Sort) Iso {
  fwd : X -> Y;
  bwd : Y -> X;
}

theory (N : PetriNet instance) Marking {
  token : Sort;
  token/of : token -> N/P;
}

Observed parameter forms:

  • sort parameters: (X : Sort)
  • instance parameters: (N : PetriNet instance)
  • dependent instance parameters: (RP : N ReachabilityProblem instance)

instance

An instance provides concrete elements and assignments for a theory.

instance Triangle : Graph = {
  A : V;
  B : V;
  C : V;
}

Instances may target parameterized theories by writing the arguments before the theory name.

instance MyMap : MyBase Map = { ... }
instance solution0 : ExampleNet problem0 Solution = { ... }
instance AB_Iso : As/a Bs/b Iso = { ... }

Theory Body Items

The examples show the following declaration forms inside a theory body.

Sort declarations

V : Sort;
E : Sort;

This introduces carrier sorts.

Constants or distinguished elements

elem : X;

This introduces a named element of an existing sort.

Functions

src : E -> V;
fwd : X -> Y;
token/of : token -> N/P;

Names may contain /, which is used heavily for structured or qualified names.

Predicates and relations

Unary predicates:

completed : Item -> Prop;

Record-shaped predicates:

Edge : [src: V, tgt: V] -> Prop;
depends : [item: Item, on: Item] -> Prop;

Product-valued functions

Functions may return record-shaped values.

pair_of : A -> [left: B, right: C];
W/src : W -> [firing: F, arc: N/out];

Nested instance slots

Theories can contain fields whose values are themselves instances.

initial_marking : N Marking instance;
trace : N Trace instance;
initial_iso : (trace/input_terminal) (RP/initial_marking/token) Iso instance;

Axioms

Axioms use a sequent-like form.

ax/trans : forall x, y, z : V.
  [src: x, tgt: y] Path, [src: y, tgt: z] Path |- [src: x, tgt: z] Path;

An axiom declaration has the observed structure:

name : forall binders. premise |- conclusion;

Formula and Term Syntax

The examples use the following building blocks inside axioms and assignments.

Quantifiers

Universal binders appear after forall.

forall x : X, y : Y.

Existentials appear directly inside conclusions or disjuncts.

exists r : R. r R/data = [x: a, y: b]
exists w : W. w W/src_firing = f, w W/src_arc = arc

Sequents

The central connective is |-, separating premise from conclusion.

premise1, premise2 |- conclusion1, conclusion2;

In the examples:

  • commas act as conjunctions
  • the left side is the premise
  • the right side is the conclusion

Equality

Equality is used for ordinary values and compound values.

ab src = A
r R/data = [x: a, y: b]
x fwd bwd = x

Truth constants

|- true;
|- false;

Disjunction

Disjunction is written as \/.

[item: x, on: y] depends |- x blocked \/ y completed;

Predicate atoms

Unary predicate atoms:

x blocked
y completed

Record-shaped predicate atoms:

[src: x, tgt: y] Edge
[a: x, f: i] id

Postfix application

Function application is postfix and can be chained.

e src
x id
x fwd bwd
w W/src_arc N/out/tgt

This is one of the most distinctive traits of the DSL.

Qualified paths

The slash / is used for qualification and nested access.

Observed examples include:

R/data
N/P
N/out/src
trace/input_terminal
RP/initial_marking/token
ExampleNet/A

Record literals

Records are written with brackets and named fields.

[x: a, y: b]
[firing: f, arc: arc]

The examples also show positional shorthand for record arguments when the field order is known:

[e, e] mul = e;
[cook_dinner, on: buy_groceries] depends;

Field projection

Record-valued terms support field projection.

r R/data .x = a

Instance Body Items

The examples show the following forms inside instance bodies.

Element declarations

a : V;
tok : token;
ab : T;

Function assignments

ab src = A;
tok token/of = ExampleNet/A;
a1 map = MyBase/b1;

Predicate facts

Unary facts:

buy_groceries completed;

Record-shaped facts:

[src: a, tgt: b] Edge;
[item: x, on: y] depends;

Product-valued assignments

a1 pair_of = [left: b1, right: c1];
ot output_terminal/src = [firing: f1, arc: SimpleNet/arc_out];

Nested instance literals

Instance-valued fields can be assigned inline blocks.

initial_marking = {
  tok : token;
  tok token/of = ExampleNet/A;
};

= { ... } vs = chase { ... }

The examples consistently use two instance forms.

Plain instance

instance Triangle : Graph = {
  ...
}

This gives a direct structure with only the explicitly listed elements and assignments.

Chase instance

instance Chain : Graph = chase {
  ...
}

This marks an instance whose contents should be extended by the theory axioms. Examples use this for transitive closure, existential witness generation, and trace/reachability constructions.

Observed Design Patterns

Parameterized theories

Theories can be abstract over:

  • a sort, such as theory (X : Sort) Container
  • an instance, such as theory (N : PetriNet instance) Marking
  • multiple arguments, such as theory (N : PetriNet instance) (RP : N ReachabilityProblem instance) Solution

Theory application by adjacency

Theory arguments are written before the theory name.

N Marking instance
MyBase Map
ExampleNet problem0 Solution

Nested structure via qualified names

Many examples model dependent structure by naming into earlier declarations.

token/of : token -> N/P;
initial_iso : (trace/input_terminal) (RP/initial_marking/token) Iso instance;

What Seems Outside the File DSL

Some example comments refer to interactive commands such as:

:source
:load
:inspect
:chase
:solve

Those commands appear to belong to an external REPL or tool environment rather than to the .geolog file grammar itself.

Best Example Files by Feature

  • transitive_closure.geolog: basic theory, axiom, and = chase usage
  • graph.geolog: plain structural instances
  • monoid.geolog: postfix application and positional record syntax
  • todo_list.geolog: unary predicates and disjunction
  • sort_param_simple.geolog: sort and instance parameters
  • nested_instance_test.geolog: nested instance-valued fields
  • product_codomain_test.geolog: record-valued function codomains
  • field_projection_test.geolog: field projection syntax
  • record_existential_test.geolog: existential witness creation with records
  • petri_net_showcase.geolog: large multi-theory composition
  • solver_demo.geolog: satisfiability-oriented axiom patterns

Minimal Example

theory Graph {
  V : Sort;
  Edge : [src: V, tgt: V] -> Prop;
  Path : [src: V, tgt: V] -> Prop;

  ax/base : forall x, y : V.
    [src: x, tgt: y] Edge |- [src: x, tgt: y] Path;
}

instance Chain : Graph = chase {
  a : V;
  b : V;
  [src: a, tgt: b] Edge;
}

That small example already shows the core structure of the DSL:

  • a theory
  • sort and predicate declarations
  • an axiom written as a sequent
  • an instance
  • a chase block that asks for closure under the theory axioms