Skip to content

Latest commit

 

History

History
1533 lines (1256 loc) · 46.4 KB

File metadata and controls

1533 lines (1256 loc) · 46.4 KB

FROG logo

🐸 FROG Diagram Specification

Definition of executable graphs in .frog programs
FROG — Free Open Graphical Language


Contents


1. Overview

The diagram section defines the executable graph of a FROG. It is the authoritative structural representation of that graph in canonical source form.

A FROG executable unit behaves conceptually like a graphical dataflow program with a public interface, an internal executable graph, optional front-panel widget participation, and optional nested language structures. In canonical source form, the diagram is the authoritative representation of that executable graph.

The diagram contains:

  • the nodes representing executable or structurally meaningful graph elements,
  • the edges representing directed connectivity between ports,
  • the canonical graph-level participation of public interface ports,
  • the canonical graph-level participation of widget values and widget references,
  • the invocation sites of other FROGs,
  • the explicit local-memory elements required for valid feedback,
  • the source-level annotations used for documentation and editor organization.

Interpretation of a validated diagram depends on additional specifications, including:

  • the public interface contract,
  • the FROG type system,
  • the widget model,
  • the widget interaction model,
  • the normative control-structure semantics,
  • the normative local-memory and cycle-validity rules,
  • the active primitive catalog or stricter execution profile.

This document defines the graph-level source representation itself. It does not own the full execution semantics of every graph element.

This document also does not own repository-wide version policy. Top-level spec_version identifies the source-format compatibility target of the containing .frog file, while published specification corpus versioning remains governed centrally in Versioning/Readme.md.


2. Purpose of the Diagram

The diagram provides:

  • the executable logic graph of the FROG,
  • the canonical dependency graph of values and explicit effects,
  • the canonical link between public interface ports and internal execution logic,
  • the canonical link between front-panel widget participation and internal execution logic,
  • the hierarchical composition mechanism used to invoke other FROGs,
  • the canonical place where valid feedback loops and explicit local memory are represented in source form,
  • the canonical source-level space for diagram annotations and organization.

The diagram MUST be sufficient to determine the executable graph shape of the FROG. Other sections may define semantics needed to interpret that graph, but they do not replace the graph itself.


3. Relation with Other Specifications

This document depends on the following FROG specifications:

  • Expression/Readme.md — defines the role of Expression/ as the canonical source-specification layer,
  • Expression/Type.md — ordinary value typing and compatibility rules,
  • Expression/Interface.md — public interface declaration and public boundary semantics,
  • Expression/Front panel.md — serialized UI composition and widget declarations,
  • Expression/Widget.md — widget classes, primary value model, and widget parts,
  • Expression/Widget interaction.md — object-style widget interaction primitives and optional UI sequencing,
  • Expression/Control structures.md — source-facing representation of structure nodes and their serialized form,
  • Expression/State and cycles.md — source-facing representation of explicit local-memory elements and feedback-cycle formation constraints,
  • Language/Readme.md — defines the role of Language/ as the normative execution-semantics layer,
  • Language/Control structures.md — normative execution semantics for structure families such as case, for_loop, and while_loop,
  • Language/State and cycles.md — normative semantics for local memory and cycle validity,
  • Libraries/Core.md — standard primitive definitions such as frog.core.add, frog.core.mul, and frog.core.delay,
  • Libraries/UI.md — standard executable UI primitive definitions such as frog.ui.property_read, frog.ui.property_write, and frog.ui.method_invoke,
  • Versioning/Readme.md — centralized distinction between specification corpus version, top-level spec_version, and program artifact versioning.

This document defines graph-level representation and validation rules. It does not redefine source ownership or execution semantics already owned by the dedicated specifications above.


4. Location in a .frog File

The diagram appears as a top-level object in the canonical .frog source file.

{
  "spec_version": "0.1",
  "metadata": {},
  "interface": {},
  "connector": {},
  "diagram": {},
  "front_panel": {}
}

The diagram section MUST exist in a canonical .frog source file.

