From 7e8e44b3f6e21015fa9db4a52ac7b9cd2a913967 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 14 Jun 2026 01:34:52 +0000 Subject: [PATCH] =?UTF-8?q?refactor(rust):=20VCL=20rename=20stage=20B=20(1?= =?UTF-8?q?/5)=20=E2=80=94=20rust-core=20server=20+=20openapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First sub-stage of the Stage B code rename (#84). Per maintainer decision this is a hard rename including the public endpoint (no back-compat alias). Renamed (git mv + identifiers, 26 files): - verisim-api/src/vql.rs -> vcl.rs; route POST /vql/execute -> /vcl/execute; handler vql_execute_handler -> vcl_execute_handler; `pub mod vql` -> `pub mod vcl` - verisim-planner/src/vql_bridge.rs -> vcl_bridge.rs (AST types VqlAst/VqlQuery/... -> Vcl*); `pub mod vql_bridge` -> vcl_bridge - verisim-repl/src/vql_fmt.rs -> vcl_fmt.rs; REPL binary "vql" -> "vcl"; client POSTs /vcl/execute; .vqlrc -> .vclrc - both fuzz targets fuzz_vql_parser -> fuzz_vcl_parser (file + [[bin]] name + path), importing verisim_api::vcl::tokenize - connectors/shared/openapi/verisim-api-v1.yaml: /api/v1/vcl/execute - tests/integration_test.rs Follow-ups (tracked under #84, intentionally out of this PR): - Client SDKs still call /api/v1/vql/execute (Elixir/Rust/Zig/Julia/ ReScript/playground) -> clients sub-stage. CI unaffected: clients compile against their own string; no live integration test in unit CI. - Elixir-internal contracts (type:vql_query tag, vql_dt_active, the vql-bridge/ JS dir + @parser_script_path) -> Elixir follow-up. Verified locally (cargo cannot build offline here -- oxigraph et al. need network, so the real compile runs on CI): grep-to-zero leaves no vql/VQL/Vql token in rust-core/fuzz/openapi/integration; no other workspace crate imports the renamed modules/types; symmetric 418/418 diff (equal-length token swaps, no structural change). Refs #84. https://claude.ai/code/session_01W9Voe3JceP66Bna9FT4jME --- connectors/shared/openapi/verisim-api-v1.yaml | 22 +- fuzz/Cargo.toml | 6 +- ...{fuzz_vql_parser.rs => fuzz_vcl_parser.rs} | 10 +- rust-core/fuzz/Cargo.toml | 6 +- ...{fuzz_vql_parser.rs => fuzz_vcl_parser.rs} | 10 +- rust-core/verisim-api/src/lib.rs | 16 +- rust-core/verisim-api/src/rbac.rs | 2 +- rust-core/verisim-api/src/{vql.rs => vcl.rs} | 96 ++--- rust-core/verisim-octad/src/query_octad.rs | 14 +- rust-core/verisim-planner/src/cost.rs | 12 +- rust-core/verisim-planner/src/lib.rs | 2 +- rust-core/verisim-planner/src/prepared.rs | 4 +- rust-core/verisim-planner/src/slow_query.rs | 2 +- .../src/{vql_bridge.rs => vcl_bridge.rs} | 354 +++++++++--------- rust-core/verisim-repl/Cargo.toml | 6 +- rust-core/verisim-repl/src/client.rs | 24 +- rust-core/verisim-repl/src/completer.rs | 14 +- rust-core/verisim-repl/src/formatter.rs | 2 +- rust-core/verisim-repl/src/highlighter.rs | 30 +- rust-core/verisim-repl/src/linter.rs | 58 +-- rust-core/verisim-repl/src/main.rs | 68 ++-- .../src/{vql_fmt.rs => vcl_fmt.rs} | 64 ++-- .../verisim-semantic/src/circuit_compiler.rs | 6 +- .../verisim-semantic/src/circuit_registry.rs | 2 +- rust-core/verisim-semantic/src/zkp_bridge.rs | 2 +- tests/integration_test.rs | 4 +- 26 files changed, 418 insertions(+), 418 deletions(-) rename fuzz/fuzz_targets/{fuzz_vql_parser.rs => fuzz_vcl_parser.rs} (69%) rename rust-core/fuzz/fuzz_targets/{fuzz_vql_parser.rs => fuzz_vcl_parser.rs} (69%) rename rust-core/verisim-api/src/{vql.rs => vcl.rs} (93%) rename rust-core/verisim-planner/src/{vql_bridge.rs => vcl_bridge.rs} (86%) rename rust-core/verisim-repl/src/{vql_fmt.rs => vcl_fmt.rs} (90%) diff --git a/connectors/shared/openapi/verisim-api-v1.yaml b/connectors/shared/openapi/verisim-api-v1.yaml index 3da235e..0f51210 100644 --- a/connectors/shared/openapi/verisim-api-v1.yaml +++ b/connectors/shared/openapi/verisim-api-v1.yaml @@ -4,7 +4,7 @@ # OpenAPI 3.1 specification for the VeriSimDB REST API. # Covers all octad CRUD operations, search endpoints, drift monitoring, # provenance chain management, spatial queries, normalisation triggers, -# and VQL query execution. +# and VCL query execution. openapi: "3.1.0" @@ -44,7 +44,7 @@ tags: description: Self-normalisation trigger and status - name: provenance description: Provenance chain management and verification - - name: vql + - name: vcl description: VeriSim Query Language execution paths: @@ -947,17 +947,17 @@ paths: $ref: "../json-schema/error.json" # --------------------------------------------------------------------------- - # VQL + # VCL # --------------------------------------------------------------------------- - /api/v1/vql/execute: + /api/v1/vcl/execute: post: - operationId: executeVql - summary: Execute a VQL query + operationId: executeVcl + summary: Execute a VCL query description: | - Executes a VeriSim Query Language (VQL) query against the - database. VQL is VeriSimDB's native query language, providing + Executes a VeriSim Query Language (VCL) query against the + database. VCL is VeriSimDB's native query language, providing cross-modal querying with optional proof requirements. - tags: [vql] + tags: [vcl] requestBody: required: true content: @@ -969,7 +969,7 @@ paths: query: type: string description: | - VQL query string. Example: + VCL query string. Example: `FIND entities WHERE document CONTAINS "neural" AND vector SIMILAR TO [0.1, 0.2, ...] LIMIT 10` explain: type: boolean @@ -1005,7 +1005,7 @@ paths: type: object description: Query execution plan (only when explain=true). "400": - description: VQL syntax error or invalid query. + description: VCL syntax error or invalid query. content: application/json: schema: diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 2e8beaf..5df369c 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -12,7 +12,7 @@ cargo-fuzz = true # directory per project (it walks up from the cwd to the nearest `fuzz/`, which # is always this one), so EVERY target ClusterFuzzLite builds must live here — # a target in rust-core/fuzz is unreachable via `cargo fuzz` and silently -# resolves back to this manifest. fuzz_vql_parser therefore lives here too. +# resolves back to this manifest. fuzz_vcl_parser therefore lives here too. # rust-core/fuzz is retained only for the native `cargo check` matrix leg in # rust-ci.yml; the canonical fuzz harnesses are these. [dependencies] @@ -33,8 +33,8 @@ test = false doc = false [[bin]] -name = "fuzz_vql_parser" -path = "fuzz_targets/fuzz_vql_parser.rs" +name = "fuzz_vcl_parser" +path = "fuzz_targets/fuzz_vcl_parser.rs" test = false doc = false diff --git a/fuzz/fuzz_targets/fuzz_vql_parser.rs b/fuzz/fuzz_targets/fuzz_vcl_parser.rs similarity index 69% rename from fuzz/fuzz_targets/fuzz_vql_parser.rs rename to fuzz/fuzz_targets/fuzz_vcl_parser.rs index 624cddc..178f652 100644 --- a/fuzz/fuzz_targets/fuzz_vql_parser.rs +++ b/fuzz/fuzz_targets/fuzz_vcl_parser.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // -// Fuzz target for the VQL parser. -// Run with: cargo +nightly fuzz run fuzz_vql_parser +// Fuzz target for the VCL parser. +// Run with: cargo +nightly fuzz run fuzz_vcl_parser // -// This fuzzer feeds arbitrary byte strings to the VQL parser to find +// This fuzzer feeds arbitrary byte strings to the VCL parser to find // panics, hangs, or memory safety issues. The parser should gracefully // reject invalid input without crashing. @@ -12,14 +12,14 @@ use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { - // Only attempt to parse valid UTF-8 strings — the VQL parser + // Only attempt to parse valid UTF-8 strings — the VCL parser // operates on &str, not raw bytes. if let Ok(input) = std::str::from_utf8(data) { // Limit input size to prevent timeouts on extremely long strings if input.len() <= 4096 { // The parser should never panic on any valid UTF-8 input. // We don't care about the result — only that it doesn't crash. - let _ = verisim_api::vql::tokenize(input); + let _ = verisim_api::vcl::tokenize(input); } } }); diff --git a/rust-core/fuzz/Cargo.toml b/rust-core/fuzz/Cargo.toml index 977c204..df9d90f 100644 --- a/rust-core/fuzz/Cargo.toml +++ b/rust-core/fuzz/Cargo.toml @@ -2,7 +2,7 @@ # Retained for the native `cargo check` matrix leg in rust-ci.yml. The # ClusterFuzzLite build uses the top-level fuzz/ crate (cargo-fuzz resolves a -# single fuzz dir per project), where fuzz_vql_parser is canonically hosted. +# single fuzz dir per project), where fuzz_vcl_parser is canonically hosted. [package] name = "verisimdb-fuzz" version = "0.0.0" @@ -23,7 +23,7 @@ path = "../verisim-api" members = ["."] [[bin]] -name = "fuzz_vql_parser" -path = "fuzz_targets/fuzz_vql_parser.rs" +name = "fuzz_vcl_parser" +path = "fuzz_targets/fuzz_vcl_parser.rs" test = false doc = false diff --git a/rust-core/fuzz/fuzz_targets/fuzz_vql_parser.rs b/rust-core/fuzz/fuzz_targets/fuzz_vcl_parser.rs similarity index 69% rename from rust-core/fuzz/fuzz_targets/fuzz_vql_parser.rs rename to rust-core/fuzz/fuzz_targets/fuzz_vcl_parser.rs index 624cddc..178f652 100644 --- a/rust-core/fuzz/fuzz_targets/fuzz_vql_parser.rs +++ b/rust-core/fuzz/fuzz_targets/fuzz_vcl_parser.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // -// Fuzz target for the VQL parser. -// Run with: cargo +nightly fuzz run fuzz_vql_parser +// Fuzz target for the VCL parser. +// Run with: cargo +nightly fuzz run fuzz_vcl_parser // -// This fuzzer feeds arbitrary byte strings to the VQL parser to find +// This fuzzer feeds arbitrary byte strings to the VCL parser to find // panics, hangs, or memory safety issues. The parser should gracefully // reject invalid input without crashing. @@ -12,14 +12,14 @@ use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { - // Only attempt to parse valid UTF-8 strings — the VQL parser + // Only attempt to parse valid UTF-8 strings — the VCL parser // operates on &str, not raw bytes. if let Ok(input) = std::str::from_utf8(data) { // Limit input size to prevent timeouts on extremely long strings if input.len() <= 4096 { // The parser should never panic on any valid UTF-8 input. // We don't care about the result — only that it doesn't crash. - let _ = verisim_api::vql::tokenize(input); + let _ = verisim_api::vcl::tokenize(input); } } }); diff --git a/rust-core/verisim-api/src/lib.rs b/rust-core/verisim-api/src/lib.rs index 1e8124e..a1f9da4 100644 --- a/rust-core/verisim-api/src/lib.rs +++ b/rust-core/verisim-api/src/lib.rs @@ -14,7 +14,7 @@ pub mod proof_attempts; pub mod rbac; pub mod regenerator; pub mod transaction; -pub mod vql; +pub mod vcl; use axum::{ extract::{Path, Query, State}, @@ -827,8 +827,8 @@ pub fn build_router(state: AppState) -> Router { post(spatial_bounds_search_handler), ) .route("/spatial/search/nearest", post(spatial_nearest_handler)) - // VQL text query endpoint (used by verisim-repl) - .route("/vql/execute", post(vql::vql_execute_handler)) + // VCL text query endpoint (used by verisim-repl) + .route("/vcl/execute", post(vcl::vcl_execute_handler)) // S4 learning loop — ECHIDNA proof attempts (see proof_attempts module docs) .route( "/proof_attempts", @@ -1530,7 +1530,7 @@ async fn planner_stats_handler( /// Store query request body #[derive(Debug, Serialize, Deserialize)] pub struct StoreQueryRequest { - /// The VQL query text + /// The VCL query text pub query: String, /// Optional embedding for the query pub embedding: Option>, @@ -1540,7 +1540,7 @@ pub struct StoreQueryRequest { pub proof_obligations: Option>, } -/// Store a VQL query as a octad (homoiconicity) +/// Store a VCL query as a octad (homoiconicity) #[instrument(skip(state, request))] async fn store_query_handler( State(state): State, @@ -1602,13 +1602,13 @@ async fn similar_queries_handler( .await .map_err(|e| ApiError::Internal(e.to_string()))?; - // Filter to only query octads (those with "vql_query" type in document fields) + // Filter to only query octads (those with "vcl_query" type in document fields) let results: Vec = scored .iter() .filter(|(h, _score)| { h.document .as_ref() - .map(|d| d.title.starts_with("VQL Query:")) + .map(|d| d.title.starts_with("VCL Query:")) .unwrap_or(false) }) .map(|(h, score)| SearchResultResponse { @@ -1745,7 +1745,7 @@ async fn query_explain_analyze_handler( /// Request to create a prepared statement #[derive(Debug, Serialize, Deserialize)] pub struct PreparedCreateRequest { - /// The VQL query text + /// The VCL query text pub query: String, /// The logical plan for the query pub plan: LogicalPlan, diff --git a/rust-core/verisim-api/src/rbac.rs b/rust-core/verisim-api/src/rbac.rs index f7b203a..761828f 100644 --- a/rust-core/verisim-api/src/rbac.rs +++ b/rust-core/verisim-api/src/rbac.rs @@ -42,7 +42,7 @@ pub enum Permission { Write, /// Administrative operations (config changes, normalizer triggers, key management). Admin, - /// Execute queries (VQL execution, query planning, EXPLAIN). + /// Execute queries (VCL execution, query planning, EXPLAIN). Execute, } diff --git a/rust-core/verisim-api/src/vql.rs b/rust-core/verisim-api/src/vcl.rs similarity index 93% rename from rust-core/verisim-api/src/vql.rs rename to rust-core/verisim-api/src/vcl.rs index 97beb71..66c9d24 100644 --- a/rust-core/verisim-api/src/vql.rs +++ b/rust-core/verisim-api/src/vcl.rs @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) //! -//! VQL execution endpoint — accepts VQL text queries, parses them, and +//! VCL execution endpoint — accepts VCL text queries, parses them, and //! routes to the appropriate store operations. //! -//! This is a lightweight server-side VQL parser that handles the core +//! This is a lightweight server-side VCL parser that handles the core //! query operations directly against the octad store. It bridges the gap -//! between the REPL client (which sends raw VQL text) and the REST API +//! between the REPL client (which sends raw VCL text) and the REST API //! (which expects structured JSON requests). //! -//! ## Supported VQL Statements +//! ## Supported VCL Statements //! //! - `SELECT [modalities] FROM octads [WHERE id = '...'] [LIMIT n]` //! - `SEARCH TEXT '' [LIMIT n]` @@ -31,16 +31,16 @@ use verisim_octad::{OctadDocumentInput, OctadId, OctadInput, OctadStore}; use crate::{ApiError, AppState, OctadResponse}; -/// VQL execute request — wraps a raw VQL query string. +/// VCL execute request — wraps a raw VCL query string. #[derive(Debug, Deserialize)] -pub struct VqlExecuteRequest { - /// The VQL query text to parse and execute. +pub struct VclExecuteRequest { + /// The VCL query text to parse and execute. pub query: String, } -/// VQL execute response — returns structured results from a query. +/// VCL execute response — returns structured results from a query. #[derive(Debug, Serialize)] -pub struct VqlExecuteResponse { +pub struct VclExecuteResponse { /// Whether the query executed successfully. pub success: bool, /// The type of statement that was executed. @@ -52,10 +52,10 @@ pub struct VqlExecuteResponse { /// Optional message (e.g., for INSERT/DELETE confirmations). #[serde(skip_serializing_if = "Option::is_none")] pub message: Option, - /// VQL-UT safety level achieved (0-9), if TypeLL validation was performed. + /// VCL-UT safety level achieved (0-9), if TypeLL validation was performed. #[serde(skip_serializing_if = "Option::is_none")] pub safety_level: Option, - /// VQL-UT query path used: "VQL (Slipstream)", "VQL-DT", or "VQL-UT". + /// VCL-UT query path used: "VCL (Slipstream)", "VCL-DT", or "VCL-UT". #[serde(skip_serializing_if = "Option::is_none")] pub query_path: Option, /// Proof obligations generated by TypeLL (for ECHIDNA dispatch). @@ -63,15 +63,15 @@ pub struct VqlExecuteResponse { pub proof_obligations: Option>, } -/// Execute a VQL query string against the database. +/// Execute a VCL query string against the database. /// /// Parses the query, determines the operation, executes it against the /// octad store, and returns structured results. #[instrument(skip(state, request), fields(query = %request.query))] -pub async fn vql_execute_handler( +pub async fn vcl_execute_handler( State(state): State, - Json(request): Json, -) -> Result, ApiError> { + Json(request): Json, +) -> Result, ApiError> { let query = request.query.trim(); if query.is_empty() { @@ -89,7 +89,7 @@ pub async fn vql_execute_handler( )); } - // Pre-flight: validate with TypeLL VQL-UT checker if available. + // Pre-flight: validate with TypeLL VCL-UT checker if available. // This is non-blocking — if TypeLL is unreachable, we proceed without it. let typell_report = validate_with_typell(query).await; @@ -102,7 +102,7 @@ pub async fn vql_execute_handler( "COUNT" => execute_count(&state, &tokens).await, "EXPLAIN" => execute_explain(&state, &tokens, query).await, other => Err(ApiError::BadRequest(format!( - "Unknown VQL statement: '{}'. Supported: SELECT, SEARCH, INSERT, DELETE, SHOW, COUNT, EXPLAIN", + "Unknown VCL statement: '{}'. Supported: SELECT, SEARCH, INSERT, DELETE, SHOW, COUNT, EXPLAIN", other ))), }?; @@ -120,15 +120,15 @@ pub async fn vql_execute_handler( statement_type = %result.statement_type, row_count = result.row_count, safety_level = ?result.safety_level, - "VQL query executed" + "VCL query executed" ); Ok(Json(result)) } -/// Tokenize a VQL query into whitespace-separated tokens, respecting +/// Tokenize a VCL query into whitespace-separated tokens, respecting /// quoted strings (single and double quotes). -/// Validate a VQL query against TypeLL's VQL-UT 10-level type checker. +/// Validate a VCL query against TypeLL's VCL-UT 10-level type checker. /// /// Calls the TypeLL server (default: localhost:7800) to verify the query's /// type safety level. Returns (safety_level, query_path, proof_obligations) @@ -143,7 +143,7 @@ async fn validate_with_typell(query: &str) -> Option<(u8, String, Vec)> let check_body = serde_json::json!({ "expression": query, - "context": "{\"language\":\"vql\",\"dialect\":\"vql-ut\",\"features\":[\"dependent\",\"linear\",\"proof-carrying\"]}" + "context": "{\"language\":\"vcl\",\"dialect\":\"vcl-ut\",\"features\":[\"dependent\",\"linear\",\"proof-carrying\"]}" }); let client = reqwest::Client::builder() @@ -164,14 +164,14 @@ async fn validate_with_typell(query: &str) -> Option<(u8, String, Vec)> let body: serde_json::Value = resp.json().await.ok()?; - // Extract VQL-UT level from features (e.g., "vql-ut-l4") + // Extract VCL-UT level from features (e.g., "vcl-ut-l4") let level = body .get("features") .and_then(|f| f.as_array()) .and_then(|arr| { arr.iter().find_map(|v| { let s = v.as_str()?; - if let Some(stripped) = s.strip_prefix("vql-ut-l") { + if let Some(stripped) = s.strip_prefix("vcl-ut-l") { stripped.parse::().ok() } else { None @@ -180,7 +180,7 @@ async fn validate_with_typell(query: &str) -> Option<(u8, String, Vec)> }) .unwrap_or(0); - // Extract query path from features (e.g., "path:VQL-UT") + // Extract query path from features (e.g., "path:VCL-UT") let path = body .get("features") .and_then(|f| f.as_array()) @@ -190,7 +190,7 @@ async fn validate_with_typell(query: &str) -> Option<(u8, String, Vec)> s.strip_prefix("path:").map(|p| p.to_string()) }) }) - .unwrap_or_else(|| "VQL (Slipstream)".to_string()); + .unwrap_or_else(|| "VCL (Slipstream)".to_string()); // Extract proof obligations let obligations: Vec = body @@ -207,13 +207,13 @@ async fn validate_with_typell(query: &str) -> Option<(u8, String, Vec)> safety_level = level, query_path = %path, obligations = obligations.len(), - "TypeLL VQL-UT pre-flight check complete" + "TypeLL VCL-UT pre-flight check complete" ); Some((level, path, obligations)) } -/// Tokenize a VQL query into whitespace-separated tokens, respecting +/// Tokenize a VCL query into whitespace-separated tokens, respecting /// quoted strings. Public so fuzz targets can exercise it. pub fn tokenize(input: &str) -> Vec { let mut tokens = Vec::new(); @@ -286,7 +286,7 @@ async fn execute_select( state: &AppState, tokens: &[String], _raw: &str, -) -> Result { +) -> Result { let (limit, _) = parse_limit(tokens); // Check for WHERE id = '...' @@ -303,7 +303,7 @@ async fn execute_select( .ok_or_else(|| ApiError::NotFound(format!("Octad '{}' not found", id)))?; let response = OctadResponse::from(&octad); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SELECT".to_string(), row_count: 1, @@ -325,7 +325,7 @@ async fn execute_select( let responses: Vec = octads.iter().map(OctadResponse::from).collect(); let count = responses.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SELECT".to_string(), row_count: count, @@ -367,7 +367,7 @@ fn find_where_id(tokens: &[String]) -> Option<&str> { async fn execute_search( state: &AppState, tokens: &[String], -) -> Result { +) -> Result { if tokens.len() < 3 { return Err(ApiError::BadRequest( "SEARCH requires at least: SEARCH TEXT '' or SEARCH VECTOR [...]".to_string(), @@ -401,7 +401,7 @@ async fn execute_search( .collect(); let count = results.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SEARCH TEXT".to_string(), row_count: count, @@ -446,7 +446,7 @@ async fn execute_search( .collect(); let count = results.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SEARCH VECTOR".to_string(), row_count: count, @@ -482,7 +482,7 @@ async fn execute_search( let responses: Vec = octads.iter().map(OctadResponse::from).collect(); let count = responses.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SEARCH RELATED".to_string(), row_count: count, @@ -529,7 +529,7 @@ fn parse_vector(s: &str) -> Result, ApiError> { /// /// Also accepts simplified form: /// `INSERT '' '<body>'` -async fn execute_insert(state: &AppState, raw: &str) -> Result<VqlExecuteResponse, ApiError> { +async fn execute_insert(state: &AppState, raw: &str) -> Result<VclExecuteResponse, ApiError> { let upper = raw.to_uppercase(); let (title, body) = if upper.starts_with("INSERT INTO") { @@ -567,7 +567,7 @@ async fn execute_insert(state: &AppState, raw: &str) -> Result<VqlExecuteRespons let response = OctadResponse::from(&octad); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "INSERT".to_string(), row_count: 1, @@ -616,7 +616,7 @@ fn parse_insert_values(raw: &str) -> Result<(String, String), ApiError> { async fn execute_delete( state: &AppState, tokens: &[String], -) -> Result<VqlExecuteResponse, ApiError> { +) -> Result<VclExecuteResponse, ApiError> { let id = find_where_id(tokens).ok_or_else(|| { ApiError::BadRequest("DELETE requires: DELETE FROM octads WHERE id = '<id>'".to_string()) })?; @@ -634,7 +634,7 @@ async fn execute_delete( _ => ApiError::Internal(e.to_string()), })?; - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "DELETE".to_string(), row_count: 1, @@ -657,7 +657,7 @@ async fn execute_delete( /// - `SHOW DRIFT` — drift metrics /// - `SHOW NORMALIZER` — normalizer status /// - `SHOW OCTADS [LIMIT n]` — list octads (alias for SELECT) -async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteResponse, ApiError> { +async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VclExecuteResponse, ApiError> { if tokens.len() < 2 { return Err(ApiError::BadRequest( "SHOW requires: SHOW STATUS | SHOW DRIFT | SHOW NORMALIZER | SHOW OCTADS".to_string(), @@ -684,7 +684,7 @@ async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteR Err(_) => ("degraded", Some("Drift detector unavailable".to_string())), }; - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SHOW STATUS".to_string(), row_count: 1, @@ -720,7 +720,7 @@ async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteR .collect(); let count = results.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SHOW DRIFT".to_string(), row_count: count, @@ -733,7 +733,7 @@ async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteR } "NORMALIZER" => { let status = state.normalizer.status().await; - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SHOW NORMALIZER".to_string(), row_count: 1, @@ -756,7 +756,7 @@ async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteR let responses: Vec<OctadResponse> = octads.iter().map(OctadResponse::from).collect(); let count = responses.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "SHOW OCTADS".to_string(), row_count: count, @@ -786,7 +786,7 @@ async fn execute_show(state: &AppState, tokens: &[String]) -> Result<VqlExecuteR async fn execute_count( state: &AppState, _tokens: &[String], -) -> Result<VqlExecuteResponse, ApiError> { +) -> Result<VclExecuteResponse, ApiError> { // List with a large limit to count (in a real DB this would be a COUNT query). let octads = state .octad_store @@ -796,7 +796,7 @@ async fn execute_count( let count = octads.len(); - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "COUNT".to_string(), row_count: 1, @@ -815,12 +815,12 @@ async fn execute_count( /// Execute an EXPLAIN query — describes what a query would do without executing. /// /// Supported form: -/// - `EXPLAIN <any VQL query>` +/// - `EXPLAIN <any VCL query>` async fn execute_explain( _state: &AppState, tokens: &[String], raw: &str, -) -> Result<VqlExecuteResponse, ApiError> { +) -> Result<VclExecuteResponse, ApiError> { if tokens.len() < 2 { return Err(ApiError::BadRequest( "EXPLAIN requires a query to explain".to_string(), @@ -906,7 +906,7 @@ async fn execute_explain( _ => json!({"operation": format!("Unrecognized: {}", statement_type)}), }; - Ok(VqlExecuteResponse { + Ok(VclExecuteResponse { success: true, statement_type: "EXPLAIN".to_string(), row_count: 1, diff --git a/rust-core/verisim-octad/src/query_octad.rs b/rust-core/verisim-octad/src/query_octad.rs index e4cf906..05de460 100644 --- a/rust-core/verisim-octad/src/query_octad.rs +++ b/rust-core/verisim-octad/src/query_octad.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 -//! QueryOctad Builder — Creates a octad from a VQL query. +//! QueryOctad Builder — Creates a octad from a VCL query. //! -//! Homoiconicity: queries are data. A VQL query stored as a octad has: +//! Homoiconicity: queries are data. A VCL query stored as a octad has: //! - **Document**: query text (searchable via full-text) //! - **Graph**: parse tree as subject → predicate → object triples //! - **Vector**: embedding of query text (for similarity search of past queries) @@ -31,7 +31,7 @@ pub struct QueryExecution { pub estimated_cost: f64, } -/// A builder for creating octads from VQL queries +/// A builder for creating octads from VCL queries #[derive(Debug)] pub struct QueryOctadBuilder { query_text: String, @@ -45,7 +45,7 @@ pub struct QueryOctadBuilder { } impl QueryOctadBuilder { - /// Create a new builder from a VQL query string + /// Create a new builder from a VCL query string pub fn new(query_text: impl Into<String>) -> Self { Self { query_text: query_text.into(), @@ -112,11 +112,11 @@ impl QueryOctadBuilder { // Document modality: query text (searchable) input.document = Some(OctadDocumentInput { - title: format!("VQL Query: {}", truncate(&self.query_text, 80)), + title: format!("VCL Query: {}", truncate(&self.query_text, 80)), body: self.query_text.clone(), fields: { let mut fields = HashMap::new(); - fields.insert("type".to_string(), "vql_query".to_string()); + fields.insert("type".to_string(), "vcl_query".to_string()); fields.insert("query_text".to_string(), self.query_text); if !self.executions.is_empty() { fields.insert( @@ -211,7 +211,7 @@ mod tests { assert!(input.semantic.is_some()); let doc = input.document.unwrap(); - assert!(doc.title.starts_with("VQL Query:")); + assert!(doc.title.starts_with("VCL Query:")); assert!(doc.body.contains("drift")); } diff --git a/rust-core/verisim-planner/src/cost.rs b/rust-core/verisim-planner/src/cost.rs index 311e10f..601e5c6 100644 --- a/rust-core/verisim-planner/src/cost.rs +++ b/rust-core/verisim-planner/src/cost.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 //! Cost model and estimation. //! -//! Base costs match VQLExplain.res values. Mode multipliers match +//! Base costs match VCLExplain.res values. Mode multipliers match //! query_planner_config.ex (conservative=1.5x, balanced=1.0x, aggressive=0.8x). use serde::{Deserialize, Serialize}; @@ -25,7 +25,7 @@ pub struct BaseCost { impl BaseCost { /// Get the default base cost for a modality. /// - /// Values match VQLExplain.res: + /// Values match VCLExplain.res: /// - Graph: 150ms, 0.2 selectivity /// - Vector: 50ms, 0.01 selectivity /// - Tensor: 200ms, 0.5 selectivity @@ -133,7 +133,7 @@ impl CostEstimate { /// /// Different proof types have vastly different verification costs. /// Values derived from the consultation-dependent-types-zkp.adoc -/// and VQLProofObligation.res cost estimates. +/// and VCLProofObligation.res cost estimates. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProofCost { /// Base verification time in milliseconds. @@ -147,7 +147,7 @@ pub struct ProofCost { impl ProofCost { /// Get the cost for a proof type by name. /// - /// Proof types from VQLProofObligation.res: + /// Proof types from VCLProofObligation.res: /// - Existence: trivial check (octad exists) /// - Citation: contract lookup in registry /// - Access: semantic store rights check @@ -309,7 +309,7 @@ impl CostModel { /// Estimate the cost of executing a single plan node. /// /// Factors: - /// 1. Base cost for the modality (from VQLExplain.res) + /// 1. Base cost for the modality (from VCLExplain.res) /// 2. Optimization mode multiplier (from query_planner_config.ex) /// 3. Store statistics (if available) /// 4. Early limit reduction @@ -491,7 +491,7 @@ mod tests { use crate::config::PlannerConfig; #[test] - fn test_base_costs_match_vql_explain() { + fn test_base_costs_match_vcl_explain() { assert_eq!(BaseCost::for_modality(Modality::Graph).time_ms, 150.0); assert_eq!(BaseCost::for_modality(Modality::Vector).time_ms, 50.0); assert_eq!(BaseCost::for_modality(Modality::Tensor).time_ms, 200.0); diff --git a/rust-core/verisim-planner/src/lib.rs b/rust-core/verisim-planner/src/lib.rs index f8c73ef..d6e0dc4 100644 --- a/rust-core/verisim-planner/src/lib.rs +++ b/rust-core/verisim-planner/src/lib.rs @@ -16,7 +16,7 @@ pub mod prepared; pub mod profiler; pub mod slow_query; pub mod stats; -pub mod vql_bridge; +pub mod vcl_bridge; use serde::{Deserialize, Serialize}; use std::fmt; diff --git a/rust-core/verisim-planner/src/prepared.rs b/rust-core/verisim-planner/src/prepared.rs index 28c9893..df8b8b4 100644 --- a/rust-core/verisim-planner/src/prepared.rs +++ b/rust-core/verisim-planner/src/prepared.rs @@ -420,7 +420,7 @@ impl PlanCache { /// Normalization rules: /// 1. Collapse all whitespace (spaces, tabs, newlines) into single spaces. /// 2. Trim leading and trailing whitespace. - /// 3. Lowercase VQL/SQL keywords (SELECT, WHERE, FROM, SEARCH, LIMIT, ORDER, BY, GROUP, + /// 3. Lowercase VCL/SQL keywords (SELECT, WHERE, FROM, SEARCH, LIMIT, ORDER, BY, GROUP, /// AND, OR, NOT, JOIN, ON, AS, HAVING, INSERT, UPDATE, DELETE, SET, INTO, VALUES, /// WITH, UNION, INTERSECT, EXCEPT, EXISTS, BETWEEN, LIKE, IN, IS, NULL, TRUE, FALSE, /// ASC, DESC, DISTINCT, ALL, ANY, SOME, CASE, WHEN, THEN, ELSE, END, PROOF, VERIFY, @@ -605,7 +605,7 @@ impl PlanCache { // We split on whitespace, check each token against the keyword list, // and lowercase it if it matches. Non-keyword tokens keep original case. let keywords = [ - // SQL/VQL standard keywords + // SQL/VCL standard keywords "SELECT", "WHERE", "FROM", diff --git a/rust-core/verisim-planner/src/slow_query.rs b/rust-core/verisim-planner/src/slow_query.rs index af995dd..bcd29c5 100644 --- a/rust-core/verisim-planner/src/slow_query.rs +++ b/rust-core/verisim-planner/src/slow_query.rs @@ -54,7 +54,7 @@ pub struct SlowQueryEntry { /// When the query was recorded. pub timestamp: DateTime<Utc>, - /// The VQL query text (if available). + /// The VCL query text (if available). pub query_text: Option<String>, /// Actual execution time in milliseconds. diff --git a/rust-core/verisim-planner/src/vql_bridge.rs b/rust-core/verisim-planner/src/vcl_bridge.rs similarity index 86% rename from rust-core/verisim-planner/src/vql_bridge.rs rename to rust-core/verisim-planner/src/vcl_bridge.rs index c6b32a6..a289d6d 100644 --- a/rust-core/verisim-planner/src/vql_bridge.rs +++ b/rust-core/verisim-planner/src/vcl_bridge.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! VQL AST to LogicalPlan bridge. +//! VCL AST to LogicalPlan bridge. //! -//! Deserializes VQL JSON produced by the ReScript parser (BuckleScript encoding) +//! Deserializes VCL JSON produced by the ReScript parser (BuckleScript encoding) //! and converts it into the [`LogicalPlan`] representation used by the planner. //! //! ## BuckleScript Encoding @@ -29,35 +29,35 @@ use crate::plan::{ConditionKind, LogicalPlan, PlanNode, PostProcessing, QuerySou use crate::Modality; // --------------------------------------------------------------------------- -// VQL AST types (mirrors BuckleScript JSON encoding) +// VCL AST types (mirrors BuckleScript JSON encoding) // --------------------------------------------------------------------------- -/// Top-level VQL statement as emitted by the ReScript parser. +/// Top-level VCL statement as emitted by the ReScript parser. /// /// BuckleScript encodes this as `{"TAG": "Query", "_0": { ... }}`. /// We use a custom deserializer because serde's internally-tagged enum /// (`#[serde(tag = "TAG")]`) does not support positional `_0` content fields. #[derive(Debug, Clone)] -pub enum VqlAst { +pub enum VclAst { /// A SELECT-style query. - Query(VqlQuery), + Query(VclQuery), } -impl<'de> Deserialize<'de> for VqlAst { +impl<'de> Deserialize<'de> for VclAst { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { - struct VqlAstVisitor; + struct VclAstVisitor; - impl<'de> Visitor<'de> for VqlAstVisitor { - type Value = VqlAst; + impl<'de> Visitor<'de> for VclAstVisitor { + type Value = VclAst; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a VQL AST object with TAG and _0 fields") + formatter.write_str("a VCL AST object with TAG and _0 fields") } - fn visit_map<M>(self, mut map: M) -> Result<VqlAst, M::Error> + fn visit_map<M>(self, mut map: M) -> Result<VclAst, M::Error> where M: MapAccess<'de>, { @@ -78,48 +78,48 @@ impl<'de> Deserialize<'de> for VqlAst { match tag.as_str() { "Query" => { let body = payload.ok_or_else(|| de::Error::missing_field("_0"))?; - let query: VqlQuery = + let query: VclQuery = serde_json::from_value(body).map_err(de::Error::custom)?; - Ok(VqlAst::Query(query)) + Ok(VclAst::Query(query)) } other => Err(de::Error::unknown_variant(other, &["Query"])), } } } - deserializer.deserialize_map(VqlAstVisitor) + deserializer.deserialize_map(VclAstVisitor) } } -/// Body of a VQL query. +/// Body of a VCL query. #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct VqlQuery { +pub struct VclQuery { /// Requested modalities (`Graph`, `Vector`, ..., or `All`). - pub modalities: Vec<VqlModality>, + pub modalities: Vec<VclModality>, /// Data source (Octad, Federation, Store). - pub source: VqlSource, + pub source: VclSource, /// Optional WHERE clause. #[serde(default, rename = "where")] - pub where_clause: Option<VqlCondition>, + pub where_clause: Option<VclCondition>, /// Optional field projections. #[serde(default)] - pub projections: Option<Vec<VqlProjection>>, + pub projections: Option<Vec<VclProjection>>, /// Optional aggregate functions. #[serde(default)] - pub aggregates: Option<Vec<VqlAggregate>>, + pub aggregates: Option<Vec<VclAggregate>>, /// Optional GROUP BY fields. #[serde(default)] - pub group_by: Option<Vec<VqlFieldRef>>, + pub group_by: Option<Vec<VclFieldRef>>, /// Optional HAVING clause. #[serde(default)] - pub having: Option<VqlCondition>, + pub having: Option<VclCondition>, /// Optional PROOF specifications. #[serde(default)] - pub proof: Option<Vec<VqlProofSpec>>, + pub proof: Option<Vec<VclProofSpec>>, /// Optional ORDER BY clauses. #[serde(default)] - pub order_by: Option<Vec<VqlOrderBy>>, + pub order_by: Option<Vec<VclOrderBy>>, /// Optional result limit. #[serde(default)] pub limit: Option<usize>, @@ -128,12 +128,12 @@ pub struct VqlQuery { pub offset: Option<usize>, } -/// A VQL modality tag. +/// A VCL modality tag. /// /// The ReScript parser emits modalities as `{"TAG": "Graph"}` etc. /// `All` is a special sentinel meaning "expand to all 6 modalities". #[derive(Debug, Clone)] -pub enum VqlModality { +pub enum VclModality { Graph, Vector, Tensor, @@ -143,21 +143,21 @@ pub enum VqlModality { All, } -impl<'de> Deserialize<'de> for VqlModality { +impl<'de> Deserialize<'de> for VclModality { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { - struct VqlModalityVisitor; + struct VclModalityVisitor; - impl<'de> Visitor<'de> for VqlModalityVisitor { - type Value = VqlModality; + impl<'de> Visitor<'de> for VclModalityVisitor { + type Value = VclModality; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a VQL modality object with TAG field") + formatter.write_str("a VCL modality object with TAG field") } - fn visit_map<M>(self, mut map: M) -> Result<VqlModality, M::Error> + fn visit_map<M>(self, mut map: M) -> Result<VclModality, M::Error> where M: MapAccess<'de>, { @@ -171,13 +171,13 @@ impl<'de> Deserialize<'de> for VqlModality { } } match tag.as_deref() { - Some("Graph") => Ok(VqlModality::Graph), - Some("Vector") => Ok(VqlModality::Vector), - Some("Tensor") => Ok(VqlModality::Tensor), - Some("Semantic") => Ok(VqlModality::Semantic), - Some("Document") => Ok(VqlModality::Document), - Some("Temporal") => Ok(VqlModality::Temporal), - Some("All") => Ok(VqlModality::All), + Some("Graph") => Ok(VclModality::Graph), + Some("Vector") => Ok(VclModality::Vector), + Some("Tensor") => Ok(VclModality::Tensor), + Some("Semantic") => Ok(VclModality::Semantic), + Some("Document") => Ok(VclModality::Document), + Some("Temporal") => Ok(VclModality::Temporal), + Some("All") => Ok(VclModality::All), Some(other) => Err(de::Error::unknown_variant( other, &[ @@ -189,14 +189,14 @@ impl<'de> Deserialize<'de> for VqlModality { } } - deserializer.deserialize_map(VqlModalityVisitor) + deserializer.deserialize_map(VclModalityVisitor) } } /// Data source as emitted by the ReScript parser. #[derive(Debug, Clone, Deserialize)] #[serde(tag = "TAG")] -pub enum VqlSource { +pub enum VclSource { /// Single octad store. `_0` is an optional UUID filter. Octad { #[serde(rename = "_0")] @@ -212,26 +212,26 @@ pub enum VqlSource { /// Direct store access for a specific modality. Store { #[serde(rename = "_0")] - modality: VqlModality, + modality: VclModality, }, } -/// A VQL condition (WHERE clause tree). +/// A VCL condition (WHERE clause tree). /// /// BuckleScript encodes each variant with TAG + positional args. #[derive(Debug, Clone)] -pub enum VqlCondition { +pub enum VclCondition { /// Conjunction. - And(Box<VqlCondition>, Box<VqlCondition>), + And(Box<VclCondition>, Box<VclCondition>), /// Disjunction. - Or(Box<VqlCondition>, Box<VqlCondition>), + Or(Box<VclCondition>, Box<VclCondition>), /// Negation. - Not(Box<VqlCondition>), + Not(Box<VclCondition>), /// Leaf condition. - Simple(VqlSimpleCondition), + Simple(VclSimpleCondition), } -impl<'de> Deserialize<'de> for VqlCondition { +impl<'de> Deserialize<'de> for VclCondition { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, @@ -242,8 +242,8 @@ impl<'de> Deserialize<'de> for VqlCondition { } } -/// Parse a `VqlCondition` from a `serde_json::Value`. -fn parse_condition(value: &serde_json::Value) -> Result<VqlCondition, String> { +/// Parse a `VclCondition` from a `serde_json::Value`. +fn parse_condition(value: &serde_json::Value) -> Result<VclCondition, String> { let obj = value.as_object().ok_or("condition must be a JSON object")?; let tag = obj .get("TAG") @@ -258,7 +258,7 @@ fn parse_condition(value: &serde_json::Value) -> Result<VqlCondition, String> { let rhs = obj .get("_1") .ok_or("And condition missing _1 (right operand)")?; - Ok(VqlCondition::And( + Ok(VclCondition::And( Box::new(parse_condition(lhs)?), Box::new(parse_condition(rhs)?), )) @@ -270,28 +270,28 @@ fn parse_condition(value: &serde_json::Value) -> Result<VqlCondition, String> { let rhs = obj .get("_1") .ok_or("Or condition missing _1 (right operand)")?; - Ok(VqlCondition::Or( + Ok(VclCondition::Or( Box::new(parse_condition(lhs)?), Box::new(parse_condition(rhs)?), )) } "Not" => { let inner = obj.get("_0").ok_or("Not condition missing _0 (operand)")?; - Ok(VqlCondition::Not(Box::new(parse_condition(inner)?))) + Ok(VclCondition::Not(Box::new(parse_condition(inner)?))) } "Simple" => { let inner = obj.get("_0").ok_or("Simple condition missing _0")?; - let simple: VqlSimpleCondition = + let simple: VclSimpleCondition = serde_json::from_value(inner.clone()).map_err(|e| e.to_string())?; - Ok(VqlCondition::Simple(simple)) + Ok(VclCondition::Simple(simple)) } other => Err(format!("unknown condition TAG: {other}")), } } -/// Leaf-level condition kinds from VQL. +/// Leaf-level condition kinds from VCL. #[derive(Debug, Clone)] -pub enum VqlSimpleCondition { +pub enum VclSimpleCondition { /// Full-text search: `CONTAINS "search text"`. FulltextContains(String), /// Vector similarity: `SIMILAR TO [embedding] THRESHOLD threshold`. @@ -303,33 +303,33 @@ pub enum VqlSimpleCondition { }, /// Field condition: `field op value`. FieldCondition { - field: VqlFieldRef, + field: VclFieldRef, operator: String, value: serde_json::Value, }, /// Cross-modal field comparison. CrossModalFieldCompare { - left: VqlFieldRef, + left: VclFieldRef, operator: String, - right: VqlFieldRef, + right: VclFieldRef, }, /// Modality drift check. ModalityDrift { - modality: VqlModality, + modality: VclModality, threshold: f64, }, /// Modality existence check. - ModalityExists(VqlModality), + ModalityExists(VclModality), /// Modality non-existence check. - ModalityNotExists(VqlModality), + ModalityNotExists(VclModality), /// Cross-modality consistency check. ModalityConsistency { - modalities: Vec<VqlModality>, + modalities: Vec<VclModality>, threshold: f64, }, } -impl<'de> Deserialize<'de> for VqlSimpleCondition { +impl<'de> Deserialize<'de> for VclSimpleCondition { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, @@ -339,8 +339,8 @@ impl<'de> Deserialize<'de> for VqlSimpleCondition { } } -/// Parse a `VqlSimpleCondition` from raw JSON. -fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleCondition, String> { +/// Parse a `VclSimpleCondition` from raw JSON. +fn parse_simple_condition(value: &serde_json::Value) -> Result<VclSimpleCondition, String> { let obj = value .as_object() .ok_or("simple condition must be a JSON object")?; @@ -355,7 +355,7 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio .get("_0") .and_then(|v| v.as_str()) .ok_or("FulltextContains missing _0 (search text)")?; - Ok(VqlSimpleCondition::FulltextContains(text.to_string())) + Ok(VclSimpleCondition::FulltextContains(text.to_string())) } "VectorSimilar" => { let embedding = obj @@ -372,7 +372,7 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio .get("_1") .and_then(|v| v.as_f64()) .ok_or("VectorSimilar missing _1 (threshold)")?; - Ok(VqlSimpleCondition::VectorSimilar { + Ok(VclSimpleCondition::VectorSimilar { embedding, threshold, }) @@ -384,11 +384,11 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio .ok_or("GraphPattern missing _0 (predicate)")? .to_string(); let depth = obj.get("_1").and_then(|v| v.as_u64()).map(|d| d as u32); - Ok(VqlSimpleCondition::GraphPattern { predicate, depth }) + Ok(VclSimpleCondition::GraphPattern { predicate, depth }) } "FieldCondition" => { let field_val = obj.get("_0").ok_or("FieldCondition missing _0 (field)")?; - let field: VqlFieldRef = + let field: VclFieldRef = serde_json::from_value(field_val.clone()).map_err(|e| e.to_string())?; let operator = obj .get("_1") @@ -399,7 +399,7 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio .get("_2") .cloned() .ok_or("FieldCondition missing _2 (value)")?; - Ok(VqlSimpleCondition::FieldCondition { + Ok(VclSimpleCondition::FieldCondition { field, operator, value: val, @@ -409,7 +409,7 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio let left_val = obj .get("_0") .ok_or("CrossModalFieldCompare missing _0 (left)")?; - let left: VqlFieldRef = + let left: VclFieldRef = serde_json::from_value(left_val.clone()).map_err(|e| e.to_string())?; let operator = obj .get("_1") @@ -419,9 +419,9 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio let right_val = obj .get("_2") .ok_or("CrossModalFieldCompare missing _2 (right)")?; - let right: VqlFieldRef = + let right: VclFieldRef = serde_json::from_value(right_val.clone()).map_err(|e| e.to_string())?; - Ok(VqlSimpleCondition::CrossModalFieldCompare { + Ok(VclSimpleCondition::CrossModalFieldCompare { left, operator, right, @@ -429,13 +429,13 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio } "ModalityDrift" => { let mod_val = obj.get("_0").ok_or("ModalityDrift missing _0 (modality)")?; - let modality: VqlModality = + let modality: VclModality = serde_json::from_value(mod_val.clone()).map_err(|e| e.to_string())?; let threshold = obj .get("_1") .and_then(|v| v.as_f64()) .ok_or("ModalityDrift missing _1 (threshold)")?; - Ok(VqlSimpleCondition::ModalityDrift { + Ok(VclSimpleCondition::ModalityDrift { modality, threshold, }) @@ -444,29 +444,29 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio let mod_val = obj .get("_0") .ok_or("ModalityExists missing _0 (modality)")?; - let modality: VqlModality = + let modality: VclModality = serde_json::from_value(mod_val.clone()).map_err(|e| e.to_string())?; - Ok(VqlSimpleCondition::ModalityExists(modality)) + Ok(VclSimpleCondition::ModalityExists(modality)) } "ModalityNotExists" => { let mod_val = obj .get("_0") .ok_or("ModalityNotExists missing _0 (modality)")?; - let modality: VqlModality = + let modality: VclModality = serde_json::from_value(mod_val.clone()).map_err(|e| e.to_string())?; - Ok(VqlSimpleCondition::ModalityNotExists(modality)) + Ok(VclSimpleCondition::ModalityNotExists(modality)) } "ModalityConsistency" => { let mods_val = obj .get("_0") .ok_or("ModalityConsistency missing _0 (modalities)")?; - let modalities: Vec<VqlModality> = + let modalities: Vec<VclModality> = serde_json::from_value(mods_val.clone()).map_err(|e| e.to_string())?; let threshold = obj .get("_1") .and_then(|v| v.as_f64()) .ok_or("ModalityConsistency missing _1 (threshold)")?; - Ok(VqlSimpleCondition::ModalityConsistency { + Ok(VclSimpleCondition::ModalityConsistency { modalities, threshold, }) @@ -477,19 +477,19 @@ fn parse_simple_condition(value: &serde_json::Value) -> Result<VqlSimpleConditio /// A field reference with optional modality qualifier. #[derive(Debug, Clone, Deserialize)] -pub struct VqlFieldRef { +pub struct VclFieldRef { /// Optional modality qualifier for the field. #[serde(default)] - pub modality: Option<VqlModality>, + pub modality: Option<VclModality>, /// Field name. pub field: String, } /// A projection entry. #[derive(Debug, Clone, Deserialize)] -pub struct VqlProjection { +pub struct VclProjection { /// The field being projected. - pub field: VqlFieldRef, + pub field: VclFieldRef, /// Optional alias. #[serde(default)] pub alias: Option<String>, @@ -497,37 +497,37 @@ pub struct VqlProjection { /// An aggregate function call. #[derive(Debug, Clone, Deserialize)] -pub struct VqlAggregate { +pub struct VclAggregate { /// Function name (COUNT, SUM, AVG, MIN, MAX, etc.). pub function: String, /// Field to aggregate (None for COUNT(*)). #[serde(default)] - pub field: Option<VqlFieldRef>, + pub field: Option<VclFieldRef>, /// Optional alias for the result. #[serde(default)] pub alias: Option<String>, } -/// A proof specification from the VQL PROOF clause. +/// A proof specification from the VCL PROOF clause. #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct VqlProofSpec { +pub struct VclProofSpec { /// Type of proof required. - pub proof_type: VqlProofType, + pub proof_type: VclProofType, /// Name of the verification contract. pub contract_name: String, } /// Proof type tag. #[derive(Debug, Clone)] -pub enum VqlProofType { +pub enum VclProofType { Citation, Zkp, Attestation, Custom(String), } -impl<'de> Deserialize<'de> for VqlProofType { +impl<'de> Deserialize<'de> for VclProofType { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, @@ -535,13 +535,13 @@ impl<'de> Deserialize<'de> for VqlProofType { struct ProofTypeVisitor; impl<'de> Visitor<'de> for ProofTypeVisitor { - type Value = VqlProofType; + type Value = VclProofType; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a VQL proof type object with TAG field") + formatter.write_str("a VCL proof type object with TAG field") } - fn visit_map<M>(self, mut map: M) -> Result<VqlProofType, M::Error> + fn visit_map<M>(self, mut map: M) -> Result<VclProofType, M::Error> where M: MapAccess<'de>, { @@ -554,10 +554,10 @@ impl<'de> Deserialize<'de> for VqlProofType { } } match tag.as_deref() { - Some("Citation") => Ok(VqlProofType::Citation), - Some("Zkp") => Ok(VqlProofType::Zkp), - Some("Attestation") => Ok(VqlProofType::Attestation), - Some(other) => Ok(VqlProofType::Custom(other.to_string())), + Some("Citation") => Ok(VclProofType::Citation), + Some("Zkp") => Ok(VclProofType::Zkp), + Some("Attestation") => Ok(VclProofType::Attestation), + Some(other) => Ok(VclProofType::Custom(other.to_string())), None => Err(de::Error::missing_field("TAG")), } } @@ -569,21 +569,21 @@ impl<'de> Deserialize<'de> for VqlProofType { /// An ORDER BY clause entry. #[derive(Debug, Clone, Deserialize)] -pub struct VqlOrderBy { +pub struct VclOrderBy { /// Field to order by. - pub field: VqlFieldRef, + pub field: VclFieldRef, /// Sort direction. - pub direction: VqlDirection, + pub direction: VclDirection, } /// Sort direction tag. #[derive(Debug, Clone)] -pub enum VqlDirection { +pub enum VclDirection { Asc, Desc, } -impl<'de> Deserialize<'de> for VqlDirection { +impl<'de> Deserialize<'de> for VclDirection { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, @@ -591,13 +591,13 @@ impl<'de> Deserialize<'de> for VqlDirection { struct DirectionVisitor; impl<'de> Visitor<'de> for DirectionVisitor { - type Value = VqlDirection; + type Value = VclDirection; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - formatter.write_str("a VQL direction object with TAG field") + formatter.write_str("a VCL direction object with TAG field") } - fn visit_map<M>(self, mut map: M) -> Result<VqlDirection, M::Error> + fn visit_map<M>(self, mut map: M) -> Result<VclDirection, M::Error> where M: MapAccess<'de>, { @@ -610,8 +610,8 @@ impl<'de> Deserialize<'de> for VqlDirection { } } match tag.as_deref() { - Some("Asc") => Ok(VqlDirection::Asc), - Some("Desc") => Ok(VqlDirection::Desc), + Some("Asc") => Ok(VclDirection::Asc), + Some("Desc") => Ok(VclDirection::Desc), Some(other) => Err(de::Error::unknown_variant(other, &["Asc", "Desc"])), None => Err(de::Error::missing_field("TAG")), } @@ -623,11 +623,11 @@ impl<'de> Deserialize<'de> for VqlDirection { } // --------------------------------------------------------------------------- -// Conversion: VqlAst -> LogicalPlan +// Conversion: VclAst -> LogicalPlan // --------------------------------------------------------------------------- -impl VqlAst { - /// Deserialize a VQL AST from JSON emitted by the ReScript parser. +impl VclAst { + /// Deserialize a VCL AST from JSON emitted by the ReScript parser. /// /// # Errors /// @@ -637,11 +637,11 @@ impl VqlAst { serde_json::from_str(json).map_err(PlannerError::Serialization) } - /// Convert the VQL AST into a [`LogicalPlan`]. + /// Convert the VCL AST into a [`LogicalPlan`]. /// /// This is the primary bridge function. It: /// 1. Expands `All` modality into all six concrete modalities. - /// 2. Maps the VQL source to [`QuerySource`]. + /// 2. Maps the VCL source to [`QuerySource`]. /// 3. Distributes WHERE conditions to per-modality [`PlanNode`]s. /// 4. Extracts LIMIT, OFFSET, ORDER BY, GROUP BY into [`PostProcessing`]. /// 5. Maps PROOF specs into [`ConditionKind::ProofVerification`] on Semantic nodes. @@ -650,7 +650,7 @@ impl VqlAst { /// /// Returns `PlannerError::EmptyPlan` if no modalities are requested. pub fn to_logical_plan(&self) -> Result<LogicalPlan, PlannerError> { - let VqlAst::Query(query) = self; + let VclAst::Query(query) = self; // 1. Resolve modalities (expand All). let modalities = resolve_modalities(&query.modalities)?; @@ -726,7 +726,7 @@ impl VqlAst { let fields: Vec<(String, bool)> = order_fields .iter() .map(|o| { - let ascending = matches!(o.direction, VqlDirection::Asc); + let ascending = matches!(o.direction, VclDirection::Asc); (field_ref_name(&o.field), ascending) }) .collect(); @@ -787,17 +787,17 @@ impl VqlAst { // Internal helpers // --------------------------------------------------------------------------- -/// Resolve VQL modalities to concrete `Modality` values, expanding `All`. -fn resolve_modalities(vql_mods: &[VqlModality]) -> Result<Vec<Modality>, PlannerError> { +/// Resolve VCL modalities to concrete `Modality` values, expanding `All`. +fn resolve_modalities(vcl_mods: &[VclModality]) -> Result<Vec<Modality>, PlannerError> { let mut result = Vec::new(); - for vm in vql_mods { + for vm in vcl_mods { match vm { - VqlModality::All => { + VclModality::All => { // Expand to all six modalities. result.extend_from_slice(&Modality::ALL); } other => { - result.push(vql_modality_to_planner(other)?); + result.push(vcl_modality_to_planner(other)?); } } } @@ -807,16 +807,16 @@ fn resolve_modalities(vql_mods: &[VqlModality]) -> Result<Vec<Modality>, Planner Ok(result) } -/// Map a single VQL modality to the planner `Modality` enum. -fn vql_modality_to_planner(vm: &VqlModality) -> Result<Modality, PlannerError> { +/// Map a single VCL modality to the planner `Modality` enum. +fn vcl_modality_to_planner(vm: &VclModality) -> Result<Modality, PlannerError> { match vm { - VqlModality::Graph => Ok(Modality::Graph), - VqlModality::Vector => Ok(Modality::Vector), - VqlModality::Tensor => Ok(Modality::Tensor), - VqlModality::Semantic => Ok(Modality::Semantic), - VqlModality::Document => Ok(Modality::Document), - VqlModality::Temporal => Ok(Modality::Temporal), - VqlModality::All => { + VclModality::Graph => Ok(Modality::Graph), + VclModality::Vector => Ok(Modality::Vector), + VclModality::Tensor => Ok(Modality::Tensor), + VclModality::Semantic => Ok(Modality::Semantic), + VclModality::Document => Ok(Modality::Document), + VclModality::Temporal => Ok(Modality::Temporal), + VclModality::All => { // Should have been expanded already. Err(PlannerError::InvalidConfig( "All modality should be expanded before individual mapping".to_string(), @@ -825,21 +825,21 @@ fn vql_modality_to_planner(vm: &VqlModality) -> Result<Modality, PlannerError> { } } -/// Map a VQL source to a planner `QuerySource`. -fn map_source(src: &VqlSource) -> Result<QuerySource, PlannerError> { +/// Map a VCL source to a planner `QuerySource`. +fn map_source(src: &VclSource) -> Result<QuerySource, PlannerError> { match src { - VqlSource::Octad { .. } => Ok(QuerySource::Octad), - VqlSource::Federation { nodes, .. } => Ok(QuerySource::Federation { + VclSource::Octad { .. } => Ok(QuerySource::Octad), + VclSource::Federation { nodes, .. } => Ok(QuerySource::Federation { nodes: nodes.clone(), }), - VqlSource::Store { modality } => { - let m = vql_modality_to_planner(modality)?; + VclSource::Store { modality } => { + let m = vcl_modality_to_planner(modality)?; Ok(QuerySource::Store { modality: m }) } } } -/// Flatten a VQL condition tree into per-modality condition lists. +/// Flatten a VCL condition tree into per-modality condition lists. /// /// Strategy: /// - Leaf conditions that target a specific modality go only to that node. @@ -848,16 +848,16 @@ fn map_source(src: &VqlSource) -> Result<QuerySource, PlannerError> { /// - `Or`/`Not` are converted to `Predicate` expressions (the physical executor /// handles them). They are broadcast to all active modalities. fn flatten_conditions( - cond: &VqlCondition, + cond: &VclCondition, active_modalities: &[Modality], out: &mut HashMap<Modality, Vec<ConditionKind>>, ) -> Result<(), PlannerError> { match cond { - VqlCondition::And(lhs, rhs) => { + VclCondition::And(lhs, rhs) => { flatten_conditions(lhs, active_modalities, out)?; flatten_conditions(rhs, active_modalities, out)?; } - VqlCondition::Or(lhs, rhs) => { + VclCondition::Or(lhs, rhs) => { // OR cannot be trivially split per-modality. Encode as a predicate // string on all active modalities. let desc = format!( @@ -871,7 +871,7 @@ fn flatten_conditions( }); } } - VqlCondition::Not(inner) => { + VclCondition::Not(inner) => { let desc = format!("NOT({})", describe_condition(inner)); for &m in active_modalities { out.entry(m).or_default().push(ConditionKind::Predicate { @@ -879,7 +879,7 @@ fn flatten_conditions( }); } } - VqlCondition::Simple(simple) => { + VclCondition::Simple(simple) => { let (target_modality, condition_kind) = map_simple_condition(simple)?; match target_modality { Some(m) if out.contains_key(&m) => { @@ -907,22 +907,22 @@ fn flatten_conditions( Ok(()) } -/// Map a VQL simple condition to a `ConditionKind` and an optional target modality. +/// Map a VCL simple condition to a `ConditionKind` and an optional target modality. /// /// Returns `(target_modality, condition_kind)` where `target_modality` is `Some` /// if the condition naturally targets a specific modality, `None` if it should be /// broadcast. fn map_simple_condition( - simple: &VqlSimpleCondition, + simple: &VclSimpleCondition, ) -> Result<(Option<Modality>, ConditionKind), PlannerError> { match simple { - VqlSimpleCondition::FulltextContains(text) => Ok(( + VclSimpleCondition::FulltextContains(text) => Ok(( Some(Modality::Document), ConditionKind::Fulltext { query: text.clone(), }, )), - VqlSimpleCondition::VectorSimilar { + VclSimpleCondition::VectorSimilar { embedding, threshold: _, } => { @@ -935,14 +935,14 @@ fn map_simple_condition( ConditionKind::Similarity { k: embedding.len() }, )) } - VqlSimpleCondition::GraphPattern { predicate, depth } => Ok(( + VclSimpleCondition::GraphPattern { predicate, depth } => Ok(( Some(Modality::Graph), ConditionKind::Traversal { predicate: predicate.clone(), depth: *depth, }, )), - VqlSimpleCondition::FieldCondition { + VclSimpleCondition::FieldCondition { field, operator, value, @@ -950,7 +950,7 @@ fn map_simple_condition( let target = field .modality .as_ref() - .and_then(|vm| vql_modality_to_planner(vm).ok()); + .and_then(|vm| vcl_modality_to_planner(vm).ok()); let field_name = field.field.clone(); let value_str = match value { serde_json::Value::String(s) => s.clone(), @@ -977,7 +977,7 @@ fn map_simple_condition( }; Ok((target, kind)) } - VqlSimpleCondition::CrossModalFieldCompare { + VclSimpleCondition::CrossModalFieldCompare { left, operator, right, @@ -999,31 +999,31 @@ fn map_simple_condition( ); Ok((None, ConditionKind::Predicate { expression: desc })) } - VqlSimpleCondition::ModalityDrift { + VclSimpleCondition::ModalityDrift { modality, threshold, } => { - let m = vql_modality_to_planner(modality)?; + let m = vcl_modality_to_planner(modality)?; let desc = format!("drift({m}) > {threshold}"); Ok((Some(m), ConditionKind::Predicate { expression: desc })) } - VqlSimpleCondition::ModalityExists(modality) => { - let m = vql_modality_to_planner(modality)?; + VclSimpleCondition::ModalityExists(modality) => { + let m = vcl_modality_to_planner(modality)?; let desc = format!("exists({m})"); Ok((Some(m), ConditionKind::Predicate { expression: desc })) } - VqlSimpleCondition::ModalityNotExists(modality) => { - let m = vql_modality_to_planner(modality)?; + VclSimpleCondition::ModalityNotExists(modality) => { + let m = vcl_modality_to_planner(modality)?; let desc = format!("not_exists({m})"); Ok((Some(m), ConditionKind::Predicate { expression: desc })) } - VqlSimpleCondition::ModalityConsistency { + VclSimpleCondition::ModalityConsistency { modalities, threshold, } => { let names: Vec<String> = modalities .iter() - .filter_map(|vm| vql_modality_to_planner(vm).ok()) + .filter_map(|vm| vcl_modality_to_planner(vm).ok()) .map(|m| m.to_string()) .collect(); let desc = format!("consistency({}) > {threshold}", names.join(", ")); @@ -1033,23 +1033,23 @@ fn map_simple_condition( } /// Produce a human-readable description of a condition (for predicate encoding). -fn describe_condition(cond: &VqlCondition) -> String { +fn describe_condition(cond: &VclCondition) -> String { match cond { - VqlCondition::And(l, r) => { + VclCondition::And(l, r) => { format!("({} AND {})", describe_condition(l), describe_condition(r)) } - VqlCondition::Or(l, r) => { + VclCondition::Or(l, r) => { format!("({} OR {})", describe_condition(l), describe_condition(r)) } - VqlCondition::Not(inner) => format!("NOT({})", describe_condition(inner)), - VqlCondition::Simple(s) => format!("{s:?}"), + VclCondition::Not(inner) => format!("NOT({})", describe_condition(inner)), + VclCondition::Simple(s) => format!("{s:?}"), } } -/// Build a per-modality projection map from VQL projections. +/// Build a per-modality projection map from VCL projections. fn build_projection_map( modalities: &[Modality], - projections: Option<&[VqlProjection]>, + projections: Option<&[VclProjection]>, ) -> HashMap<Modality, Vec<String>> { let mut map: HashMap<Modality, Vec<String>> = HashMap::new(); let Some(projs) = projections else { @@ -1063,7 +1063,7 @@ fn build_projection_map( .unwrap_or_else(|| proj.field.field.clone()); if let Some(ref vm) = proj.field.modality { - if let Ok(m) = vql_modality_to_planner(vm) { + if let Ok(m) = vcl_modality_to_planner(vm) { if modalities.contains(&m) { map.entry(m).or_default().push(field_name); } @@ -1078,8 +1078,8 @@ fn build_projection_map( map } -/// Render a `VqlFieldRef` as a dotted name string. -fn field_ref_name(f: &VqlFieldRef) -> String { +/// Render a `VclFieldRef` as a dotted name string. +fn field_ref_name(f: &VclFieldRef) -> String { match &f.modality { Some(m) => format!("{m:?}.{}", f.field), None => f.field.clone(), @@ -1094,9 +1094,9 @@ fn field_ref_name(f: &VqlFieldRef) -> String { mod tests { use super::*; - /// Helper: parse JSON string into VqlAst and convert to LogicalPlan. + /// Helper: parse JSON string into VclAst and convert to LogicalPlan. fn parse_and_plan(json: &str) -> Result<LogicalPlan, PlannerError> { - let ast = VqlAst::from_json(json)?; + let ast = VclAst::from_json(json)?; ast.to_logical_plan() } @@ -1343,7 +1343,7 @@ mod tests { "_0": {} }"#; - let result = VqlAst::from_json(json); + let result = VclAst::from_json(json); assert!(result.is_err(), "should reject unknown TAG"); } @@ -1353,7 +1353,7 @@ mod tests { "no_tag_field": "oops" }"#; - let result = VqlAst::from_json(json); + let result = VclAst::from_json(json); assert!(result.is_err(), "should reject missing TAG"); } diff --git a/rust-core/verisim-repl/Cargo.toml b/rust-core/verisim-repl/Cargo.toml index 7b774be..61a6ff4 100644 --- a/rust-core/verisim-repl/Cargo.toml +++ b/rust-core/verisim-repl/Cargo.toml @@ -2,7 +2,7 @@ [package] name = "verisim-repl" -description = "Interactive VQL REPL for VeriSimDB" +description = "Interactive VCL REPL for VeriSimDB" version.workspace = true edition.workspace = true authors.workspace = true @@ -10,7 +10,7 @@ license.workspace = true publish = false # workspace-internal; path deps cannot be published to crates.io [[bin]] -name = "vql" +name = "vcl" path = "src/main.rs" [dependencies] @@ -29,5 +29,5 @@ clap = { version = "4", features = ["derive"] } comfy-table = "7" colored = "3" -# Home directory resolution (history file, .vqlrc) +# Home directory resolution (history file, .vclrc) dirs = "6" diff --git a/rust-core/verisim-repl/src/client.rs b/rust-core/verisim-repl/src/client.rs index 8faee0f..4e1006d 100644 --- a/rust-core/verisim-repl/src/client.rs +++ b/rust-core/verisim-repl/src/client.rs @@ -4,12 +4,12 @@ //! HTTP client for communicating with the verisim-api server. //! //! Wraps `reqwest::blocking::Client` and provides typed methods for -//! VQL query execution, EXPLAIN output, and health checks. +//! VCL query execution, EXPLAIN output, and health checks. use reqwest::blocking::Client; use serde_json::Value; -/// Error type for VQL client operations. +/// Error type for VCL client operations. #[derive(Debug)] pub enum ClientError { /// HTTP transport or connection error. @@ -44,14 +44,14 @@ impl From<reqwest::Error> for ClientError { /// /// All methods use blocking I/O so they can be called directly from the /// synchronous REPL loop without an async runtime. -pub struct VqlClient { +pub struct VclClient { /// Base URL of the verisim-api server (e.g. `http://localhost:8080`). base_url: String, /// Underlying HTTP client (connection-pooled). http: Client, } -impl VqlClient { +impl VclClient { /// Create a new client pointing at the given base URL. /// /// The URL should include the scheme and port but no trailing slash. @@ -73,24 +73,24 @@ impl VqlClient { &self.base_url } - /// Execute a VQL query string. + /// Execute a VCL query string. /// - /// Sends `POST /vql/execute` with body `{"query": "<vql>"}`. + /// Sends `POST /vcl/execute` with body `{"query": "<vcl>"}`. /// Returns the raw JSON response from the server. pub fn execute(&self, query: &str) -> Result<Value, ClientError> { - let url = format!("{}/vql/execute", self.base_url); + let url = format!("{}/vcl/execute", self.base_url); let payload = serde_json::json!({ "query": query }); let response = self.http.post(&url).json(&payload).send()?; self.handle_response(response) } - /// Request EXPLAIN output for a VQL query. + /// Request EXPLAIN output for a VCL query. /// - /// Sends the query through the VQL execute endpoint with an EXPLAIN + /// Sends the query through the VCL execute endpoint with an EXPLAIN /// prefix, which returns a query plan without executing the query. pub fn explain(&self, query: &str) -> Result<Value, ClientError> { - let url = format!("{}/vql/execute", self.base_url); + let url = format!("{}/vcl/execute", self.base_url); let explain_query = format!("EXPLAIN {}", query); let payload = serde_json::json!({ "query": explain_query }); @@ -129,13 +129,13 @@ mod tests { #[test] fn test_client_creation() { - let client = VqlClient::new("http://localhost:8080"); + let client = VclClient::new("http://localhost:8080"); assert_eq!(client.base_url(), "http://localhost:8080"); } #[test] fn test_trailing_slash_stripped() { - let client = VqlClient::new("http://localhost:8080/"); + let client = VclClient::new("http://localhost:8080/"); assert_eq!(client.base_url(), "http://localhost:8080"); } diff --git a/rust-core/verisim-repl/src/completer.rs b/rust-core/verisim-repl/src/completer.rs index 9bac730..adab22c 100644 --- a/rust-core/verisim-repl/src/completer.rs +++ b/rust-core/verisim-repl/src/completer.rs @@ -1,17 +1,17 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! Tab-completion for the VQL REPL. +//! Tab-completion for the VCL REPL. //! //! Provides context-aware completion for: -//! - VQL keywords (SELECT, FROM, WHERE, PROOF, LIMIT, etc.) +//! - VCL keywords (SELECT, FROM, WHERE, PROOF, LIMIT, etc.) //! - Modality names (GRAPH, VECTOR, TENSOR, SEMANTIC, DOCUMENT, TEMPORAL) //! - Meta-commands (\\connect, \\explain, \\format, etc.) use rustyline::completion::{Completer, Pair}; use rustyline::Context; -/// All completable VQL keywords. +/// All completable VCL keywords. const KEYWORDS: &[&str] = &[ "SELECT", "FROM", @@ -94,15 +94,15 @@ const META_COMMANDS: &[&str] = &[ "\\q", ]; -/// Tab-completer for VQL input. +/// Tab-completer for VCL input. /// /// Completes the word under the cursor by matching against known keywords, /// modality names, and meta-commands. Matching is case-insensitive; the /// replacement preserves the user's casing style (upper if the prefix is /// uppercase, otherwise lowercase). -pub struct VqlCompleter; +pub struct VclCompleter; -impl Completer for VqlCompleter { +impl Completer for VclCompleter { type Candidate = Pair; fn complete( @@ -155,7 +155,7 @@ impl Completer for VqlCompleter { } } - // VQL keywords. + // VCL keywords. for kw in KEYWORDS { if kw.starts_with(&upper_prefix) { let replacement = if use_upper { diff --git a/rust-core/verisim-repl/src/formatter.rs b/rust-core/verisim-repl/src/formatter.rs index 7f448e6..bbc02da 100644 --- a/rust-core/verisim-repl/src/formatter.rs +++ b/rust-core/verisim-repl/src/formatter.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! Output formatters for VQL query results. +//! Output formatters for VCL query results. //! //! Supports three output modes: //! - **Table**: Human-readable columnar output using `comfy-table`. diff --git a/rust-core/verisim-repl/src/highlighter.rs b/rust-core/verisim-repl/src/highlighter.rs index d3dc7cc..f4ce8a9 100644 --- a/rust-core/verisim-repl/src/highlighter.rs +++ b/rust-core/verisim-repl/src/highlighter.rs @@ -1,17 +1,17 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! VQL syntax highlighting for the interactive REPL. +//! VCL syntax highlighting for the interactive REPL. //! -//! Implements `rustyline::highlight::Highlighter` to colour VQL keywords, +//! Implements `rustyline::highlight::Highlighter` to colour VCL keywords, //! modality names, string literals, and numeric literals as the user types. use colored::Colorize; use rustyline::highlight::Highlighter; use std::borrow::Cow; -/// VQL keywords that are highlighted in blue/bold. -const VQL_KEYWORDS: &[&str] = &[ +/// VCL keywords that are highlighted in blue/bold. +const VCL_KEYWORDS: &[&str] = &[ "SELECT", "FROM", "WHERE", @@ -67,10 +67,10 @@ const VQL_KEYWORDS: &[&str] = &[ "DISTINCT", ]; -/// VQL modality names highlighted in green. +/// VCL modality names highlighted in green. /// All 8 octad modalities: Graph, Vector, Tensor, Semantic, Document, Temporal, /// Provenance, Spatial. -const VQL_MODALITIES: &[&str] = &[ +const VCL_MODALITIES: &[&str] = &[ "GRAPH", "VECTOR", "TENSOR", @@ -81,18 +81,18 @@ const VQL_MODALITIES: &[&str] = &[ "SPATIAL", ]; -/// Syntax highlighter for VQL input lines. +/// Syntax highlighter for VCL input lines. /// /// This is used by the rustyline `Editor` to provide real-time syntax /// colouring as the user types queries. -pub struct VqlHighlighter; +pub struct VclHighlighter; -impl Highlighter for VqlHighlighter { +impl Highlighter for VclHighlighter { /// Highlight the input line with ANSI colour codes. /// /// The highlighting strategy is token-based: /// 1. String literals (single or double quoted) are coloured yellow. - /// 2. Tokens matching VQL keywords are coloured blue and bold. + /// 2. Tokens matching VCL keywords are coloured blue and bold. /// 3. Tokens matching modality names are coloured green and bold. /// 4. Numeric tokens are coloured cyan. /// 5. Everything else is left uncoloured. @@ -136,7 +136,7 @@ impl Highlighter for VqlHighlighter { } } -/// Apply syntax highlighting to a single line of VQL input. +/// Apply syntax highlighting to a single line of VCL input. /// /// Handles quoted strings as atomic units so that keywords inside strings /// are not incorrectly coloured. @@ -185,9 +185,9 @@ fn highlight_line(line: &str) -> String { let word: String = chars[start..i].iter().collect(); let upper = word.to_uppercase(); - if VQL_MODALITIES.contains(&upper.as_str()) { + if VCL_MODALITIES.contains(&upper.as_str()) { result.push_str(&word.green().bold().to_string()); - } else if VQL_KEYWORDS.contains(&upper.as_str()) { + } else if VCL_KEYWORDS.contains(&upper.as_str()) { result.push_str(&word.blue().bold().to_string()); } else { result.push_str(&word); @@ -233,7 +233,7 @@ mod tests { #[test] fn test_highlight_returns_something() { - let hl = VqlHighlighter; + let hl = VclHighlighter; let output = hl.highlight("SELECT FROM octad", 0); // Just verify it does not panic and returns non-empty output. assert!(!output.is_empty()); @@ -241,7 +241,7 @@ mod tests { #[test] fn test_highlight_char_always_true() { - let hl = VqlHighlighter; + let hl = VclHighlighter; assert!(hl.highlight_char("test", 0, rustyline::highlight::CmdKind::Other)); } diff --git a/rust-core/verisim-repl/src/linter.rs b/rust-core/verisim-repl/src/linter.rs index 4bda148..6c9bec3 100644 --- a/rust-core/verisim-repl/src/linter.rs +++ b/rust-core/verisim-repl/src/linter.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! VQL linter — static analysis for VQL queries. +//! VCL linter — static analysis for VCL queries. //! -//! Detects common issues, antipatterns, and performance pitfalls in VQL +//! Detects common issues, antipatterns, and performance pitfalls in VCL //! queries before execution: //! //! - Missing LIMIT clause on unbounded queries @@ -54,7 +54,7 @@ pub enum LintRule { OrderByWithoutLimit, /// DELETE or UPDATE without WHERE clause. DangerousWrite, - /// VQL-DT PROOF type not recognized. + /// VCL-DT PROOF type not recognized. UnknownProofType, /// Redundant WHERE clause (always true). RedundantWhere, @@ -67,17 +67,17 @@ pub enum LintRule { impl fmt::Display for LintRule { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - LintRule::MissingLimit => write!(f, "VQL001"), - LintRule::SelectAllModalities => write!(f, "VQL002"), - LintRule::MissingProof => write!(f, "VQL003"), - LintRule::UnboundedTraverse => write!(f, "VQL004"), - LintRule::MissingThreshold => write!(f, "VQL005"), - LintRule::OrderByWithoutLimit => write!(f, "VQL006"), - LintRule::DangerousWrite => write!(f, "VQL007"), - LintRule::UnknownProofType => write!(f, "VQL008"), - LintRule::RedundantWhere => write!(f, "VQL009"), - LintRule::MultiModalityNoExplain => write!(f, "VQL010"), - LintRule::FederationWithoutStore => write!(f, "VQL011"), + LintRule::MissingLimit => write!(f, "VCL001"), + LintRule::SelectAllModalities => write!(f, "VCL002"), + LintRule::MissingProof => write!(f, "VCL003"), + LintRule::UnboundedTraverse => write!(f, "VCL004"), + LintRule::MissingThreshold => write!(f, "VCL005"), + LintRule::OrderByWithoutLimit => write!(f, "VCL006"), + LintRule::DangerousWrite => write!(f, "VCL007"), + LintRule::UnknownProofType => write!(f, "VCL008"), + LintRule::RedundantWhere => write!(f, "VCL009"), + LintRule::MultiModalityNoExplain => write!(f, "VCL010"), + LintRule::FederationWithoutStore => write!(f, "VCL011"), } } } @@ -131,7 +131,7 @@ impl fmt::Display for LintDiagnostic { } } -/// VQL modality names — all 8 octad modalities. +/// VCL modality names — all 8 octad modalities. const MODALITIES: &[&str] = &[ "GRAPH", "VECTOR", @@ -143,7 +143,7 @@ const MODALITIES: &[&str] = &[ "SPATIAL", ]; -/// Known VQL-DT proof types. +/// Known VCL-DT proof types. const KNOWN_PROOF_TYPES: &[&str] = &[ "EXISTENCE", "CONSISTENCY", @@ -156,7 +156,7 @@ const KNOWN_PROOF_TYPES: &[&str] = &[ "PLONK", ]; -/// Lint a VQL query string and return diagnostics. +/// Lint a VCL query string and return diagnostics. /// /// This performs token-level analysis (not full parsing) to detect common /// issues. For full AST-based linting, the LSP will use the ReScript parser. @@ -182,7 +182,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { let has_store = tokens.contains(&"STORE"); let has_semantic = tokens.contains(&"SEMANTIC"); - // VQL001: Missing LIMIT on SELECT + // VCL001: Missing LIMIT on SELECT if is_select && !has_limit && !is_explain { diagnostics.push(LintDiagnostic { rule: LintRule::MissingLimit, @@ -192,7 +192,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL002: SELECT all modalities + // VCL002: SELECT all modalities if is_select { let modality_count = MODALITIES.iter().filter(|m| tokens.contains(m)).count(); if modality_count >= 8 { @@ -205,7 +205,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { } } - // VQL003: Semantic without PROOF + // VCL003: Semantic without PROOF if has_semantic && !has_proof && is_select { diagnostics.push(LintDiagnostic { rule: LintRule::MissingProof, @@ -215,7 +215,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL004: TRAVERSE without DEPTH + // VCL004: TRAVERSE without DEPTH if has_traverse && !has_depth { diagnostics.push(LintDiagnostic { rule: LintRule::UnboundedTraverse, @@ -225,7 +225,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL005: DRIFT/CONSISTENCY without THRESHOLD + // VCL005: DRIFT/CONSISTENCY without THRESHOLD if has_drift && !has_threshold { diagnostics.push(LintDiagnostic { rule: LintRule::MissingThreshold, @@ -238,7 +238,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL006: ORDER BY without LIMIT + // VCL006: ORDER BY without LIMIT if has_order && !has_limit && is_select { diagnostics.push(LintDiagnostic { rule: LintRule::OrderByWithoutLimit, @@ -248,7 +248,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL007: Dangerous write without WHERE + // VCL007: Dangerous write without WHERE if (is_delete || is_update) && !has_where { diagnostics.push(LintDiagnostic { rule: LintRule::DangerousWrite, @@ -258,7 +258,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { }); } - // VQL008: Unknown proof type + // VCL008: Unknown proof type if has_proof { if let Some(proof_pos) = tokens.iter().position(|t| *t == "PROOF") { if let Some(proof_type) = tokens.get(proof_pos + 1) { @@ -278,7 +278,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { } } - // VQL009: Redundant WHERE (WHERE 1=1, WHERE TRUE) + // VCL009: Redundant WHERE (WHERE 1=1, WHERE TRUE) if has_where { let where_pos = upper.find("WHERE").unwrap_or(0); let after_where = &upper[where_pos + 5..].trim_start(); @@ -295,7 +295,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { } } - // VQL010: Multi-modality without EXPLAIN + // VCL010: Multi-modality without EXPLAIN if is_select && !is_explain { let modality_count = MODALITIES.iter().filter(|m| tokens.contains(m)).count(); if modality_count >= 3 { @@ -308,7 +308,7 @@ pub fn lint_query(query: &str) -> Vec<LintDiagnostic> { } } - // VQL011: FEDERATION without STORE + // VCL011: FEDERATION without STORE if has_federation && !has_store { diagnostics.push(LintDiagnostic { rule: LintRule::FederationWithoutStore, @@ -556,7 +556,7 @@ mod tests { fn test_format_diagnostics_output() { let diagnostics = lint_query("DELETE FROM OCTAD"); let output = format_diagnostics("DELETE FROM OCTAD", &diagnostics); - assert!(output.contains("VQL007")); + assert!(output.contains("VCL007")); assert!(output.contains("error")); } diff --git a/rust-core/verisim-repl/src/main.rs b/rust-core/verisim-repl/src/main.rs index 4324c8d..a6c44f8 100644 --- a/rust-core/verisim-repl/src/main.rs +++ b/rust-core/verisim-repl/src/main.rs @@ -1,10 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! VQL REPL — Interactive query shell for VeriSimDB. +//! VCL REPL — Interactive query shell for VeriSimDB. //! //! Provides a readline-based interactive shell with: -//! - VQL syntax highlighting +//! - VCL syntax highlighting //! - Tab completion for keywords, modalities, and meta-commands //! - Multiline query support (backslash continuation) //! - Multiple output formats (table, JSON, CSV) @@ -18,7 +18,7 @@ mod completer; mod formatter; mod highlighter; pub mod linter; -pub mod vql_fmt; +pub mod vcl_fmt; use clap::Parser; use colored::Colorize; @@ -30,7 +30,7 @@ use rustyline::validate::MatchingBracketValidator; use rustyline_derive::{Completer, Helper, Highlighter, Hinter, Validator}; use std::time::Instant; -use client::VqlClient; +use client::VclClient; use formatter::{format_value, OutputFormat}; /// VeriSimDB version string, pulled from Cargo.toml at compile time. @@ -40,9 +40,9 @@ const VERSION: &str = env!("CARGO_PKG_VERSION"); // CLI argument parsing // --------------------------------------------------------------------------- -/// VQL — Interactive query shell for VeriSimDB. +/// VCL — Interactive query shell for VeriSimDB. #[derive(Parser, Debug)] -#[command(name = "vql", version = VERSION, about = "VQL REPL for VeriSimDB")] +#[command(name = "vcl", version = VERSION, about = "VCL REPL for VeriSimDB")] struct Cli { /// Hostname or IP of the verisim-api server. #[arg(long, default_value = "localhost")] @@ -64,11 +64,11 @@ struct Cli { /// Combined helper that provides highlighting, completion, hinting, and /// bracket validation for the rustyline editor. #[derive(Helper, Highlighter, Completer, Hinter, Validator)] -struct VqlHelper { +struct VclHelper { #[rustyline(Highlighter)] - highlighter: highlighter::VqlHighlighter, + highlighter: highlighter::VclHighlighter, #[rustyline(Completer)] - completer: completer::VqlCompleter, + completer: completer::VclCompleter, #[rustyline(Hinter)] hinter: HistoryHinter, #[rustyline(Validator)] @@ -82,7 +82,7 @@ struct VqlHelper { /// Mutable session state for the REPL loop. struct Session { /// HTTP client for the verisim-api server. - client: VqlClient, + client: VclClient, /// Current output format. format: OutputFormat, /// Whether to display query timing after each result. @@ -93,7 +93,7 @@ impl Session { /// Create a new session from CLI arguments. fn new(host: &str, port: u16, format: OutputFormat) -> Self { let base_url = format!("http://{host}:{port}"); - let client = VqlClient::new(&base_url); + let client = VclClient::new(&base_url); Self { client, format, @@ -108,7 +108,7 @@ impl Session { } else { format!("http://{addr}") }; - self.client = VqlClient::new(&base_url); + self.client = VclClient::new(&base_url); println!("Connected to {}", self.client.base_url()); } } @@ -131,31 +131,31 @@ fn main() { print_banner(&session); // Set up readline editor with helper. - let helper = VqlHelper { - highlighter: highlighter::VqlHighlighter, - completer: completer::VqlCompleter, + let helper = VclHelper { + highlighter: highlighter::VclHighlighter, + completer: completer::VclCompleter, hinter: HistoryHinter::new(), validator: MatchingBracketValidator::new(), }; - let mut editor = rustyline::Editor::<VqlHelper, DefaultHistory>::new() + let mut editor = rustyline::Editor::<VclHelper, DefaultHistory>::new() .expect("failed to create readline editor"); editor.set_helper(Some(helper)); editor.set_auto_add_history(true); - // Load history from ~/.vql_history (ignore errors on first run). + // Load history from ~/.vcl_history (ignore errors on first run). let history_path = history_file_path(); let _ = editor.load_history(&history_path); - // Load .vqlrc from home directory if present. - load_vqlrc(&mut session); + // Load .vclrc from home directory if present. + load_vclrc(&mut session); // Main REPL loop. let mut query_buf = String::new(); loop { let prompt = if query_buf.is_empty() { - format!("{} ", "vql>".bright_green().bold()) + format!("{} ", "vcl>".bright_green().bold()) } else { format!("{} ", " ..".bright_green()) }; @@ -200,7 +200,7 @@ fn main() { continue; } - // Single-line VQL query. + // Single-line VCL query. // Strip trailing semicolons (SQL habit). let query = trimmed.trim_end_matches(';'); execute_query(&mut session, query); @@ -234,7 +234,7 @@ fn main() { // Query execution // --------------------------------------------------------------------------- -/// Send a VQL query to the server and display the result. +/// Send a VCL query to the server and display the result. fn execute_query(session: &mut Session, query: &str) { if query.is_empty() { return; @@ -294,7 +294,7 @@ fn handle_meta_command(session: &mut Session, line: &str) -> bool { } "\\explain" => { if arg.is_empty() { - println!("Usage: \\explain <VQL query>"); + println!("Usage: \\explain <VCL query>"); } else { explain_query(session, arg); } @@ -384,18 +384,18 @@ fn check_status(session: &Session) { } // --------------------------------------------------------------------------- -// .vqlrc loading +// .vclrc loading // --------------------------------------------------------------------------- -/// Load and execute commands from `~/.vqlrc` if the file exists. +/// Load and execute commands from `~/.vclrc` if the file exists. /// /// Each non-empty, non-comment line in the file is treated as either a -/// meta-command or a VQL query (same as typing it at the prompt). -fn load_vqlrc(session: &mut Session) { +/// meta-command or a VCL query (same as typing it at the prompt). +fn load_vclrc(session: &mut Session) { let Some(home) = dirs::home_dir() else { return; }; - let rc_path = home.join(".vqlrc"); + let rc_path = home.join(".vclrc"); if !rc_path.exists() { return; } @@ -412,7 +412,7 @@ fn load_vqlrc(session: &mut Session) { if trimmed.starts_with('\\') { handle_meta_command(session, trimmed); } else { - // Execute as VQL query (silently, during startup). + // Execute as VCL query (silently, during startup). let _ = session.client.execute(trimmed); } } @@ -422,11 +422,11 @@ fn load_vqlrc(session: &mut Session) { // History file path // --------------------------------------------------------------------------- -/// Determine the history file path (~/.vql_history). +/// Determine the history file path (~/.vcl_history). fn history_file_path() -> std::path::PathBuf { dirs::home_dir() .unwrap_or_else(|| std::path::PathBuf::from(".")) - .join(".vql_history") + .join(".vcl_history") } // --------------------------------------------------------------------------- @@ -436,7 +436,7 @@ fn history_file_path() -> std::path::PathBuf { /// Print the welcome banner. fn print_banner(session: &Session) { println!(); - println!("{}", " VeriSimDB VQL REPL".bright_cyan().bold()); + println!("{}", " VeriSimDB VCL REPL".bright_cyan().bold()); println!(" {} {}", "Version:".dimmed(), VERSION); println!(" {} {}", "Server: ".dimmed(), session.client.base_url()); println!(" {} {}", "Format: ".dimmed(), session.format); @@ -452,7 +452,7 @@ fn print_banner(session: &Session) { /// Print the help text for meta-commands. fn print_help() { println!(); - println!("{}", " VQL Meta-Commands".bright_cyan().bold()); + println!("{}", " VCL Meta-Commands".bright_cyan().bold()); println!(); println!( " {} Change server connection", @@ -485,7 +485,7 @@ fn print_help() { println!(); println!("{}", " Query Input".bright_cyan().bold()); println!(); - println!(" Enter VQL queries at the prompt. End with Enter to execute."); + println!(" Enter VCL queries at the prompt. End with Enter to execute."); println!(" Use \\ at end of line for multiline continuation."); println!(" Trailing semicolons are stripped automatically."); println!(); diff --git a/rust-core/verisim-repl/src/vql_fmt.rs b/rust-core/verisim-repl/src/vcl_fmt.rs similarity index 90% rename from rust-core/verisim-repl/src/vql_fmt.rs rename to rust-core/verisim-repl/src/vcl_fmt.rs index 9fb6d96..d4bef23 100644 --- a/rust-core/verisim-repl/src/vql_fmt.rs +++ b/rust-core/verisim-repl/src/vcl_fmt.rs @@ -1,16 +1,16 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> //! -//! VQL query formatter. +//! VCL query formatter. //! -//! Provides canonical formatting for VQL queries: +//! Provides canonical formatting for VCL queries: //! - Keywords uppercased //! - Consistent indentation for clauses //! - Normalized whitespace //! - Aligned modality lists -/// VQL keywords that should be uppercased. -const VQL_KEYWORDS: &[&str] = &[ +/// VCL keywords that should be uppercased. +const VCL_KEYWORDS: &[&str] = &[ "SELECT", "FROM", "WHERE", @@ -67,10 +67,10 @@ const VQL_KEYWORDS: &[&str] = &[ "ANALYZE", ]; -/// VQL modality names that should be uppercased. +/// VCL modality names that should be uppercased. /// All 8 octad modalities: Graph, Vector, Tensor, Semantic, Document, Temporal, /// Provenance, Spatial. -const VQL_MODALITIES: &[&str] = &[ +const VCL_MODALITIES: &[&str] = &[ "GRAPH", "VECTOR", "TENSOR", @@ -87,7 +87,7 @@ const CLAUSE_STARTERS: &[&str] = &[ "SET", "INTO", "VALUES", "TRAVERSE", "PROOF", "EXPLAIN", ]; -/// Format a VQL query string into canonical form. +/// Format a VCL query string into canonical form. /// /// Applies: /// 1. Keyword uppercasing @@ -95,7 +95,7 @@ const CLAUSE_STARTERS: &[&str] = &[ /// 3. Clause-level newlines and indentation /// 4. Whitespace normalization /// 5. String literal preservation -pub fn format_vql(query: &str) -> String { +pub fn format_vcl(query: &str) -> String { let tokens = tokenize(query); let formatted_tokens = uppercase_keywords(&tokens); let indented = indent_clauses(&formatted_tokens); @@ -103,7 +103,7 @@ pub fn format_vql(query: &str) -> String { } /// Compact format — normalize whitespace and case without indentation. -pub fn format_vql_compact(query: &str) -> String { +pub fn format_vcl_compact(query: &str) -> String { let tokens = tokenize(query); let formatted = uppercase_keywords(&tokens); let mut result = String::with_capacity(query.len()); @@ -150,7 +150,7 @@ pub fn format_vql_compact(query: &str) -> String { result.trim().to_string() } -/// Token types in VQL input. +/// Token types in VCL input. #[derive(Debug, Clone, PartialEq)] enum Token { Keyword(String), @@ -162,7 +162,7 @@ enum Token { Punctuation(char), } -/// Tokenize VQL input into a sequence of tokens. +/// Tokenize VCL input into a sequence of tokens. /// /// Preserves string literals as atomic units. fn tokenize(input: &str) -> Vec<Token> { @@ -252,9 +252,9 @@ fn uppercase_keywords(tokens: &[Token]) -> Vec<Token> { .map(|t| match t { Token::Word(w) => { let upper = w.to_uppercase(); - if VQL_KEYWORDS.contains(&upper.as_str()) { + if VCL_KEYWORDS.contains(&upper.as_str()) { Token::Keyword(upper) - } else if VQL_MODALITIES.contains(&upper.as_str()) { + } else if VCL_MODALITIES.contains(&upper.as_str()) { Token::Modality(upper) } else { Token::Word(w.clone()) @@ -356,7 +356,7 @@ mod tests { #[test] fn test_keyword_uppercasing() { let input = "select graph from octad where id = 'abc'"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("SELECT")); assert!(output.contains("GRAPH")); assert!(output.contains("FROM")); @@ -367,7 +367,7 @@ mod tests { #[test] fn test_modality_uppercasing() { let input = "select vector, tensor from octad"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("VECTOR")); assert!(output.contains("TENSOR")); } @@ -375,14 +375,14 @@ mod tests { #[test] fn test_string_literals_preserved() { let input = "select graph from octad where name = 'hello world'"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("'hello world'")); } #[test] fn test_clause_newlines() { let input = "SELECT GRAPH FROM OCTAD WHERE id = 'abc' LIMIT 10"; - let output = format_vql(input); + let output = format_vcl(input); // FROM should be on a new line assert!(output.contains("\nFROM")); // WHERE should be on a new line @@ -394,7 +394,7 @@ mod tests { #[test] fn test_and_or_indentation() { let input = "SELECT GRAPH FROM OCTAD WHERE a = 1 AND b = 2 OR c = 3"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("\n AND")); assert!(output.contains("\n OR")); } @@ -402,21 +402,21 @@ mod tests { #[test] fn test_compact_format() { let input = " select graph from octad "; - let output = format_vql_compact(input); + let output = format_vcl_compact(input); assert_eq!(output, "SELECT GRAPH FROM OCTAD"); } #[test] fn test_whitespace_normalization() { let input = "SELECT GRAPH FROM OCTAD"; - let compact = format_vql_compact(input); + let compact = format_vcl_compact(input); assert_eq!(compact, "SELECT GRAPH FROM OCTAD"); } #[test] fn test_number_preservation() { let input = "select graph from octad limit 42 offset 10"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("42")); assert!(output.contains("10")); } @@ -424,7 +424,7 @@ mod tests { #[test] fn test_mixed_case_keywords() { let input = "Select Graph From Octad Where Id = 'test'"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("SELECT")); assert!(output.contains("GRAPH")); assert!(output.contains("FROM")); @@ -435,14 +435,14 @@ mod tests { #[test] fn test_non_keyword_preserved() { let input = "SELECT graph FROM octad WHERE entity_name = 'test'"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("entity_name")); } #[test] fn test_explain_select_same_line() { let input = "explain select graph from octad"; - let output = format_vql(input); + let output = format_vcl(input); // EXPLAIN and SELECT should stay on the same line let first_line = output.lines().next().unwrap(); assert!(first_line.contains("EXPLAIN")); @@ -451,8 +451,8 @@ mod tests { #[test] fn test_empty_input() { - assert_eq!(format_vql(""), ""); - assert_eq!(format_vql_compact(""), ""); + assert_eq!(format_vcl(""), ""); + assert_eq!(format_vcl_compact(""), ""); } #[test] @@ -469,7 +469,7 @@ mod tests { #[test] fn test_traverse_depth_formatting() { let input = "select graph from octad traverse relates_to depth 3"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("TRAVERSE")); assert!(output.contains("DEPTH")); assert!(output.contains("3")); @@ -478,7 +478,7 @@ mod tests { #[test] fn test_proof_clause_formatting() { let input = "select semantic from octad proof existence threshold 0.95"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("SEMANTIC")); assert!(output.contains("PROOF")); assert!(output.contains("THRESHOLD")); @@ -488,14 +488,14 @@ mod tests { #[test] fn test_comma_spacing() { let input = "select graph , vector , tensor from octad"; - let compact = format_vql_compact(input); + let compact = format_vcl_compact(input); assert!(compact.contains("GRAPH, VECTOR, TENSOR")); } #[test] fn test_federation_formatting() { let input = "select graph from federation store 'remote-1' octad"; - let output = format_vql(input); + let output = format_vcl(input); assert!(output.contains("FEDERATION")); assert!(output.contains("STORE")); assert!(output.contains("'remote-1'")); @@ -504,8 +504,8 @@ mod tests { #[test] fn test_roundtrip_idempotent() { let input = "SELECT GRAPH\nFROM OCTAD\nWHERE id = 'abc'\nLIMIT 10"; - let first = format_vql(input); - let second = format_vql(&first); + let first = format_vcl(input); + let second = format_vcl(&first); assert_eq!(first, second, "Formatting should be idempotent"); } } diff --git a/rust-core/verisim-semantic/src/circuit_compiler.rs b/rust-core/verisim-semantic/src/circuit_compiler.rs index cfcbade..702806a 100644 --- a/rust-core/verisim-semantic/src/circuit_compiler.rs +++ b/rust-core/verisim-semantic/src/circuit_compiler.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: MPL-2.0 //! Circuit Compiler for VeriSimDB //! -//! Compiles circuit definitions from the VQL DSL into R1CS constraint systems +//! Compiles circuit definitions from the VCL DSL into R1CS constraint systems //! suitable for verification. Circuits are parameterizable at runtime via -//! VQL `WITH (param=value, ...)` clauses. +//! VCL `WITH (param=value, ...)` clauses. use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -43,7 +43,7 @@ pub struct CircuitDef { pub wires: Vec<WireDef>, /// Gate definitions pub gates: Vec<GateDef>, - /// Parameter names (filled from VQL WITH clause at runtime) + /// Parameter names (filled from VCL WITH clause at runtime) pub parameters: Vec<String>, } diff --git a/rust-core/verisim-semantic/src/circuit_registry.rs b/rust-core/verisim-semantic/src/circuit_registry.rs index be8def8..5daf6a2 100644 --- a/rust-core/verisim-semantic/src/circuit_registry.rs +++ b/rust-core/verisim-semantic/src/circuit_registry.rs @@ -2,7 +2,7 @@ //! Circuit Registry for VeriSimDB ZKP Custom Circuits //! //! In-memory registry mapping circuit names to compiled verification functions. -//! Custom circuits allow VQL queries to include `PROOF CUSTOM "circuit-name" +//! Custom circuits allow VCL queries to include `PROOF CUSTOM "circuit-name" //! WITH (param=value, ...)` clauses that verify application-specific properties. use serde::{Deserialize, Serialize}; diff --git a/rust-core/verisim-semantic/src/zkp_bridge.rs b/rust-core/verisim-semantic/src/zkp_bridge.rs index 69c1b5c..7474a2e 100644 --- a/rust-core/verisim-semantic/src/zkp_bridge.rs +++ b/rust-core/verisim-semantic/src/zkp_bridge.rs @@ -20,7 +20,7 @@ //! # Architecture //! //! ```text -//! VQL PROOF clause → Elixir executor → Rust API → ZkpBridge +//! VCL PROOF clause → Elixir executor → Rust API → ZkpBridge //! │ //! ┌───────────────────────────────┘ //! │ diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 0b0675b..3d6222e 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MPL-2.0 //! Integration Tests for VeriSimDB //! -//! Tests the full stack: Rust stores → HTTP API → Elixir orchestration → VQL +//! Tests the full stack: Rust stores → HTTP API → Elixir orchestration → VCL use verisim_api::{ApiConfig, ConcreteOctadStore}; use verisim_document::{Document, TantivyDocumentStore}; @@ -295,7 +295,7 @@ async fn test_multi_modal_query() { let octad_id = store.create(input).await.unwrap(); // Query combining text search, vector similarity, and semantic types - // In full implementation, would use VQL multi-modal query + // In full implementation, would use VCL multi-modal query } #[tokio::test]