78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
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=<id>
|
|
# description=<description>
|
|
# variables=<k1>=<v1>,<k2>=<v2>;...
|
|
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)
|