In this source shape:

  • top-level spec_version identifies the source-format compatibility target of the file,
  • diagram defines the authoritative executable graph in canonical source,
  • the repository-wide specification corpus version remains governed centrally in Versioning/Readme.md.

5. Diagram Structure

The diagram object contains up to four fields:

"diagram": {
  "nodes": [],
  "edges": [],
  "dependencies": [],
  "annotations": []
}

Fields:

  • nodes — required array of graph nodes,
  • edges — required array of directed graph connections,
  • dependencies — optional array of referenced external FROGs,
  • annotations — optional array of visible diagram annotations.

Rules:

  • nodes MUST exist and MUST be an array.
  • edges MUST exist and MUST be an array.
  • dependencies MAY be omitted when unused.
  • annotations MAY be omitted when unused.

The annotations field belongs to canonical source because it expresses author-created documentation and visible organization of the diagram. It MUST NOT affect execution semantics.

Diagram objects such as nodes, edges, structure regions, and annotations MAY be referenced by source provenance attestations through ide.provenance. The diagram object itself remains the executable source object; provenance evidence SHOULD be carried outside the object rather than adding mandatory signature or trust fields to every node or edge.


6. Diagram Scopes

FROG diagrams are recursive. The top-level diagram object defines the outer executable graph of the FROG. Language structures MAY own internal executable regions, and each such region contains its own local diagram scope.

Accordingly, FROG distinguishes:

  • top-level diagram scope — the outer executable graph of the FROG,
  • region-local diagram scope — a nested executable graph owned by a structure region.

Each diagram scope has its own local:

  • node identifier namespace,
  • edge identifier namespace,
  • annotation identifier namespace.

Rules defined in this document apply both to the top-level diagram and to region-local diagrams unless a structure-specific rule explicitly states otherwise.

An edge MUST connect nodes within the same diagram scope. Cross-scope communication MUST occur only through the explicit mechanisms defined by structure boundaries.


7. Conceptual Model

A validated diagram defines a directed graph whose nodes expose typed ports and whose edges connect compatible ports. The graph is structural and execution-relevant:

  • structural, because it explicitly defines graph boundaries and nesting,
  • execution-relevant, because it provides the graph form consumed by the language, primitive, and widget-interaction semantics defined elsewhere.

At conceptual level:

  • a node is a graph element that owns ports and participates in execution or graph boundaries,
  • a port is a typed participation point on a node,
  • an edge is a directed connection from one node port to another node port,
  • a diagram scope is a container of nodes, edges, and annotations with its own local namespaces.

The diagram itself does not impose a textual instruction order. The validated graph participates in execution according to dataflow, structure, local-memory, and widget-interaction semantics owned by other specifications.


8. Node Model

A node represents an executable or structurally meaningful element of the graph. Every node owns a set of input and output ports, whether those ports are declared directly in the node, derived from a referenced primitive signature, derived from a structure family, derived from an interface boundary, or derived from widget semantics.

Every node MUST define:

  • id — unique node identifier within the owning diagram scope,
  • kind — node category.

A node MAY also define:

  • layout — graphical editor position and size metadata,
  • doc — optional structured documentation,
  • tags — optional structured tags,
  • kind-specific fields defined by this document or by a referenced specification.

8.1 Common node shape

{
  "id": "node_1",
  "kind": "primitive",
  "type": "frog.core.add",
  "layout": {
    "x": 120,
    "y": 80
  }
}

Nodes are structural objects. Their valid ports are resolved from:

  • their kind,
  • their kind-specific metadata,
  • the active primitive catalog or structure family definition,
  • other referenced specifications when applicable.

Rules:

  • Node identifiers MUST be unique within the owning diagram scope.
  • Node identifiers MAY be reused in different nested scopes.
  • A node MUST NOT expose hidden semantically required ports outside the canonical resolution rules of its kind.

9. Standard Node Kinds for v0.1

FROG v0.1 defines the following standard node kinds:

  • primitive
  • structure
  • subfrog
  • interface_input
  • interface_output
  • widget_value
  • widget_reference

