InputLayer Syntax Cheatsheet

A unified syntax for InputLayer, designed for intuitive data manipulation and querying.

Quick Reference

OperatorMeaningPersistedDD Semantics
+Insert fact or persistent ruleYesdiff = +1
-Delete fact or drop ruleYesdiff = -1
<- (no +)Session rule (transient)NoAd-hoc computation
?QueryNoAd-hoc query

Key Terminology

TermDescription
FactBase data stored in a relation (e.g., +edge(1, 2))
RuleDerived relation defined by a rule (persistent)
Session RuleTransient rule that exists only for current session
SchemaType definition for a relation's columns
QueryOne-shot question against facts and rules
Knowledge GraphIsolated namespace containing relations, rules, and indexes

Meta Commands

Meta commands start with . and control the system:

.kg                  Show current knowledge graph
.kg list             List all knowledge graphs
.kg create <name>    Create knowledge graph
.kg use <name>       Switch to knowledge graph
.kg drop <name>      Drop knowledge graph (cannot drop current)

.rel                 List relations (base facts)
.rel <name>          Describe relation schema
.rel drop <name>     Drop a relation and its data

.rule                List persistent rules
.rule <name>         Query rule (show computed data)
.rule def <name>     Show rule definition
.rule drop <name>    Drop all clauses of a rule
.rule remove <name> <n>  Remove clause #n from rule (1-based)
.rule clear <name>   Clear all clauses for re-registration

.session             List session rules
.session clear       Clear all session rules
.session drop <n>    Remove session rule #n

.index               List all indexes
.index list          List all indexes (explicit)
.index create <name> on <relation>(<column>) [options]
.index drop <name>   Drop an index
.index stats <name>  Show index statistics
.index rebuild <name>  Rebuild an index

.load <file>         Load and execute a .idl file

.user list           List all users
.user create <name> <password> <role>  Create user
.user drop <name>    Delete user
.user password <name> <password>       Change password
.user role <name> <role>               Change role

.apikey create <label>   Create API key
.apikey list             List API keys
.apikey revoke <label>   Revoke API key

.kg acl list [<kg>]              List ACLs
.kg acl grant <kg> <user> <role> Grant access
.kg acl revoke <kg> <user>       Revoke access

.explain <query>     Show query plan without executing
.compact             Compact WAL and consolidate batch files
.status              Show system status
.help                Show this help
.quit                Exit client

Index Creation Options

.index create vec_idx on docs(embedding) type hnsw metric cosine m 16 ef_construction 200

Options: type <hnsw>, metric <cosine|euclidean|dot_product|manhattan>, m <N>, ef_construction <N>, ef_search <N>

.idx is an alias for .index.

Data Manipulation

Insert Facts (+)

Single fact:

+edge(1, 2)

Bulk insert:

+edge[(1, 2), (2, 3), (3, 4)]

Delete Facts (-)

Single fact:

-edge(1, 2)

Conditional delete (query-based):

-edge(X, Y) <- edge(X, Y), X > 5

Updates (Delete then Insert)

To update data, delete the old value then insert the new:

// Delete old value
-counter(1, 0)
// Insert new value
+counter(1, 5)

Persistent Rules (+head <- body)

Persistent rules are saved to disk and incrementally maintained by Differential Dataflow.

Simple rule:

+path(X, Y) <- edge(X, Y)

Recursive rule (transitive closure):

+path(X, Y) <- edge(X, Y)
+path(X, Z) <- path(X, Y), edge(Y, Z)

Rule with filter:

+adult(Name, Age) <- person(Name, Age), Age >= 18

Rule with computed head variable:

+doubled(X, Y) <- nums(X), Y = X * 2

Rules are saved to {kg_dir}/rules/catalog.json and automatically loaded on knowledge graph startup.

Session Rules (<-)

Session rules are executed immediately but not persisted. They're useful for ad-hoc analysis:

result(X, Y) <- edge(X, Y), X < Y

Session rules can reference persistent rules:

reachable_from_one(X) <- path(1, X)

Multiple session rules accumulate and evaluate together:

foo(X, Y) <- bar(X, Y)
foo(X, Z) <- foo(X, Y), foo(Y, Z)  // Adds to previous rule

Queries (?)

Query a relation or rule:

Simple query:

? edge(1, X)

Query with constraints:

? person(Name, Age), Age > 30

Query a derived relation:

? path(1, X)

Schema Declarations

Define typed relations:

+employee(id: int, name: string, dept_id: int)
+user(id: int, email: string, name: string)

Aggregations

+total_sales(Dept, sum<Amount>) <- sales(Dept, _, Amount)
+employee_count(Dept, count<Id>) <- employee(Id, _, Dept)
+max_salary(Dept, max<Salary>) <- employee(_, Salary, Dept)
+min_age(min<Age>) <- person(_, Age)
+avg_score(avg<Score>) <- test_results(_, Score)

Supported aggregates: count, sum, min, max, avg, count_distinct, top_k, top_k_threshold.

TopK Example

