Logica Imperatives
Logica imperatives are special directives that start with @ and provide instructions to the Logica engine. They control how the program is processed, executed, or how results are presented.
| Imperative | Description | Arguments |
|---|---|---|
@Engine(engine) | Specifies which SQL engine to use for query execution | engine: String with engine name ("sqlite", "bigquery", "postgres", "duckdb") |
@Ground(predicate, table) | Instructs Logica to save a predicate to the database | predicate: Predicate name to be savedtable: (Optional) String with target table name. By default saves to logica_test.Predicate in BigQuery and SQLite, or logica_home.Predicate in DuckDB and PostgreSQL |
@Limit(predicate, limit) | Instructs Logica to limit the number of rows in the predicate to limit | predicate: Name of the predicatelimit: Integer limit |
@OrderBy(predicate, column1, column2, ...) | Specifies the sort order for a predicate's results | predicate: Predicate namecolumn1, column2, ...: Strings with column names and optional sort direction ("DESC") |
@Recursive(predicate, iterations, stop, satellites) | Controls recursion properties for recursive predicates | predicate: Predicate nameiterations: Integer number of iterationsstop: (Optional) Predicate that stops recursion when it has rowssatellites: (Optional) List of predicates to iterate along |
@AttachDatabase(alias, path) | Connects to a database file (primarily for SQLite) | alias: String with database alias namepath: String with path to database file |
Examples
@Engine
@Engine("sqlite"); # Use SQLite engine for this program.
# The rest of the program uses the specified engine.
Edge("a", "b");
Edge("b", "c");
Path(x, y) distinct :- Edge(x, y) | (Edge(x, z), Path(z, y));@Ground
@Engine("sqlite");
@Ground(MyPredicate); # Save MyPredicate to default table.
# In BigQuery/SQLite: saved to logica_test.MyPredicate.
# In PostgreSQL/DuckDB: saved to logica_home.MyPredicate.
# Define the predicate.
MyPredicate(user:, score:) :-
UserActivity(user:, actions:),
score = Sum{action.cost :- action in actions};
# Using a custom table name.
@Ground(TopUsers, "analytics.high_value_users");
TopUsers(user:) :- MyPredicate(user:, score:), score > 100;@OrderBy
@OrderBy(ExpensiveItems, "price DESC"); # Sort ExpensiveItems by price in descending order.
ExpensiveItems(name:, price:) :- Product(name:, price:), price > 100;
# Multiple OrderBy directives can be used for different predicates.
@OrderBy(NewCustomers, "signup_date DESC");
NewCustomers(id:, name:, signup_date:) :- Customer(id:, name:, signup_date:),
signup_date > "2023-01-01";
# Sort by multiple columns with mixed directions.
@OrderBy(SalesReport, "region", "total_sales DESC", "product_name");
SalesReport(region:, product_name:, total_sales:) :-
Sales(region:, product_name:, sales:),
total_sales = Sum{amount :- sale in sales, amount = sale.amount};@Recursive
# Define a graph with edges.
Edge("a", "b");
Edge("b", "c");
Edge("c", "d");
# Compute transitive closure with 10 iterations.
@Recursive(Path, 10);
Path(x, y) distinct :- Edge(x, y);
Path(x, y) distinct :- Path(x, z), Edge(z, y);
# Using a stop condition.
@Recursive(ShortPath, 20, stop: ReachedTarget);
ShortPath(node) Min= distance :- node = "start", distance = 0;
ShortPath(node) Min= distance + 1 :- ShortPath(prev, distance), Edge(prev, node);
ReachedTarget() :- ShortPath("target");@AttachDatabase
@AttachDatabase("db", "some_db_file.db"); # Connect to some_db_file.db as db.
# Querying the database.
Person(name:) :- db.Engineer(name:) | db.Analyst(name:);