9.1 primitive

A primitive node represents a built-in or profile-defined executable primitive.

{
  "id": "mul_1",
  "kind": "primitive",
  "type": "frog.core.mul",
  "layout": {
    "x": 240,
    "y": 120
  }
}

Rules:

  • type MUST exist.
  • type MUST identify a valid primitive in the active catalog or profile.
  • Primitive identifiers SHOULD use canonical namespaces such as frog.core.*, frog.ui.*, or another standardized library namespace.
  • Primitive meaning and port signature are defined by the referenced primitive definition.

Primitive nodes include ordinary computational functions, widget interaction primitives, and local-memory primitives such as frog.core.delay.

9.2 structure

A structure node represents a language-level control structure. Its canonical source representation is defined by Expression/Control structures.md. Its normative execution semantics are defined by Language/Control structures.md.

{
  "id": "case_1",
  "kind": "structure",
  "structure_type": "case",
  "boundary": {
    "inputs": [],
    "outputs": []
  },
  "structure_terminals": {},
  "regions": [],
  "layout": {
    "x": 300,
    "y": 120,
    "width": 260,
    "height": 180
  }
}

Rules:

  • structure_type MUST exist.
  • structure_type MUST identify a valid standardized or profile-defined structure family.
  • The canonical standardized structure types for v0.1 are case, for_loop, and while_loop.
  • boundary, structure_terminals, and regions MUST be valid for the chosen structure type.
  • Structure internals and region representation MUST remain aligned with the control-structure specifications and MUST NOT be redefined ad hoc by tools.

There is no separate canonical if structure in v0.1. Boolean conditional branching is represented canonically as case with selector type bool.

9.3 subfrog

A subfrog node represents an invocation of another FROG.

{
  "id": "math_add_1",
  "kind": "subfrog",
  "ref": "Math.Add",
  "layout": {
    "x": 420,
    "y": 120
  }
}

Rules:

  • ref MUST exist.
  • ref MUST match a declared dependency identifier.
  • The input and output ports of the node are derived from the referenced FROG interface.

9.4 interface_input

An interface_input node represents the entry point of a declared public interface input inside the executable graph.

{
  "id": "input_a",
  "kind": "interface_input",
  "interface_port": "a",
  "layout": {
    "x": 40,
    "y": 100
  }
}

Rules:

  • interface_port MUST exist.
  • interface_port MUST reference an existing input declared in the interface section.
  • The node exposes exactly one output port named value.

9.5 interface_output

An interface_output node represents the exit point used to drive a declared public interface output from the executable graph.

{
  "id": "output_result",
  "kind": "interface_output",
  "interface_port": "result",
  "layout": {
    "x": 760,
    "y": 100
  }
}

Rules:

  • interface_port MUST exist.
  • interface_port MUST reference an existing output declared in the interface section.
  • The node exposes exactly one input port named value.

9.6 widget_value

A widget_value node represents the natural primary-value participation of a front-panel widget in the executable graph. It materializes the canonical natural widget value path defined by Widget.md.

{
  "id": "ctrl_gain_value",
  "kind": "widget_value",
  "widget": "ctrl_gain",
  "layout": {
    "x": 100,
    "y": 220
  }
}

Rules:

  • widget MUST exist.
  • widget MUST reference an existing widget declared in the front_panel.
  • The referenced widget MUST be value-carrying.
  • The node exposes exactly one port named value.
  • If the widget role is control, the value port is an output.
  • If the widget role is indicator, the value port is an input.
  • The port type MUST equal the widget value_type.

A front-panel widget does not define a public interface port by itself. Public interface semantics remain represented canonically through interface_input and interface_output.

9.7 widget_reference

A widget_reference node represents an explicit object-style reference to a widget. It is used when the diagram needs to access widget properties, widget parts, or widget methods through the widget interaction model.

{
  "id": "ctrl_gain_ref",
  "kind": "widget_reference",
  "widget": "ctrl_gain",
  "layout": {
    "x": 80,
    "y": 300
  }
}

