aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.org255
-rw-r--r--config/vm.args2
-rw-r--r--docs/reliability_roadmap.org223
-rw-r--r--flake.nix6
-rw-r--r--rebar.config4
-rw-r--r--src/constraint.erl75
-rw-r--r--src/operations.erl2
-rw-r--r--src/repl.erl10
-rw-r--r--src/xml_server_app.erl6
9 files changed, 411 insertions, 172 deletions
diff --git a/README.org b/README.org
index 2cfebe7..cf42f5c 100644
--- a/README.org
+++ b/README.org
@@ -1,122 +1,139 @@
-#+TITLE: Domino
+#+TITLE: Sakura
* About
-Domino is an *Extended Relational Database Engine* based on E. F. Codd's
-RM/T (Relational Model/Tasmania, 1979). It implements relational algebra
-in its strict, theoretical form while extending it to capture more of the
-meaning of data through semantic modeling concepts.
-
-** Theoretical Foundation
-
-The engine builds upon two seminal works by E. F. Codd:
-
-1. *"A Relational Model of Data for Large Shared Data Banks"* (1970) —
- The foundation of relational theory
-2. *"Extending the Database Relational Model to Capture More Meaning"* (1979) —
- RM/T extensions for semantic modeling
-
-** Core Principles
-
-A relation is modeled as a set of tuples, each tuple being a set of
-attributes. Each attribute is a pairing of a name with a value drawn
-from a domain. All operations are defined on entire relations as sets,
-with no recourse to the compromises typical of SQL or other practical
-implementations.
-
-** What Makes Domino Extended?
-
-*** Content-Addressed Storage
-Entities are identified by system-controlled *surrogates* — cryptographic
-hashes (SHA-256) that provide permanent, unique identification. This
-enables:
-- Automatic deduplication
-- Immutable versioning
-- Merkle tree-based diffing
-- Distributed synchronization
-
-*** Entity Types (RM/T)
-Three fundamental entity classifications:
-- *Kernel Entities* — Independent entities (e.g., Employee, Supplier)
-- *Characteristic Entities* — Multi-valued properties (e.g., Job History)
-- *Associative Entities* — Relationships as first-class entities
-
-*** Four Dimensions of Molecular Semantics
-1. *Cartesian Aggregation* — Properties, characteristics, and associations
-2. *Generalization* — Subtyping and inheritance hierarchies
-3. *Cover Aggregation* — Collections and groupings (e.g., teams, convoys)
-4. *Event Precedence* — Temporal ordering of events
-
-*** Immutable Architecture
-All data structures are immutable. Every modification creates a new version
-with a new hash, enabling:
-- Temporal queries
-- Audit trails
-- Safe concurrent access
-- Version control for data
-
-** Current Implementation
-
-*** What's Built
-- Content-addressed storage with SHA-256 surrogates
-- E-relations for entity type management
-- P-relations for immediate properties
-- Merkle tree integration for efficient versioning
-- Volcano iterator model for lazy evaluation
-- Transactional ACID operations via Mnesia
-- Comprehensive EUnit test suite
-
-*** What's Planned
-- Full relational algebra operators (σ, π, ⋈, ∪, ∩, −)
-- Characteristic entities and CG-relation
-- Associative entities and AG-relation
-- Generalization hierarchies (UGI/AGI)
-- Cover aggregation (KG-relation)
-- Event precedence (US/AS/UP/AP)
-- Extended operators (OUTER JOIN, MAYBE operators)
-- RM/T catalog relations
-- Null value handling (three-valued logic)
-- Infinite relations (aleph₀)
-- High-level query language
-
-** Design Philosophy
-
-The engine is intended as a study in correctness and semantic richness:
-each operation is executed in a manner consistent with the classical
-definition of relational algebra, while the RM/T extensions provide a
-framework for capturing more meaning about entities, their properties,
-and their relationships.
-
-It is a platform for exploring the consequences of relational theory in
-a low-level programming context, providing both a tool for experimentation
-and a concrete realization of Codd's vision for semantic data modeling.
-
-** Why RM/T?
-
-Most database systems today are compromises — they sacrifice theoretical
-purity for practical performance. Domino takes a different approach:
-implement the theory *correctly* first, then optimize. RM/T provides:
-
-- *Atomic Semantics* — What constitutes a minimal meaningful unit?
-- *Molecular Semantics* — What larger clusters constitute meaningful units?
-- *Systematic Design* — Principled approach to database schema design
-- *Intelligent Behavior* — System understands more about data meaning
-
-** Documentation
-
-See =docs/= directory:
-- =code.org= — Comprehensive code documentation
-- =features.org= — Feature roadmap and RM/T extensions
-- =ci.org= — Continuous integration setup
-
-** References
-
-- Codd, E. F. (1970). "A Relational Model of Data for Large Shared Data Banks."
- /Communications of the ACM/ 13(6): 377-387.
-- Codd, E. F. (1979). "Extending the Database Relational Model to Capture More Meaning."
- /ACM Transactions on Database Systems/ 4(4): 397-434.
-- Date, C. J. & Darwen, H. "Foundation for Future Database Systems: The Third Manifesto."
-
-** License
-
-See LICENSE file.
+Sakura is a semantic-relational algebra engine inspired by
+E. F. Codd's RM/T and D. McGoveran's (as understood by Fabian Pascal)
+SRDM. It models relations in both intension and extension, providing
+their manipulation as first-class elements of an algebra.
+
+* Motivation
+
+We believe the relational model was not ever fully implemented. The
+fundamental necessity of expressing intent and binding meaning
+enclosed to a conceptual model in data is seldom achieved by any
+self-claimed relational database vendor. The emergence of different
+physically concerned paradigms in the industry demonstrate not only a
+large scale amnesia about fundamentals, but also a lethal
+manifestation of problems that should not exist otherwise. The
+relational data model as an applied theory is an universally rich and
+concrete approach to reality that bases itself greatly in
+moderate-realism applied to mathematics, as described in =An
+Aristotelian Realist Philosophy of Mathematics: Mathematics as the
+Science of Quantity and Structure= by J. Franklin. We believe that
+unleashing the full potential of the relational model as refined over
+the years despite overwhelming disregard of the industry as a whole,
+will promote efficiency to a new scale never seen, that was very much
+so cut short by relational pretenders and theoretically unsound
+approaches. Our goal is to eliminate the application-database
+distinction, while maintaining a clear separation between a first
+order predicate logic algebra engine and a higher order predicate
+logic decision engine (application) via an embedded data sublanguage
+with Sakura as a possible auxiliary runtime.
+
+* Current State
+
+** What Works Today
+
+- Base finite relations: create, insert, retract, clear
+- Built-in immutable/generated domains on database creation:
+ =integer=, =natural=, =rational=, =string=, =atom=, =term=
+- Query DSL in =query_planner= and =repl=:
+ - base relation scan (using relation atom)
+ - =select=, =project=, =join=, =theta_join=, =sort=, =take=, =rename=
+ - =materialize= (plan-level, with caveats)
+- Volcano-style iterator execution model (process-per-operator)
+- Visual output modes in =visualizer= (table/tree/nested views)
+- XML TCP server protocol commands: =QUERY=, =NEXT=, =CLOSE=
+
+** Known Gaps / Reliability Risks
+
+- Lack of constraints greater than 1OPs;
+- =repl:start/0= is destructive: it calls =main:setup/0=, which recreates schema;
+- =xml_server= =SCHEMA= path is currently fragile with constraints representation;
+- Constraint/intension representation is not yet fully normalized across modules;
+- Planner contains dual compilation styles (iterator path + relation path);
+- Blocking operators (for example =sort=) over infinite relations can time out unless bounded with =take= first;
+- There is currently no substantial automated test suite in-repo despite CI hooks;
+
+See =docs/reliability_roadmap.org= for the detailed remediation plan.
+
+* Architecture (High Level)
+
+- =src/operations.erl= :: core storage/versioning and iterator primitives
+- =src/constraint.erl= :: domain constraints, inference, validation
+- =src/generators.erl= :: infinite relation generators
+- =src/relational_operators.erl= :: pure relation-to-relation algebra operators
+- =src/query_planner.erl= :: tuple DSL parsing/validation/execution planning
+- =src/repl.erl= :: shell-facing query convenience API
+- =src/xml_server.erl= :: TCP/XML query interface
+- =src/visualizer.erl= :: renderers for result tuples
+
+Data model records are defined in =include/operations.hrl=.
+
+* Query DSL
+
+Plans are Erlang tuples:
+
+- base relation: =employees=
+- selection: ={select, employees, fun(T) -> maps:get(age, T) > 30 end}=
+- projection: ={project, employees, [name, age]}=
+- equijoin: ={join, employees, departments, dept_id}=
+- theta join: ={theta_join, Left, Right, Pred2}=
+- sort: ={sort, Plan, Comparator2}=
+- take: ={take, Plan, N}=
+- rename: ={rename, old_attr, new_attr, Plan}=
+
+* Running
+
+** Compile
+
+#+begin_src sh
+rebar3 compile
+#+end_src
+
+** REPL
+
+#+begin_src erlang
+repl:start().
+DB = repl:example_db().
+repl:q(DB, employees).
+repl:q(DB, {take, {sort, employees,
+ fun(A,B) -> maps:get(age,A) =< maps:get(age,B) end}, 3}).
+#+end_src
+
+** XML Server (manual)
+
+Start server from Erlang shell, then send line commands over TCP:
+
+- =QUERY <plan>=
+- =NEXT <session_id> <n>=
+- =CLOSE <session_id>=
+
+* Design Intent
+
+Sakura aims to treat relations as algebraic manipulation units with both:
+
+- extension (actual tuples, finite or generated)
+- intension (schema + constraints + derivation meaning)
+
+The current engine already exposes the extension side robustly for
+many operations, despite the lack of constraints greater than 1OP.
+The main active work is making intension handling fully consistent and
+reliable across planners/operators/protocols.
+
+* Roadmap and Docs
+
+- =docs/reliability_roadmap.org= :: precise reliability + correctness roadmap
+- =docs/code.org= :: code-oriented notes
+- =docs/features.org= :: feature notes (may contain older planning context)
+- =docs/constraints.org= :: constraint model notes
+
+* References
+
+- Codd, E. F. (1970), "A Relational Model of Data for Large Shared Data Banks"
+- Codd, E. F. (1979), "Extending the Database Relational Model to Capture More Meaning"
+
+* License
+
+See =LICENSE=.
diff --git a/config/vm.args b/config/vm.args
index 4ff3840..524f9f2 100644
--- a/config/vm.args
+++ b/config/vm.args
@@ -1,5 +1,5 @@
## Name of the node
--sname domino
+-sname sakura
## Extra options
-heart
diff --git a/docs/reliability_roadmap.org b/docs/reliability_roadmap.org
new file mode 100644
index 0000000..d47a00e
--- /dev/null
+++ b/docs/reliability_roadmap.org
@@ -0,0 +1,223 @@
+#+TITLE: Sakura Reliability Roadmap (Precise)
+
+* Scope
+
+Build Sakura into a correct and efficient first-order predicate logic (FOPL)
+relational algebra engine where relations are first-class values with:
+
+- *Extension* :: denotation as a tuple set (finite stored set or generated stream)
+- *Intension* :: logical meaning (schema + normalized constraints + derivation)
+
+* Formal Position on Issue =#48=
+
+Issue =#48= is *not* semantic redundancy.
+
+- =constraint:create_1op/3= is an attribute-constraint *definition* constructor.
+- =constraint:add_attribute_constraint/3= is a relation-level *binding* operation.
+
+They are distinct layers. The defect is API ambiguity and weak invariants.
+
+- [ ] Require key/record coherence: key =:= =#attribute_constraint.attribute=.
+- [ ] Provide one canonical "declare and bind" path to prevent invalid states.
+
+* Relation Contract (Non-Negotiable)
+
+** C1 Representation Contract
+
+- [ ] Exactly one extension mode per relation:
+ - finite stored: =tree =/= undefined= and =generator= is factory for tree iterator
+ - generated: =tree == undefined= and =generator= is mandatory
+- [ ] Intension is always =#relation_constraints{}=, never raw =#{}=.
+- [ ] =membership_criteria= is either removed (Issue =#47=) or treated as a derived cache from constraints, never a second source of truth.
+
+** C2 Identity Contract
+
+- [ ] Relation hash function is canonical and identical across all mutation paths.
+- [ ] Hash input includes the same semantic fields in the same order, with explicit versioned format.
+- [ ] Any relation update that changes intension or extension must change hash deterministically.
+
+** C3 Algebraic Closure Contract
+
+- [ ] Every algebra operator returns a relation with valid extension + intension.
+- [ ] Constraint propagation rules are explicit and tested per operator.
+- [ ] Result schema and constraints are compatible and normalized.
+
+* Current Critical Correctness Gaps
+
+- [ ] Non-canonical relation hash updates in =src/operations.erl=.
+- [ ] Split semantics between =constraints= and =membership_criteria=.
+- [ ] Mixed constraints shapes (=#relation_constraints{}= and raw maps).
+- [ ] Placeholder substitution search in =constraint:find_satisfying_substitution/4=.
+- [ ] Derived infinite/finite relations not consistently honoring constraints (=#13=, =#14=).
+- [ ] Dual planner paths with mismatched behavior in =src/query_planner.erl=.
+- [ ] Iterator close protocol mismatch (=stop= vs =close= forms).
+- [ ] XML schema endpoint assumes map constraints and crashes.
+
+* Workstreams
+
+** W0 Safety and Determinism (P0)
+
+- [ ] Fix =xml_server= SCHEMA serialization for record constraints (=src/xml_server.erl=).
+- [ ] Replace ad-hoc prints with =logger= (=#39=), remove debug output in constraint lookup.
+- [ ] Make =repl:start/0= non-destructive; add explicit destructive reset command.
+- [ ] Standardize iterator termination protocol across all iterator loops.
+- [ ] Normalize constraints type in all constructors (planner/operators/operations).
+
+*Acceptance criteria*
+
+- [ ] No SCHEMA crash under any built-in relation set.
+- [ ] No unsolicited stdout noise during normal queries.
+- [ ] No relation loss on default REPL startup.
+- [ ] No orphan iterator processes after collect/close paths.
+
+** W1 FOPL Semantics Core (P1)
+
+- [ ] Implement full variable binding search and substitution for partial constraints.
+- [ ] Define and enforce formula AST for =and/or/not/exists/forall=.
+- [ ] Separate logical membership from physical storage existence checks.
+- [ ] Decide and document two-valued logic policy (no NULL) or explicit three-valued policy.
+- [ ] Complete 1OPiC modeling (=#42=) and baseline 1OP constraints (=#28=).
+
+*Acceptance criteria*
+
+- [ ] Quantified constraints produce correct truth values on finite fixtures.
+- [ ] Membership equivalence tests pass for stored vs generated extension of same intension.
+- [ ] Constraint violation diagnostics identify failing attribute/formula branch.
+
+** W2 Constraint Model Consistency (P1)
+
+- [ ] Resolve =#48= with scope-safe API (define vs bind) and strict invariant checks.
+- [ ] Implement relation creation with constraints in one call (=#15=).
+- [ ] Decide fate of =membership_criteria= (=#47=): remove or strict derivation cache.
+- [ ] Add migration helper to convert legacy constraint maps to =#relation_constraints{}=.
+- [ ] Establish extension/intension introspection API for debugging and tooling.
+
+*Acceptance criteria*
+
+- [ ] No public path can construct mismatched attribute constraint key/record pairs.
+- [ ] New relation creation API supports schema + constraints atomically.
+- [ ] Intension is serialized/deserialized in one normalized shape everywhere.
+
+** W3 Planner Unification (P1)
+
+- [ ] Remove dual compile paths; keep one logical -> rewrite -> physical pipeline.
+- [ ] Add semantic validation (schema compatibility, attribute existence, constraint shape).
+- [ ] Add rewrite rules: projection pruning, predicate pushdown, limited join reordering.
+- [ ] Add typed planner errors for REPL/XML consumers.
+
+*Acceptance criteria*
+
+- [ ] Same query plan always yields same output schema and row semantics across interfaces.
+- [ ] Planner rejects invalid plans with stable machine-readable reasons.
+
+** W4 Algebra Completeness and Performance (P2)
+
+- [ ] Implement union/intersection/difference with strict compatibility checks.
+- [ ] Implement semijoin/antijoin/division.
+- [ ] Add hash join and merge join; keep nested loop fallback.
+- [ ] Enforce bounded execution preconditions for blocking operators over infinite relations.
+- [ ] Improve tuple hash retrieval path performance (=#7=).
+
+*Acceptance criteria*
+
+- [ ] Algebra law regression tests pass for finite relations (where laws apply).
+- [ ] Join strategy selection is observable and benchmarked.
+- [ ] Infinite + blocking plans fail fast with actionable diagnostics unless bounded.
+
+** W5 Versioning and Updatable Views (P2)
+
+- [ ] Implement branch metadata and lineage (=#43=).
+- [ ] Implement fast-forward merge semantics and conflict checks (=#44=).
+- [ ] Implement provenance-safe updatable ephemeral views (=#26=).
+
+*Acceptance criteria*
+
+- [ ] Branch/merge operations are deterministic and test-covered.
+- [ ] Updatable views reject ambiguous write-back paths.
+
+** W6 Interfaces and Hardening (P2)
+
+- [ ] Replace XML =erl_eval= execution with safe parsed DSL/AST.
+- [ ] Version protocol responses and provide structured errors.
+- [ ] Add explain-analyze metrics (rows, time, strategy, spills/materialization).
+- [ ] Add visualizer mode for relation semantics (schema, constraints, lineage, extension mode).
+- [ ] Integrate or deprecate =relation.erl= helper model.
+
+*Acceptance criteria*
+
+- [ ] No arbitrary code execution path through external query interface.
+- [ ] Interface responses are stable under malformed input and concurrency.
+
+* GitHub Issue Mapping
+
+** Core reliability and semantics
+
+- [ ] =#39= logging
+- [ ] =#15= define constraints at finite relation creation
+- [ ] =#14= derived finite from infinite honors/inherits constraints
+- [ ] =#13= derived infinite honors constraints
+- [ ] =#7= tuple hash retrieval performance
+
+** Constraint/data model
+
+- [ ] =#48= clarify define/bind API and enforce invariants
+- [ ] =#47= remove/replace membership_criteria split
+- [ ] =#42= proper 1OPiC model
+- [ ] =#28 #29 #30 #31= 1st/2nd/3rd/4th order property constraints
+
+** Versioning and updates
+
+- [ ] =#43= branching
+- [ ] =#44= fast-forward merge
+- [ ] =#26= updatable views
+
+** Optional research tracks
+
+- [ ] =#45= nullary relations vs booleans
+- [ ] =#40= state monad
+- [ ] =#41= C node for hot loops
+- [ ] =#19= chessboard integration
+
+* Verification Matrix (Must Exist in CI)
+
+- [ ] Unit tests: constraints AST eval, membership semantics, hash determinism
+- [ ] Property tests: algebra laws, hash stability, propagation invariants
+- [ ] Integration tests: REPL flows, XML QUERY/NEXT/CLOSE/SCHEMA, malformed inputs
+- [ ] Performance tests: join algorithms, bounded infinite queries, Merkle hash retrieval
+- [ ] Concurrency tests: iterator lifecycle and server session cleanup
+
+* Milestones and Exit Criteria
+
+** M1 (Safety Baseline)
+
+- Deliver W0
+- Close target issues: =#39 #15 #14 #13 #7=
+- Exit: no destructive default startup, no XML schema crash, no protocol-level iterator leaks
+
+** M2 (Semantic Correctness)
+
+- Deliver W1 + W2
+- Close target issues: =#48 #47 #42 #28= (with foundations for =#29 #30 #31=)
+- Exit: extension/intension invariants hold across create/query/derive flows
+
+** M3 (Planner and Performance)
+
+- Deliver W3 + W4
+- Exit: unified planner, bounded infinite behavior, measurable join improvements
+
+** M4 (Versioned Workflows)
+
+- Deliver W5 + W6
+- Close target issues: =#43 #44 #26=
+- Exit: deterministic branch/merge and safe updatable views with stable interfaces
+
+* Execution Order
+
+1. W0 Safety and Determinism
+2. W1 FOPL Semantics Core
+3. W2 Constraint Model Consistency
+4. W3 Planner Unification
+5. W4 Algebra Completeness and Performance
+6. W5 Versioning and Updatable Views
+7. W6 Interfaces and Hardening
+8. Optional research tracks (=#45 #40 #41 #19=)
diff --git a/flake.nix b/flake.nix
index c0a22b2..14cc8de 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,5 +1,5 @@
{
- description = "Domino's flakes";
+ description = "Sakura's flakes";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
@@ -20,7 +20,7 @@
erlangLatest = pkgs.erlang_28;
rebar_config = builtins.readFile ./rebar.config;
- match = builtins.match ".*release,.+domino, \"([0-9.]+)\".*" rebar_config;
+ match = builtins.match ".*release,.+sakura, \"([0-9.]+)\".*" rebar_config;
pversion = builtins.head match;
in {
# This sets `pkgs` to a nixpkgs with allowUnfree option set.
@@ -39,7 +39,7 @@
};
in
pkgs.beamPackages.rebar3Relx {
- pname = "domino";
+ pname = "sakura";
version = pversion;
src = pkgs.lib.cleanSource ./.;
releaseType = "release";
diff --git a/rebar.config b/rebar.config
index b419da1..584e37b 100644
--- a/rebar.config
+++ b/rebar.config
@@ -23,7 +23,7 @@
%% == Releases ==
{relx, [
- {release, {domino, "0.1.0"}, [
+ {release, {sakura, "0.1.0"}, [
merklet,
uuid_erl
]},
@@ -98,6 +98,6 @@
{includes, ["include"]},
{dir, "doc"},
{overview, "doc/overview.edoc"},
- {title, "Domino - Extended Relational Database Engine"},
+ {title, "Sakura - Extended Relational Database Engine"},
{pretty_printer, erl_pp}
]}.
diff --git a/src/constraint.erl b/src/constraint.erl
index 24b5fa7..0562f49 100644
--- a/src/constraint.erl
+++ b/src/constraint.erl
@@ -23,12 +23,12 @@
validate_tuple/3,
validate_tuple_against_schema/3,
build_membership_criteria/2,
- lt/1, % value < X
- lte/1, % value <= X
- gt/1, % value > X
- gte/1, % value >= X
- eq/1, % value = X
- neq/1, % value != X
+ lt/2, % value < X
+ lte/2, % value <= X
+ gt/2, % value > X
+ gte/2, % value >= X
+ eq/2, % value = X
+ neq/2, % value != X
between/2, % Min <= value < Max
%% Constraint Propagation
empty_constraints/0, % Create empty #relation_constraints{}
@@ -132,9 +132,9 @@ equal(DomainName, Cardinality) ->
constraints = #{},
%% The diagonal has the same cardinality as the domain itself
cardinality = Cardinality,
- generator = {comparison, '==', DomainName},
+ generator = {comparison, '=:=', DomainName},
membership_criteria = #{
- intension => fun(#{left := L, right := R}) -> L == R end
+ intension => fun(#{left := L, right := R}) -> L =:= R end
},
provenance = undefined,
lineage = {base, equal}
@@ -551,44 +551,44 @@ build_membership_criteria(Database, Schema) ->
%% @doc Create a "less than" constraint: value &lt; X
%%
%% Expressed relationally as: (value, X) ∈ less_than
--spec lt(term()) -> relational_constraint().
-lt(Value) ->
- {member_of, less_than, #{left => {var, value}, right => Value}}.
+-spec lt(term(), term()) -> relational_constraint().
+lt(Left, Right) ->
+ {member_of, less_than, #{left => Left, right => Right}}.
%% @doc Create a "less than or equal" constraint: value &lt;= X
--spec lte(term()) -> relational_constraint().
-lte(Value) ->
- {member_of, less_than_or_equal, #{left => {var, value}, right => Value}}.
+-spec lte(term(), term()) -> relational_constraint().
+lte(Left, Right) ->
+ {member_of, less_than_or_equal, #{left => Left, right => Right}}.
%% @doc Create a "greater than" constraint: value &gt; X
%%
-%% Expressed relationally as: (X, value) ∈ less_than
--spec gt(term()) -> relational_constraint().
-gt(Value) ->
- {member_of, less_than, #{left => Value, right => {var, value}}}.
+%% Expressed relationally as: (X, value) ∈ greater_than
+-spec gt(term(), term()) -> relational_constraint().
+gt(Left, Right) ->
+ {member_of, greater_than, #{left => Left, right => Right}}.
%% @doc Create a "greater than or equal" constraint: value &gt;= X
--spec gte(term()) -> relational_constraint().
-gte(Value) ->
- {member_of, less_than_or_equal, #{left => Value, right => {var, value}}}.
+-spec gte(term(), term()) -> relational_constraint().
+gte(Left, Right) ->
+ {member_of, greater_than_or_equal, #{left => Left, right => Right}}.
%% @doc Create an "equal" constraint: value = X
--spec eq(term()) -> relational_constraint().
-eq(Value) ->
- {member_of, equal, #{left => {var, value}, right => Value}}.
+-spec eq(term(), term()) -> relational_constraint().
+eq(Left, Right) ->
+ {member_of, equal, #{left => Left, right => Right}}.
%% @doc Create a "not equal" constraint: value != X
--spec neq(term()) -> relational_constraint().
-neq(Value) ->
- {member_of, not_equal, #{left => {var, value}, right => Value}}.
+-spec neq(term(), term()) -> relational_constraint().
+neq(Left, Right) ->
+ {member_of, not_equal, #{left => Left, right => Right}}.
%% @doc Create a range constraint: Min &lt;= value &lt; Max
%%
%% This is a conjunction of two relational constraints:
-%% (Min, value) ∈ less_than_or_equal AND (value, Max) ∈ less_than
+%% (Min, value) ∈ greater_than_or_equal AND (value, Max) ∈ less_than
-spec between(term(), term()) -> relational_constraint().
between(Min, Max) ->
- {'and', [gte(Min), lt(Max)]}.
+ {'and', [gte({var,value}, Min), lt({var, value}, Max)]}.
%%% Constraint Propagation
%%%
@@ -788,13 +788,12 @@ rename_vars_in_constraint({'not', Constraint, Universe}, Mappings) ->
rename_vars_in_constraint(Other, _Mappings) ->
Other.
-%% Helper: convert declarative operator to relational constraint
-op_to_constraint(lt, Value) -> lt(Value);
-op_to_constraint(lte, Value) -> lte(Value);
-op_to_constraint(gt, Value) -> gt(Value);
-op_to_constraint(gte, Value) -> gte(Value);
-op_to_constraint(eq, Value) -> eq(Value);
-op_to_constraint(neq, Value) -> neq(Value);
+op_to_constraint(lt, Value) -> lt({var, value}, Value);
+op_to_constraint(lte, Value) -> lte({var, value}, Value);
+op_to_constraint(gt, Value) -> gt({var, value}, Value);
+op_to_constraint(gte, Value) -> gte({var, value}, Value);
+op_to_constraint(eq, Value) -> eq({var, value}, Value);
+op_to_constraint(neq, Value) -> neq({var, value}, Value);
op_to_constraint(between, {Min, Max}) -> between(Min, Max);
op_to_constraint(_, _Value) -> {'and', []}. % No-op constraint
@@ -987,8 +986,8 @@ example() ->
DB = operations:create_database(test_db),
maps:keys(DB#database_state.relations),
{DB1, _} = operations:create_relation(DB, employees, #{id => integer, name => string, age => integer, salary => integer}),
- IdConstraint = constraint:create_1op(id, integer, [constraint:gt(0)]),
- AgeConstraint = constraint:create_1op(age, integer, [constraint:gte(18), constraint:lt(70)]),
+ IdConstraint = constraint:create_1op(id, integer, [constraint:gt({var, value}, 0)]),
+ AgeConstraint = constraint:create_1op(age, integer, [constraint:gte({var, value}, 18), constraint:lt({var,value}, 70)]),
SalaryConstraint = constraint:create_1op(salary, integer, [constraint:between(30000, 200000)]),
C1 = constraint:add_attribute_constraint(undefined, id, IdConstraint),
C2 = constraint:add_attribute_constraint(C1, age, AgeConstraint),
diff --git a/src/operations.erl b/src/operations.erl
index f4143c8..0462034 100644
--- a/src/operations.erl
+++ b/src/operations.erl
@@ -1,6 +1,6 @@
%%% @doc Extended Relational Database Operations (RM/T)
%%%
-%%% This module implements core database operations for Domino, an extended
+%%% This module implements core database operations for Sakura, an extended
%%% relational database engine based on E. F. Codd's RM/T (1979).
%%%
%%% == Architecture ==
diff --git a/src/repl.erl b/src/repl.erl
index 599d721..b26a418 100644
--- a/src/repl.erl
+++ b/src/repl.erl
@@ -1,4 +1,4 @@
-%%% @doc Interactive REPL Helper for Domino Query Planner
+%%% @doc Interactive REPL Helper for Sakura Query Planner
%%%
%%% Provides convenience functions for working with the query planner
%%% in the Erlang shell (REPL). Includes utilities for pretty-printing
@@ -69,7 +69,7 @@
%%% Public API
-%% @doc Start the Domino system and initialize Mnesia.
+%% @doc Start the Sakura system and initialize Mnesia.
%%
%% Call this first when starting a new REPL session.
%%
@@ -78,7 +78,7 @@
start() ->
main:setup(),
io:format("~n~s~n", [banner()]),
- io:format("Domino REPL started. Type repl:help() for usage.~n~n"),
+ io:format("Sakura REPL started. Type repl:help() for usage.~n~n"),
ok.
%% @doc Create an example database with sample data.
@@ -243,7 +243,7 @@ pretty(Results) ->
-spec help() -> ok.
help() ->
io:format("~n~s~n~n", [banner()]),
- io:format("Domino Query REPL - Lisp-inspired tuple-based query language~n~n"),
+ io:format("Sakura Query REPL - Lisp-inspired tuple-based query language~n~n"),
io:format("Quick Start:~n"),
io:format(" repl:start(). %% Initialize system~n"),
io:format(" DB = repl:example_db(). %% Create example database~n"),
@@ -321,6 +321,6 @@ help() ->
banner() ->
"========================================\n"
- " Domino - Extended Relational DB\n"
+ " Sakura - Extended Relational DB\n"
" Tasmania / RM/T Implementation\n"
"========================================".
diff --git a/src/xml_server_app.erl b/src/xml_server_app.erl
index b7b9faa..51a9565 100644
--- a/src/xml_server_app.erl
+++ b/src/xml_server_app.erl
@@ -11,9 +11,9 @@ start() ->
%% @doc Start XML server on specified port.
start(Port) ->
- % Initialize Domino
+ % Initialize Sakura
main:setup(),
- io:format("~nDomino initialized~n"),
+ io:format("~nSakura initialized~n"),
% Create example database
DB = repl:example_db(),
@@ -23,6 +23,6 @@ start(Port) ->
io:format("~nXML Server ready!~n"),
io:format("Connect with: nc localhost ~p~n", [Port]),
- io:format("Or run Emacs client: M-x domino-run-examples~n~n"),
+ io:format("Or run Emacs client: M-x sakura-run-examples~n~n"),
ok.