diff --git a/gridverse/dsl.py b/gridverse/dsl.py new file mode 100644 index 0000000..b04e2c5 --- /dev/null +++ b/gridverse/dsl.py @@ -0,0 +1,77 @@ +from __future__ import annotations + +"""Tiny DSL sketch and helper to bootstrap GridVerse DSL usage. + +This module provides a minimal, safe path to convert a small, human-friendly + DSL into GridVerse canonical contracts via the existing bridge helpers. The + goal is to enable rapid prototyping of cross-domain problems without touching + the solver or registry code. +""" + +from typing import Any, Dict +import re + +from gridverse.core_contracts import LocalProblem, SharedVariables +from gridverse.bridge_energia import to_canonical, CanonicalBundle + + +def _parse_value(v: str) -> Any: + v = v.strip() + if v.lower() in {"true", "false"}: + return v.lower() == "true" + if v.isdigit(): + return int(v) + try: + return float(v) + except ValueError: + return v + + +def _parse_variables(part: str) -> Dict[str, Any]: + result: Dict[str, Any] = {} + # allow comma or semicolon separated entries + items = [p for p in re.split(r"[,;]", part) if p.strip()] + for item in items: + if "=" in item: + k, v = item.split("=", 1) + result[k.strip()] = _parse_value(v.strip()) + return result + + +def parse_local_problem_from_dsl(text: str) -> LocalProblem: + # Very small DSL format (case-sensitive for simplicity): + # site_id= + # description= + # variables==,=;... + site_id = "dsl_site" + description = "Parsed from DSL" + variables: Dict[str, Any] = {} + + for line in text.splitlines(): + line = line.strip() + if not line: + continue + if line.startswith("site_id="): + site_id = line.split("=", 1)[1].strip() + elif line.startswith("description="): + description = line.split("=", 1)[1].strip() + elif line.startswith("variables="): + var_part = line.split("=", 1)[1].strip() + variables = _parse_variables(var_part) + + return LocalProblem(site_id=site_id, description=description, variables=variables) + + +def dsl_to_canonical_bundle(text: str, version: str | None = None) -> CanonicalBundle: + """Convert a tiny DSL snippet into a CanonicalBundle via the bridge. + + The function produces a minimal canon bundle with the parsed LocalProblem and + an empty SharedVariables payload. It is intentionally lightweight and + suitable for bootstrapping demos. + """ + lp = parse_local_problem_from_dsl(text) + lp_dict = lp.to_dict() + sv = SharedVariables(signals={}, version=1) + sv_dict = sv.to_dict() + plan_delta: Dict[str, Any] = {} + return to_canonical(lp_dict, sv_dict, plan_delta, version) diff --git a/gridverse/dsl_sketch.md b/gridverse/dsl_sketch.md new file mode 100644 index 0000000..2a9b2e4 --- /dev/null +++ b/gridverse/dsl_sketch.md @@ -0,0 +1,24 @@ +# GridVerse DSL Sketch (Conceptual) + +This document outlines a tiny, human-friendly DSL to describe a LocalProblem +and its associated SharedVariables that GridVerse adapters will map into a +canonical bundle for cross-domain optimization. + +Core concepts +- LocalProblem (Objects): a local optimization task at a site with a set of + tunable variables. +- SharedVariables (Morphisms): signals exchanged with other sites or global + constraints. +- PlanDelta: incremental actions derived from solving the local/global problem. +- Governance/Audit: lightweight metadata for traceability (version/timestamp). + +Tiny DSL example +site_id=siteA +description=DER and building load coordination +variables=pv_capacity=5,load=10,storage=2 +variables=another_key=42 + +Notes +- This DSL is intentionally minimal to bootstrap interoperability without + introducing a full language runtime. +- A real system would support richer types, validation, and versioning hooks.