Rules:

  • widget MUST exist.
  • widget MUST reference an existing widget declared in the front_panel.
  • The node exposes exactly one output port named ref.
  • The ref token is an opaque widget-reference token in v0.1.

10. Port Model

FROG v0.1 does not require every node to declare an explicit ports array inside the diagram source. Instead, valid ports are resolved from the node kind and its definition source.

A port is a typed participation point on a node. A port belongs to exactly one node and has a direction relative to that node.

For v0.1, a port is characterized conceptually by:

  • its owning node,
  • its local port name,
  • its direction — input or output,
  • its type, including opaque sequencing-token or widget-reference types where applicable.

Rules:

  • A port name MUST be unique within the resolved port set of its owning node.
  • Each input port accepts at most one incoming ordinary driver edge unless a referenced primitive or structure explicitly defines otherwise.
  • An output port MAY fan out to multiple consumer ports where type and scope rules allow.

11. Port Resolution Model

Port resolution rules are:

  • primitive — ports are defined by the primitive function signature,
  • structure — ports are defined by the structure family source model, its boundary, and its outer-visible terminals,
  • subfrog — ports are derived from the referenced FROG interface,
  • interface_input — exactly one output port named value,
  • interface_output — exactly one input port named value,
  • widget_value — exactly one port named value, with direction resolved from widget role and type resolved from widget value_type,
  • widget_reference — exactly one output port named ref.

11.1 Primitive port resolution for widget interaction

For canonical diagram port resolution in v0.1, the standardized frog.ui.* primitive signatures align with Libraries/UI.md and Expression/Widget interaction.md as follows:

11.1.1 frog.ui.property_read

  • required input port: ref,
  • optional input port: ui_in,
  • required output port: value,
  • optional output port: ui_out.

The value port type is defined by the addressed widget member. The ref port is an opaque widget-reference token. The optional ui_in and ui_out ports are opaque UI sequencing ports.

11.1.2 frog.ui.property_write

  • required input port: ref,
  • required input port: value,
  • optional input port: ui_in,
  • optional output port: ui_out.

The value port type is defined by the addressed widget member. The ref port is an opaque widget-reference token. The optional ui_in and ui_out ports are opaque UI sequencing ports.

11.1.3 frog.ui.method_invoke

  • required input port: ref,
  • zero or more method parameter input ports, in canonical method order,
  • optional input port: ui_in,
  • zero or more method result output ports, in canonical method order,
  • optional output port: ui_out.

Method parameter and result ports are defined by the addressed widget or widget-part method signature. The ref port is an opaque widget-reference token. The optional ui_in and ui_out ports are opaque UI sequencing ports.

11.2 Primitive port resolution for local memory

The minimal standard local-memory primitive for v0.1 is frog.core.delay. Its canonical signature is defined by Libraries/Core.md, its source-facing constraints are defined by Expression/State and cycles.md, and its normative execution semantics are defined by Language/State and cycles.md.

For canonical diagram validation in v0.1:

  • frog.core.delay MUST define an initial field,
  • its input port in and output port out MUST have the same type,
  • the initial value MUST be type-compatible with that type.

11.3 Structure port resolution

For a structure node, visible ports are derived from the canonical source form of the referenced structure family. This includes boundary inputs, boundary outputs, selector terminals, loop count terminals, continuation terminals, loop index terminals, and other outer-visible structure-defined terminals where applicable.

11.4 Sub-FROG port resolution

For a subfrog node, ports are derived from the declared public interface of the referenced dependency.


12. Edge Model

An edge connects one output port to one input port. Edges define directed graph connectivity.

12.1 Common edge shape

{
  "id": "e1",
  "from": { "node": "input_a", "port": "value" },
  "to":   { "node": "add_1",   "port": "a" }
}

Every edge MUST define:

  • id — unique edge identifier within the owning diagram scope,
  • from.node — source node identifier,
  • from.port — source output port identifier,
  • to.node — destination node identifier,
  • to.port — destination input port identifier.