+top_scores(Name, top_k<3, Score, desc>) <- scores(Name, Score)

Builtin Functions

Distance Functions

Dist = euclidean(V1, V2)    // Euclidean (L2) distance
Dist = cosine(V1, V2)       // Cosine distance (1 - similarity)
Score = dot(V1, V2)         // Dot product
Dist = manhattan(V1, V2)    // Manhattan (L1) distance

Vector Operations

NormV = normalize(V)        // Unit vector
Dim = vec_dim(V)            // Vector dimension
Sum = vec_add(V1, V2)       // Element-wise addition
Scaled = vec_scale(V, S)    // Scalar multiplication

Math Functions

A = abs(X)                  // Absolute value
R = sqrt(X)                 // Square root
R = pow(Base, Exp)          // Power
R = log(X)                  // Natural logarithm
R = exp(X)                  // Exponential (e^x)
R = sin(X)                  // Sine (radians)
R = cos(X)                  // Cosine (radians)
R = tan(X)                  // Tangent (radians)
R = floor(X)                // Floor
R = ceil(X)                 // Ceiling
S = sign(X)                 // Sign (-1, 0, 1)

String Functions

L = len(S)                  // String length
U = upper(S)                // To uppercase
L = lower(S)                // To lowercase
T = trim(S)                 // Trim whitespace
Sub = substr(S, Start, Len) // Substring
R = replace(S, Find, Repl)  // Replace all
R = concat(S1, S2)          // Concatenate

Temporal Functions

Now = time_now()            // Current Unix timestamp (ms)
Diff = time_diff(T1, T2)   // Timestamp difference
New = time_add(Ts, Dur)     // Add duration
New = time_sub(Ts, Dur)     // Subtract duration
W = time_decay(Ts, Now, HL) // Exponential decay

Scalar Min/Max

M = min_val(A, B)           // Smaller of two values
M = max_val(A, B)           // Larger of two values

See functions for the complete reference (55 functions).

Vector Operations Example

// Insert vectors
+vectors[(1, [1.0, 0.0, 0.0]), (2, [0.0, 1.0, 0.0])]

// Query with distance computation
? vectors(Id1, V1), vectors(Id2, V2), Id1 < Id2,
   Dist = euclidean(V1, V2), Dist < 1.0

// Persistent rule with vector computation
+similarity(Id1, Id2, Score) <-
    vectors(Id1, V1), vectors(Id2, V2),
    Id1 < Id2,
    Score = cosine(V1, V2)

Examples

Social Graph

// Create knowledge graph
.kg create social
.kg use social

// Add edges
+follows[(1, 2), (2, 3), (3, 4), (1, 4)]

// Define reachability rule (persistent)
+reach(X, Y) <- follows(X, Y)
+reach(X, Z) <- reach(X, Y), follows(Y, Z)

// Query who user 1 can reach
? reach(1, X)

Access Control (RBAC)

.kg create acl
.kg use acl

// Facts: users, roles, permissions
+user_role[("alice", "admin"), ("bob", "viewer")]
+role_permission[("admin", "read"), ("admin", "write"), ("viewer", "read")]

// Rule: user has permission if they have a role with that permission
+has_permission(User, Perm) <-
  user_role(User, Role),
  role_permission(Role, Perm)

// Query: what can alice do?
? has_permission("alice", Perm)

Policy-First RAG

.kg create rag
.kg use rag

// Facts
+member[("alice", "engineering"), ("bob", "sales")]
+doc[(101, "Design Doc"), (102, "Sales Pitch")]
+acl[("engineering", 101), ("sales", 102)]
+emb[(101, [1.0, 0.0]), (102, [0.0, 1.0])]

// Rule: user can access docs via group membership
+can_access(User, DocId) <- member(User, Group), acl(Group, DocId)

// Query: what can alice retrieve, with similarity score?
? can_access("alice", DocId), emb(DocId, V),
   Sim = cosine(V, [0.9, 0.1]), Sim > 0.5

Differential Dataflow Semantics

InputLayer is built on Differential Dataflow (DD), which uses a diff-based model:

  • +fact sends (fact, time, +1) to DD
  • -fact sends (fact, time, -1) to DD
  • Rules are incrementally maintained using DD's iterate() operator
  • Queries are executed using DD's dataflow operators

The persistence layer stores (data, time, diff) triples, enabling:

  • Efficient incremental updates
  • Crash recovery with WAL (Write-Ahead Log)

Architecture

Statement Parser     ->  Statement enum (facts, rules, queries)
       |
Storage Engine       ->  Multi-knowledge-graph management
       |
Rule Catalog         ->  Persistent rule definitions (JSON)
       |
Query Engine       ->  DD-based execution
       |
Persist Layer        ->  WAL + batched Parquet storage

See architecture for the complete architecture reference.

File Locations

  • Config: ./config.toml or --config <path>
  • Data: {data_dir}/{knowledge_graph}/
  • Rules: {data_dir}/{knowledge_graph}/rules/catalog.json
  • Persist: {data_dir}/persist/{knowledge_graph}:{relation}/