12.2 Edge validity

An edge is valid only if all of the following hold:

  • the source node exists in the same diagram scope,
  • the destination node exists in the same diagram scope,
  • the source port exists and is an output port,
  • the destination port exists and is an input port,
  • the source value type is compatible with the destination input type,
  • the connection does not violate structure-boundary rules or other dedicated specifications.

12.3 Fan-out and single-driver rule

  • An output port MAY drive multiple destination ports when type compatibility holds.
  • An input port MUST NOT have more than one incoming edge unless a stricter structure-specific rule explicitly defines otherwise.

12.4 Scope locality

An edge MUST connect nodes within the same diagram scope. Cross-scope communication MUST occur only through the explicit mechanisms defined by structure boundaries.


13. Annotations, Documentation, and Tags

13.1 Diagram annotations

Annotations are optional source-level objects used to document and visually organize the diagram. They do not participate in execution.

{
  "id": "ann_1",
  "kind": "text",
  "text": "Signal conditioning",
  "layout": {
    "x": 180,
    "y": 40,
    "width": 180,
    "height": 24
  }
}

The exact annotation vocabulary MAY be extended by editor profiles, but canonical source MUST preserve the distinction between annotations and executable nodes.

13.2 Node documentation

A node MAY define a doc object. This field is source documentation only. It MUST NOT change execution behavior.

13.3 Tags

A node MAY define a tags array. Tags MAY be used by tools for organization, search, or diagnostics, but MUST NOT alter validated execution semantics.


14. Layout Information

Layout information belongs to canonical source because FROG is a graphical language.

Typical layout fields include:

  • x,
  • y,
  • width,
  • height.

Rules:

  • Layout metadata MAY be omitted where unnecessary.
  • Layout metadata MUST NOT change validated execution semantics.
  • Structure layout MAY include size information for editor rendering.

15. FROG Dependencies

When a diagram invokes other FROGs through subfrog nodes, those external FROGs MUST be declared in diagram.dependencies.

"dependencies": [
  {
    "name": "Math.Add",
    "path": "lib/math/add.frog"
  }
]

Dependency fields:

  • name — logical identifier used by subfrog.ref,
  • path — relative path or equivalent source reference.

Rules:

  • Dependency names MUST be unique within the diagram.
  • A subfrog.ref value MUST match one declared dependency name.
  • The referenced dependency MUST resolve to a FROG whose interface can define the node boundary.

16. Sub-FROG Invocation

A subfrog node invokes another FROG as a reusable executable unit.

Its externally visible ports are derived from the referenced FROG interface:

  • each public input of the referenced FROG becomes an input port of the subfrog node,
  • each public output of the referenced FROG becomes an output port of the subfrog node.

A subfrog node MUST NOT invent a different boundary shape than the one implied by the referenced interface.


17. Interface, Widget, and Structure Boundaries

17.1 Public interface boundary

Public interface participation in the diagram is represented canonically by:

  • interface_input
  • interface_output

Conceptually:

external input  → interface_input.value   → internal graph
internal graph  → interface_output.value  → external output

A front-panel widget does not create a public interface port by itself. The front panel defines UI composition, not public API semantics.

17.2 Front-panel widget boundary

Front-panel primary-value participation is represented canonically by:

  • widget_value

Object-style widget access is represented canonically by:

  • widget_reference,
  • frog.ui.property_read,
  • frog.ui.property_write,
  • frog.ui.method_invoke.

A widget MAY expose its primary value both naturally through widget_value and as a property through the object-style path when the widget class allows it. These two paths MUST remain semantically distinct.

17.3 Structure boundary

A structure boundary is part of the executable graph representation of the program. Boundary values crossing the structure wall MUST be represented explicitly according to the control-structure model.

This document does not redefine structure-boundary internals. Their canonical source representation is defined by Expression/Control structures.md, and their normative execution meaning is defined by Language/Control structures.md.


18. Widget Interaction Model

18.1 Natural primary-value path

The natural path is:

widget instance → widget primary value → widget_value node → dataflow graph

This path SHOULD be used for ordinary control and indicator wiring.

18.2 Object-style path

The object-style path is:

widget instance → widget_reference node → frog.ui.* primitive

This path MUST be used for:

  • property reads,
  • property writes,
  • method invocation,
  • object-style access to widget parts.

18.3 Primitive-local member descriptors

For canonical diagram representation:

  • property interaction primitives MUST use widget_member,
  • method interaction primitives MUST use widget_method.

18.4 Optional UI sequencing

Widget interaction primitives MAY use optional ui_in and ui_out ports for explicit ordering of UI side effects. These sequencing ports are opaque and MUST NOT be interpreted as ordinary value ports.


19. Graph-Level Participation of Cycles and Local Memory

Cycles and explicit local memory participate in the diagram as graph-level elements. This document defines only that participation in canonical source form.

In particular:

  • directed cycles appear through ordinary graph connectivity inside a diagram scope,
  • explicit local memory appears through local-memory primitive nodes such as frog.core.delay,
  • graph-level validation of feedback paths MUST remain aligned with Expression/State and cycles.md,
  • primitive identity, required ports, and required metadata for frog.core.delay MUST remain aligned with Libraries/Core.md.

Cycle validity and local-memory semantics are defined normatively by Language/State and cycles.md. The source-facing representation of those constructs in canonical .frog content is defined by Expression/State and cycles.md. This document defines only their graph-level participation.


20. Graph Validation

A diagram is valid only if all of the following hold:

  • every node identifier is unique within its diagram scope,
  • every edge identifier is unique within its diagram scope,
  • every annotation identifier is unique within its diagram scope when annotation identifiers are present,
  • every node kind is valid,
  • every kind-specific required field is present,
  • every referenced interface port exists,
  • every referenced widget exists,
  • every referenced dependency exists,
  • every source and destination port resolves successfully,
  • every connected value edge is type-compatible,
  • every input port has at most one incoming edge unless explicitly allowed by another specification,
  • every structure boundary is valid under the control-structure specifications,
  • every widget interaction node is valid under the widget interaction and UI library specifications,
  • every feedback cycle satisfies the local-memory source rules defined by Expression/State and cycles.md,
  • layout, documentation, tags, and annotations do not conflict with executable fields.

20.1 Interface participation checks

  • Each declared interface input MUST be consumable by the graph.
  • Each declared interface output MUST be producible by the graph.
  • Canonical source SHOULD represent each declared public interface port through a dedicated matching boundary node.

20.2 Widget participation checks

  • A widget_value node MUST reference a value-carrying widget.
  • A widget_reference node MUST reference an existing widget.
  • Object-style widget interaction MUST use widget_reference plus a valid frog.ui.* primitive.

20.3 Recommended diagnostics

Validators SHOULD diagnose at least the following error classes:

  • unknown node kind,
  • duplicate node identifier,
  • duplicate edge identifier,
  • unknown port,
  • output-to-output connection,
  • input-to-input connection,
  • type incompatibility,
  • unknown interface port,
  • unknown widget,
  • unknown dependency reference,
  • invalid widget-value use on a non-value-carrying widget,
  • invalid feedback cycle without local memory,
  • missing mandatory initial on frog.core.delay.

These checks validate the graph-level source form of the artifact. They do not, by themselves, redefine top-level spec_version policy or repository-wide corpus-version governance.


21. Relation with Execution Semantics

21.1 General principle

A validated diagram is the graph-level source form consumed by execution-facing layers. This document defines that source form. It does not define the full runtime behavior of every graph element.

21.2 Interface participation

An interface_input node is the canonical graph-level representation of a public input entering the internal graph. An interface_output node is the canonical graph-level representation of a public output driven from the internal graph.

21.3 Widget participation

The natural widget path and the object-style widget path are distinct:

  • widget_value is the canonical natural representation for primary widget value participation,
  • widget_reference plus frog.ui.* primitives are the canonical object-style representation.

A widget primary value MAY be accessible through both mechanisms when the widget class allows it, but tools SHOULD preserve the distinction rather than collapsing both forms into one undifferentiated mechanism.

21.4 Structure participation

Structure nodes participate in the diagram as explicit graph objects with boundaries, terminals, and owned regions. Their runtime execution semantics are owned by Language/Control structures.md.

21.5 Local-memory participation

Local-memory nodes participate in the diagram as explicit primitive nodes in feedback-capable graph paths. Their source-facing representation is owned by Expression/State and cycles.md. Their normative execution semantics are owned by Language/State and cycles.md. Primitive-local delayed-value behavior for frog.core.delay is owned by Libraries/Core.md.

21.6 No semantic ownership in this document

This document MUST NOT be interpreted as redefining:

  • general execution readiness rules,
  • structure branch-selection or loop-iteration semantics,
  • primitive-local runtime behavior,
  • cycle-validity semantics,
  • runtime scheduling policy,
  • repository-wide version-transition law.

22. Examples

22.1 Basic public interface graph

{
  "interface": {
    "inputs": [
      { "id": "a", "type": "f64" },
      { "id": "b", "type": "f64" }
    ],
    "outputs": [
      { "id": "result", "type": "f64" }
    ]
  },
  "diagram": {
    "nodes": [
      {
        "id": "input_a",
        "kind": "interface_input",
        "interface_port": "a"
      },
      {
        "id": "input_b",
        "kind": "interface_input",
        "interface_port": "b"
      },
      {
        "id": "add_node",
        "kind": "primitive",
        "type": "frog.core.add"
      },
      {
        "id": "output_result",
        "kind": "interface_output",
        "interface_port": "result"
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "input_a", "port": "value" },
        "to":   { "node": "add_node", "port": "a" }
      },
      {
        "id": "e2",
        "from": { "node": "input_b", "port": "value" },
        "to":   { "node": "add_node", "port": "b" }
      },
      {
        "id": "e3",
        "from": { "node": "add_node", "port": "result" },
        "to":   { "node": "output_result", "port": "value" }
      }
    ]
  }
}

22.2 Natural widget-value participation

{
  "front_panel": {
    "widgets": [
      {
        "id": "ctrl_gain",
        "role": "control",
        "widget": "frog.ui.standard.numeric_control",
        "value_type": "f64"
      },
      {
        "id": "ind_result",
        "role": "indicator",
        "widget": "frog.ui.standard.numeric_indicator",
        "value_type": "f64"
      }
    ]
  },
  "diagram": {
    "nodes": [
      {
        "id": "ctrl_gain_value",
        "kind": "widget_value",
        "widget": "ctrl_gain"
      },
      {
        "id": "input_signal",
        "kind": "interface_input",
        "interface_port": "signal"
      },
      {
        "id": "mul_1",
        "kind": "primitive",
        "type": "frog.core.mul"
      },
      {
        "id": "ind_result_value",
        "kind": "widget_value",
        "widget": "ind_result"
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "input_signal", "port": "value" },
        "to":   { "node": "mul_1", "port": "a" }
      },
      {
        "id": "e2",
        "from": { "node": "ctrl_gain_value", "port": "value" },
        "to":   { "node": "mul_1", "port": "b" }
      },
      {
        "id": "e3",
        "from": { "node": "mul_1", "port": "result" },
        "to":   { "node": "ind_result_value", "port": "value" }
      }
    ]
  }
}

22.3 Object-style widget property read

{
  "diagram": {
    "nodes": [
      {
        "id": "ctrl_gain_ref",
        "kind": "widget_reference",
        "widget": "ctrl_gain"
      },
      {
        "id": "read_label_text",
        "kind": "primitive",
        "type": "frog.ui.property_read",
        "widget_member": {
          "part": "label",
          "member": "text"
        }
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "ctrl_gain_ref", "port": "ref" },
        "to":   { "node": "read_label_text", "port": "ref" }
      }
    ]
  }
}

22.4 Object-style widget property write with public input

{
  "diagram": {
    "nodes": [
      {
        "id": "status_text",
        "kind": "interface_input",
        "interface_port": "status"
      },
      {
        "id": "ctrl_gain_ref",
        "kind": "widget_reference",
        "widget": "ctrl_gain"
      },
      {
        "id": "write_label_text",
        "kind": "primitive",
        "type": "frog.ui.property_write",
        "widget_member": {
          "part": "label",
          "member": "text"
        }
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "status_text", "port": "value" },
        "to":   { "node": "write_label_text", "port": "value" }
      },
      {
        "id": "e2",
        "from": { "node": "ctrl_gain_ref", "port": "ref" },
        "to":   { "node": "write_label_text", "port": "ref" }
      }
    ]
  }
}

22.5 Valid feedback cycle with local memory

{
  "diagram": {
    "nodes": [
      {
        "id": "input_x",
        "kind": "interface_input",
        "interface_port": "x"
      },
      {
        "id": "add_1",
        "kind": "primitive",
        "type": "frog.core.add"
      },
      {
        "id": "delay_1",
        "kind": "primitive",
        "type": "frog.core.delay",
        "initial": 0.0
      },
      {
        "id": "output_y",
        "kind": "interface_output",
        "interface_port": "y"
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "input_x", "port": "value" },
        "to":   { "node": "add_1", "port": "a" }
      },
      {
        "id": "e2",
        "from": { "node": "delay_1", "port": "out" },
        "to":   { "node": "add_1", "port": "b" }
      },
      {
        "id": "e3",
        "from": { "node": "add_1", "port": "result" },
        "to":   { "node": "delay_1", "port": "in" }
      },
      {
        "id": "e4",
        "from": { "node": "add_1", "port": "result" },
        "to":   { "node": "output_y", "port": "value" }
      }
    ]
  }
}

22.6 Boolean case structure

{
  "diagram": {
    "nodes": [
      {
        "id": "input_enabled",
        "kind": "interface_input",
        "interface_port": "enabled"
      },
      {
        "id": "case_enabled",
        "kind": "structure",
        "structure_type": "case",
        "boundary": {
          "inputs": [],
          "outputs": [
            { "id": "result", "type": "f64" }
          ]
        },
        "structure_terminals": {
          "selector": {
            "type": "bool",
            "outer_visible": true,
            "exposed_in_body": false,
            "read_only": true,
            "role": "selector"
          }
        },
        "regions": [
          {
            "id": "true_case",
            "match": true,
            "diagram": {
              "nodes": [],
              "edges": []
            }
          },
          {
            "id": "false_case",
            "match": false,
            "diagram": {
              "nodes": [],
              "edges": []
            }
          }
        ]
      }
    ],
    "edges": [
      {
        "id": "e1",
        "from": { "node": "input_enabled", "port": "value" },
        "to":   { "node": "case_enabled", "port": "selector" }
      }
    ]
  }
}

This illustrates the canonical source-level replacement for a traditional if / else structure.


23. Summary

The FROG diagram is the authoritative executable graph of a FROG in canonical source form. It is the canonical place where public interface participation, widget participation, structure participation, sub-FROG invocation, explicit local memory, and graph-level documentation are represented.

  • Public interface participation is represented canonically by interface_input and interface_output.
  • Natural widget value participation is represented canonically by widget_value.
  • Object-style widget access is represented canonically by widget_reference plus frog.ui.* primitives.
  • Language structures are explicit graph nodes, not hidden function expansions.
  • Cycles and explicit local memory participate directly in the diagram graph.
  • The diagram owns graph structure representation; annotations and layout do not change execution semantics.
  • Diagram nodes, edges, regions, and annotations may be subjects of source provenance attestations, but provenance does not change graph meaning.
  • The diagram does not define source-format compatibility law or published specification corpus versioning.

This keeps FROG understandable as a graphical dataflow language while remaining explicit, canonical, and durable as a long-term language specification.