Vithanco Graph Language (VGL) Guide
Estimated reading time: 27 minutes.
Vithanco Graph Language (VGL) Guide
Table of Contents
Concepts
Overview
The Vithanco Graph Language (VGL) is a human-readable text format for creating and editing graphs. VGL provides a simple, declarative syntax for defining nodes, edges, groups, and their attributes.
Notation
Every VGL document must declare a notation, which defines the types of nodes and edges available in the graph.
Syntax:
vgraph <graph_id>: <NOTATION> "<graph_label>" {
...
}
VGL currently supports built-in notations that come with predefined node types and edge types:
- IBIS (Issue-Based Information System) - for decision-making and argumentation
- BBS (Benefit Breakdown Structure) - for benefit analysis
- ImpactMapping - for strategic planning and goal alignment
- ConceptMap - for visualizing relationships between concepts
- CRT (Current Reality Tree) - for root cause analysis using Theory of Constraints
- FRT (Future Reality Tree) - for solution validation using Theory of Constraints
- PRT (Prerequisite Tree) - for planning with necessary condition thinking using Theory of Constraints
- TRT (Transition Tree) - for step-by-step implementation planning using Theory of Constraints
- ADTree (Attack-Defense Tree) - for security modelling of attack and defense interactions
The notation determines what node types and edge types are available in your graph.
Nodes
Nodes represent the primary entities in your graph. Each node has:
- ID: A unique identifier (required)
- Type: The kind of node, determined by the notation (required)
- Label: A human-readable display name (optional)
- Attributes: Additional properties like color, fontsize, etc. (optional)
Syntax:
node <id>: <NodeType> "<label>" [<attributes>];
Example:
node q1: Question "What should we do?" [fontsize: 16; color: red];
Node Types
Node types are defined by the chosen notation. Each notation has its own set of node types with specific purposes and default styling.
IBIS Node Types:
Question- A question or issue to be resolved (default: blue)Answer- A proposed answer or solution (default: pink)Pro- An argument supporting an answer (default: green)Con- An argument opposing an answer (default: red)
BBS Node Types:
InvestmentObjective- High-level business objectiveBenefit- Expected benefit from the investmentBusinessChange- Organizational or process change requiredEnabler- Technology or capability enabler
ImpactMapping Node Types:
Goal- Strategic goal or objective (default: dark blue)Actor- Person or group who can produce impact (default: blue)Impact- Behavioral change or outcome (default: cyan)Deliverable- Product feature or capability (default: green)
ConceptMap Node Types:
Concept- A concept or term (default: blue rounded box)EmphasizedConcept- An important concept to highlight (default: red rounded box)Relation- A relationship verb connecting concepts (default: bare text)
CRT Node Types:
UndesirableEffect- An unwanted outcome requiring investigation (default: red)IntermediateEffect- A neutral outcome in the causal chain (default: blue)DesirableEffect- A wanted outcome caused by other conditions (default: green)Given- An unchangeable constant like laws or physics (default: dark purple)Changeable- A modifiable condition that can be addressed (default: light purple)AndJunctor- Indicates multiple conditions required simultaneously (icon: AND circle)OrJunctor- Indicates alternative causes (icon: OR circle)
FRT Node Types: FRT shares the same node types as CRT, as both are Theory of Constraints tools. The difference is in usage: FRT starts with solutions (Changeable/injections) and builds upward to show how they lead to desirable effects.
Changeable- Proposed solutions or injections to implement (default: light purple)Given- Unchangeable facts that still apply (default: dark purple)IntermediateEffect- Expected intermediate outcomes from solutions (default: blue)DesirableEffect- Goals we want to achieve (default: green)UndesirableEffect- Potential negative side effects to monitor (default: red)AndJunctor- Indicates multiple conditions required simultaneously (icon: AND circle)OrJunctor- Indicates alternative paths to outcomes (icon: OR circle)
PRT Node Types: PRT (Prerequisite Tree) is a planning tool using necessary condition thinking. It starts with the desired objective and works backward to identify obstacles and the intermediate objectives needed to overcome them.
Objective- The desired goal you aim to achieve (default: green)Obstacle- Barriers preventing objective achievement (default: red)IntermediateObjective- A milestone that overcomes a specific obstacle (default: blue)OR- Connector allowing optional conditions instead of requiring all predecessors (icon: OR circle)
TRT Node Types: TRT (Transition Tree) is an implementation planning tool that answers "HOW TO CAUSE the change?" by providing step-by-step actions needed to implement changes. It shares node types with CRT/FRT but focuses on the detailed action sequence.
UndesirableEffect- Current state problems being addressed (default: red)IntermediateEffect- Stepping stone outcomes from actions (default: blue)DesirableEffect- Goal outcomes we want to achieve (default: green)Given- Unchangeable facts and constraints (default: dark purple)Changeable- Actions we can take to cause change (default: light purple)AndJunctor- Indicates multiple conditions required together for an effect (icon: AND circle)
ADTree Node Types: ADTree (Attack-Defense Tree) is a security modelling methodology based on Kordy et al. (2014). It extends classical attack trees by allowing defense nodes at any level, modelling the ongoing arms race between attacker and defender.
Attack- An attacker's goal or sub-goal (default: red)Defense- A defender's countermeasure or protective measure (default: green)AndJunctor- Conjunctive refinement: all children must be achieved (icon: AND circle)OrJunctor- Disjunctive refinement: at least one child must be achieved (icon: OR circle)
Edges
Edges represent connections between nodes. Each edge has:
- From: Source node ID (required)
- To: Target node ID (required)
- Type: The kind of connection (optional, can be inferred)
- Label: A description of the relationship (optional)
- Attributes: Additional properties like style, weight, etc. (optional)
Syntax:
edge <from_id> -> <to_id>: <EdgeType> "<label>" [<attributes>];
Concise Syntax (omitting type):
edge <from_id> -> <to_id>;
When the edge type is omitted, VGL will automatically infer it based on the connected node types, if unambiguous.
Example:
edge q1 -> a1: answered_by "Initial solution";
edge a1 -> pro1 [style: dashed];
edge q2 -> a2; // Type inferred from node types
Edge Types
Edge types are defined by the notation and specify valid connections between node types.
IBIS Edge Types:
answered_by- Connects Question → Answersupports- Connects Answer → Proobjects_to- Connects Answer → Conpro_questions_question- Connects Pro → Questioncon_questions_question- Connects Con → Question
BBS Edge Types:
requires_benefit- Connects Benefit → InvestmentObjectiverequires_business_change- Connects BusinessChange → Benefitrequires_enabler- Connects Enabler → BusinessChangechange_requires_change- Connects BusinessChange → BusinessChangeenabler_requires_enabler- Connects Enabler → Enabler
ImpactMapping Edge Types:
goal_to_actor- Connects Goal → Actoractor_to_impact- Connects Actor → Impactimpact_to_deliverable- Connects Impact → Deliverable
ConceptMap Edge Types:
concept_to_relation- Connects Concept → Relation (tail marker only)relation_to_concept- Connects Relation → Concept (arrow head only)
CRT Edge Types: CRT has many edge types connecting causes to effects. The graph flows bottom-to-top (causes at bottom, effects at top).
From effects to effects:
undesirable_causes_undesirable,undesirable_causes_intermediate,undesirable_causes_desirableintermediate_causes_undesirable,intermediate_causes_intermediate,intermediate_causes_desirabledesirable_causes_undesirable,desirable_causes_intermediate,desirable_causes_desirable
From Given/Changeable to effects:
given_causes_undesirable,given_causes_intermediate,given_causes_desirablechangeable_causes_undesirable,changeable_causes_intermediate,changeable_causes_desirable
To/From Junctors:
*_to_and_junctor,*_to_or_junctor- Connect any type to junctorsand_junctor_causes_*,or_junctor_causes_*- Connect junctors to effects
FRT Edge Types: FRT shares the same edge types as CRT. The graph flows bottom-to-top (solutions at bottom, desired effects at top).
From Changeable/Given to effects (typical starting points in FRT):
changeable_causes_undesirable,changeable_causes_intermediate,changeable_causes_desirablegiven_causes_undesirable,given_causes_intermediate,given_causes_desirable
Between effects:
intermediate_causes_undesirable,intermediate_causes_intermediate,intermediate_causes_desirabledesirable_causes_*,undesirable_causes_*
To/From Junctors:
*_to_and_junctor,*_to_or_junctor- Connect any type to junctorsand_junctor_causes_*,or_junctor_causes_*- Connect junctors to effects
PRT Edge Types: PRT uses edges to show how obstacles block objectives and how intermediate objectives overcome obstacles. The graph flows bottom-to-top (intermediate objectives at bottom, main objective at top).
Obstacle blocking relationships:
obstacle_blocks_objective- Connects Obstacle → Objectiveobstacle_blocks_intermediate_objective- Connects Obstacle → IntermediateObjective
Intermediate objective relationships:
intermediate_objective_overcomes_obstacle- Connects IntermediateObjective → Obstacleintermediate_objective_to_objective- Connects IntermediateObjective → Objective (direct path)
To/From OR Junctor:
obstacle_to_or,intermediate_objective_to_or- Connect to OR junctoror_to_objective,or_to_intermediate_objective,or_to_obstacle- Connect from OR junctor
TRT Edge Types: TRT shares similar edge types with CRT/FRT but focuses on action planning. The graph flows bottom-to-top (actions at bottom, desired effects at top).
From Changeable/Given to effects (typical starting points for actions):
changeable_causes_undesirable,changeable_causes_intermediate,changeable_causes_desirablegiven_causes_undesirable,given_causes_intermediate,given_causes_desirable
Between effects:
intermediate_causes_undesirable,intermediate_causes_intermediate,intermediate_causes_desirabledesirable_causes_*,undesirable_causes_*
To/From And Junctor:
*_to_and_junctor- Connect any type to And junctorand_junctor_causes_*- Connect And junctor to effects (excluding And)
ADTree Edge Types: ADTree uses two kinds of edges: refinement edges (solid lines) for same-type decomposition, and countermeasure edges (dotted lines) for opposite-type countering. The graph flows top-to-bottom (root goal at top).
Refinement edges (solid):
attack_refines_attack- Decompose an attack into sub-attacksdefense_refines_defense- Decompose a defense into sub-defenses
Countermeasure edges (dotted):
defense_counters_attack- A defense that mitigates an attackattack_counters_defense- An attack that circumvents a defense
To/From Junctors:
attack_to_and_junctor,defense_to_and_junctor- Connect to AND junctorand_junctor_to_attack,and_junctor_to_defense- Connect from AND junctorattack_to_or_junctor,defense_to_or_junctor- Connect to OR junctoror_junctor_to_attack,or_junctor_to_defense- Connect from OR junctor
Edge types ensure that connections make semantic sense within the notation's domain.
Groups
Groups organize nodes hierarchically and can be nested to create subgroups. Groups help visually organize complex graphs.
Syntax:
group <id> "<label>" {
<attributes>;
<nodes>;
<edges>;
<nested_groups>;
};
Features:
- Groups can contain nodes, edges, and other groups
- Groups can have attributes like
style,color,label - Groups can be nested to unlimited depth
- Edges can connect nodes across different groups
Example:
group research "Research Phase" {
style: filled;
color: lightblue;
node q1: Question "What to research?";
node a1: Answer "User interviews";
group methodology "Methods" {
node m1: Pro "Direct feedback";
};
};
Attributes
Attributes customize the appearance and behavior of nodes, edges, and groups.
Inline Syntax (brackets):
[attribute1: value1; attribute2: value2]
Graph-Level Attributes (inside graph body):
rankdir: LR;
fontcolor: darkblue;
Common Node Attributes:
color- Node color (e.g.,red,blue,#FF0000)fontsize- Font size for node label (number)shape- Node shape (varies by notation)
Common Edge Attributes:
style- Line style (solid,dashed,dotted)weight- Edge weight (number)label- Edge label text
Common Group Attributes:
style- Group style (filled,dashed,dotted)color- Group background or border colorlabel- Group display name
Common Graph Attributes:
rankdir- Layout direction (LRfor left-to-right,TBfor top-to-bottom)fontcolor- Default font colorlabeljust- Label justification (lfor left,rfor right,cfor center)
Comments
VGL supports single-line comments using //:
// This is a comment
node q1: Question "Main question"; // This is also a comment
Comments can appear anywhere in the document and are ignored by the parser.
Grammar
The VGL grammar is defined as follows (simplified BNF notation):
document ::= "vgraph" identifier ":" notation label? "{" statement* "}"
notation ::= identifier
// Built-in notations: IBIS, BBS, ImpactMapping, ConceptMap, CRT, FRT, PRT, TRT, ADTree
statement ::= group | node | edge | attribute
group ::= "group" identifier label? "{" statement* "}" ";"?
node ::= "node" identifier ":" identifier label? attributes? ";"?
edge ::= "edge" identifier "->" identifier (":" identifier)? label? attributes? ";"?
attribute ::= identifier ":" value ";"?
attributes ::= "[" (attribute (";" | ",")?)* "]"
label ::= quoted_string
value ::= quoted_string | number | identifier
identifier ::= [a-zA-Z0-9_\.\,\-]+
number ::= [-]?[0-9]+(\.[0-9]+)?
quoted_string::= "\"" ([^\"\\] | "\\" .)* "\""
comment ::= "//" [^\n]*
Key Grammar Rules:
- Document Structure: Every VGL file must start with a
vgraphdeclaration - Node IDs: Must be unique throughout the document
- Edge References: Edges can only reference nodes that have been declared
- Type Validation: Node types and edge types must be valid for the chosen notation, or will be marked as "unknown"
- Attributes: Can appear inline with brackets
[]or as separate statements within groups - Semicolons: Optional after nodes, edges, groups, and standalone attributes
- Quoted Strings: Used for labels and string attribute values, support escape sequences (
\",\\, etc.) - Comments: Single-line only, using
//syntax
Examples
Example 1: Simple IBIS Graph
A basic decision-making graph with questions and answers:
vgraph simple_decision: IBIS "Simple Decision" {
node q1: Question "What framework should we use?";
node a1: Answer "React";
node a2: Answer "Vue";
edge q1 -> a1;
edge q1 -> a2;
}
Example 2: IBIS with Arguments
A more complete decision graph with pro and con arguments:
vgraph tech_decision: IBIS "Technology Decision" {
node q1: Question "Which database should we use?";
node a1: Answer "PostgreSQL";
node a2: Answer "MongoDB";
node pro1: Pro "ACID compliance";
node pro2: Pro "Flexible schema";
node con1: Con "More complex setup";
node con2: Con "Limited transaction support";
edge q1 -> a1: answered_by;
edge q1 -> a2: answered_by;
edge a1 -> pro1: supports;
edge a1 -> con1: objects_to;
edge a2 -> pro2: supports;
edge a2 -> con2: objects_to;
}
Example 3: Using Groups
Organizing nodes into logical groups:
vgraph project_planning: IBIS "Project Planning" {
node main_q: Question "How should we structure the project?" [fontsize: 20];
group architecture "Architecture Decisions" {
style: filled;
color: lightblue;
node q1: Question "Which architecture pattern?";
node a1: Answer "Microservices";
node a2: Answer "Monolithic";
edge q1 -> a1;
edge q1 -> a2;
};
group testing "Testing Strategy" {
style: filled;
color: lightgreen;
node q2: Question "What testing approach?";
node a3: Answer "TDD";
node a4: Answer "BDD";
edge q2 -> a3;
edge q2 -> a4;
};
edge main_q -> q1: answered_by "Consider architecture";
edge main_q -> q2: answered_by "Define testing";
}
Example 4: Nested Groups with Attributes
Complex hierarchical structure with styling:
vgraph research_project: IBIS "Research Project" {
rankdir: LR;
group phase1 "Discovery Phase" {
style: filled;
color: lightyellow;
node q1: Question "What should we research?" [fontsize: 16];
node a1: Answer "User behavior" [fontsize: 14];
node a2: Answer "Market trends" [fontsize: 14];
group methods "Research Methods" {
style: dashed;
color: orange;
node pro1: Pro "Interviews provide depth" [fontsize: 12];
node pro2: Pro "Surveys give breadth" [fontsize: 12];
node con1: Con "Time consuming" [fontsize: 12];
};
edge q1 -> a1;
edge q1 -> a2;
edge a1 -> pro1: supports;
edge a1 -> con1: objects_to;
};
group phase2 "Analysis Phase" {
style: filled;
color: lightblue;
node q2: Question "How to analyze data?" [fontsize: 16];
node a3: Answer "Quantitative analysis" [fontsize: 14];
};
}
Example 5: Minimal Syntax
Using the most concise syntax available:
vgraph minimal: IBIS "Minimal Example" {
// Questions and answers
node q1: Question "Question 1";
node a1: Answer "Answer 1";
node a2: Answer "Answer 2";
// Arguments
node p1: Pro "Pro argument";
node c1: Con "Con argument";
// Edges with inferred types
edge q1 -> a1;
edge q1 -> a2;
edge a1 -> p1;
edge a1 -> c1;
}
Example 6: Complex Graph with All Features
A comprehensive example demonstrating all VGL features:
vgraph comprehensive: IBIS "Comprehensive Example" {
// Graph-level properties
rankdir: LR;
fontcolor: darkblue;
labeljust: l;
// Root-level nodes
node root: Question "Main Question" [fontsize: 20; color: navy];
node ans1: Answer "Primary Solution" [fontsize: 16];
node ans2: Answer "Alternative Solution" [fontsize: 16];
// Detailed analysis group
group analysis "Detailed Analysis" {
style: filled;
color: lightgray;
node q_perf: Question "What about performance?";
node a_fast: Answer "Optimize critical paths" [color: green];
node pro_perf: Pro "40% faster response time" [fontsize: 12];
// Nested considerations
group tradeoffs "Trade-offs" {
style: dashed;
color: yellow;
node con_complex: Con "Increased code complexity" [fontsize: 10];
node q_maint: Question "Can we maintain this?" [fontsize: 11];
};
edge q_perf -> a_fast: answered_by;
edge a_fast -> pro_perf: supports;
edge a_fast -> con_complex: objects_to;
edge con_complex -> q_maint: con_questions_question "Raises concern";
};
// Implementation group
group implementation "Implementation Plan" {
style: filled;
color: lightblue;
node q_when: Question "When to implement?" [fontsize: 14];
node a_phase: Answer "Phased rollout" [fontsize: 13];
node pro_safe: Pro "Reduces risk" [fontsize: 11];
edge q_when -> a_phase;
edge a_phase -> pro_safe;
};
// Cross-group connections
edge root -> ans1: answered_by "Main path";
edge root -> ans2: answered_by "Backup option";
edge ans1 -> q_perf: answered_by [style: dashed; weight: 5];
edge ans2 -> q_when: answered_by;
}
Example 7: Using Explicit Edge Types
Demonstrating all IBIS edge types:
vgraph edge_types: IBIS "Edge Type Examples" {
// Setup nodes
node q1: Question "Should we proceed?";
node a1: Answer "Yes, with caution";
node pro1: Pro "Market opportunity";
node con1: Con "Technical debt";
node q2: Question "How to mitigate risks?";
// Demonstrate each edge type
edge q1 -> a1: answered_by;
edge a1 -> pro1: supports;
edge a1 -> con1: objects_to;
edge pro1 -> q2: pro_questions_question;
edge con1 -> q2: con_questions_question;
}
Example 8: Impact Mapping
A strategic planning graph showing goals, actors, impacts, and deliverables:
vgraph mobileApp: ImpactMapping "Mobile App Launch" {
node g1: Goal "Increase Revenue by 30%";
node a1: Actor "New Customers";
node a2: Actor "Existing Customers";
node i1: Impact "Make First Purchase";
node i2: Impact "Increase Purchase Frequency";
node i3: Impact "Upgrade to Premium";
node d1: Deliverable "Mobile App with Easy Checkout";
node d2: Deliverable "Push Notifications for Deals";
node d3: Deliverable "Loyalty Rewards Program";
node d4: Deliverable "Premium Features Bundle";
edge g1 -> a1: goal_to_actor;
edge g1 -> a2: goal_to_actor;
edge a1 -> i1: actor_to_impact;
edge a2 -> i2: actor_to_impact;
edge a2 -> i3: actor_to_impact;
edge i1 -> d1: impact_to_deliverable;
edge i2 -> d2: impact_to_deliverable;
edge i2 -> d3: impact_to_deliverable;
edge i3 -> d4: impact_to_deliverable;
}
Example 9: Impact Mapping with Inferred Types
Using type inference for cleaner syntax:
vgraph product_growth: ImpactMapping "Product Growth Strategy" {
// Strategic goal
node goal: Goal "Double User Engagement";
// Key actors
node power_users: Actor "Power Users";
node casual_users: Actor "Casual Users";
node new_users: Actor "New Users";
// Desired impacts
node i1: Impact "Share content more frequently";
node i2: Impact "Complete onboarding successfully";
node i3: Impact "Return within 7 days";
// Required deliverables
node d1: Deliverable "Social sharing features";
node d2: Deliverable "Interactive tutorial";
node d3: Deliverable "Email reminder system";
// Connections with inferred types
edge goal -> power_users;
edge goal -> casual_users;
edge goal -> new_users;
edge power_users -> i1;
edge new_users -> i2;
edge casual_users -> i3;
edge i1 -> d1;
edge i2 -> d2;
edge i3 -> d3;
}
Example 10: Concept Map
Visualizing relationships between concepts using linking verbs:
vgraph learningCM: ConceptMap "How Learning Works" {
// Main concepts
node c1: Concept "Student";
node c2: Concept "Subject";
node c3: EmphasizedConcept "Practice"; // Emphasized for importance
node c4: Concept "Understanding";
node c5: Concept "Resources";
// Relationship verbs (relations)
node r1: Relation "learns";
node r2: Relation "requires";
node r3: Relation "leads to";
node r4: Relation "uses";
// Concept map connections
// Pattern: Concept -> Relation -> Concept
edge c1 -> r1: concept_to_relation;
edge r1 -> c2: relation_to_concept;
edge c2 -> r2: concept_to_relation;
edge r2 -> c3: relation_to_concept;
edge c3 -> r3: concept_to_relation;
edge r3 -> c4: relation_to_concept;
edge c2 -> r4: concept_to_relation;
edge r4 -> c5: relation_to_concept;
}
Note: In concept maps, relationships are represented as nodes (Relation type) rather than edge labels. This creates readable propositions like "Student learns Subject" and "Subject requires Practice".
Example 11: Current Reality Tree (CRT)
A root cause analysis graph showing how causes lead to undesirable effects:
vgraph salesDecline: CRT "Sales Decline Analysis" {
// Undesirable Effects (problems at the top)
node ude1: UndesirableEffect "Sales revenue declining";
node ude2: UndesirableEffect "Customer complaints increasing";
node ude3: UndesirableEffect "Market share decreasing";
// Intermediate Effects (neutral outcomes in the causal chain)
node ie1: IntermediateEffect "Customers switching to competitors";
node ie2: IntermediateEffect "Product perceived as outdated";
node ie3: IntermediateEffect "Support response time is slow";
// Desirable Effects (things we want to keep)
node de1: DesirableEffect "Brand reputation still strong";
// Given (unchangeable facts at the bottom)
node g1: Given "Market is highly competitive";
node g2: Given "Customer expectations keep rising";
// Changeable (root causes we can address)
node c1: Changeable "Product development cycle is too long";
node c2: Changeable "Support team is understaffed";
node c3: Changeable "No customer feedback loop";
// Junctors for combining conditions
node and1: AndJunctor "";
node or1: OrJunctor "";
// Root causes leading to intermediate effects
edge c1 -> ie2: changeable_causes_intermediate;
edge c3 -> ie2: changeable_causes_intermediate;
edge c2 -> ie3: changeable_causes_intermediate;
// Given facts contributing to situation
edge g1 -> ie1: given_causes_intermediate;
edge g2 -> and1: given_to_and_junctor;
edge ie2 -> and1: intermediate_to_and_junctor;
// And junctor combining conditions
edge and1 -> ie1: and_junctor_causes_intermediate;
// Or junctor for alternative paths
edge ie1 -> or1: intermediate_to_or_junctor;
edge ie3 -> or1: intermediate_to_or_junctor;
// Intermediate effects leading to undesirable effects
edge or1 -> ude2: or_junctor_causes_undesirable;
edge ie1 -> ude1: intermediate_causes_undesirable;
edge ie1 -> ude3: intermediate_causes_undesirable;
// Brand reputation affected but still positive
edge ie2 -> de1: intermediate_causes_desirable;
}
Note: CRT graphs flow bottom-to-top, with root causes (Given and Changeable) at the bottom and Undesirable Effects at the top. The AndJunctor indicates multiple conditions must be true together, while OrJunctor indicates any one of the conditions is sufficient. Labels for junctors are typically empty as the icon conveys the meaning.
Example 12: Future Reality Tree (FRT)
A solution validation graph showing how proposed solutions lead to desired outcomes:
vgraph salesSolution: FRT "Sales Improvement Plan" {
// Changeable nodes (injections/solutions we will implement)
node c1: Changeable "Implement agile product development";
node c2: Changeable "Hire additional support staff";
node c3: Changeable "Create customer feedback system";
// Given (unchangeable facts that still apply)
node g1: Given "Market is highly competitive";
node g2: Given "Customer expectations keep rising";
// Intermediate Effects (expected outcomes from our solutions)
node ie1: IntermediateEffect "Faster product iterations";
node ie2: IntermediateEffect "Products match customer needs";
node ie3: IntermediateEffect "Support response time improves";
node ie4: IntermediateEffect "Customer feedback drives development";
// Junctors for combining conditions
node and1: AndJunctor "";
node or1: OrJunctor "";
// Desirable Effects (the goals we want to achieve)
node de1: DesirableEffect "Sales revenue increasing";
node de2: DesirableEffect "Customer satisfaction high";
node de3: DesirableEffect "Market share growing";
// Potential negative side effects (to monitor)
node ude1: UndesirableEffect "Initial implementation costs";
// Solutions leading to intermediate effects
edge c1 -> ie1: changeable_causes_intermediate;
edge c3 -> ie4: changeable_causes_intermediate;
edge c2 -> ie3: changeable_causes_intermediate;
// Given facts combining with solutions
edge g2 -> and1: given_to_and_junctor;
edge ie4 -> and1: intermediate_to_and_junctor;
// And junctor combining conditions
edge and1 -> ie2: and_junctor_causes_intermediate;
// Multiple paths can lead to customer satisfaction
edge ie2 -> or1: intermediate_to_or_junctor;
edge ie3 -> or1: intermediate_to_or_junctor;
// Intermediate effects leading to desirable effects
edge or1 -> de2: or_junctor_causes_desirable;
edge ie1 -> de3: intermediate_causes_desirable;
edge ie2 -> de1: intermediate_causes_desirable;
edge ie2 -> de3: intermediate_causes_desirable;
// Acknowledging potential downsides
edge c1 -> ude1: changeable_causes_undesirable;
edge c2 -> ude1: changeable_causes_undesirable;
// Given competitive market affects outcomes
edge g1 -> ie2: given_causes_intermediate;
}
Note: FRT graphs also flow bottom-to-top like CRT, but with a different focus. While CRT starts with problems (Undesirable Effects) and traces back to root causes, FRT starts with proposed solutions (Changeable/injections) and traces forward to show how they achieve desired outcomes. This makes FRT ideal for validating that proposed changes will actually deliver the expected benefits.
Example 13: Prerequisite Tree (PRT)
A planning graph showing obstacles blocking objectives and intermediate objectives to overcome them:
vgraph projectLaunch: PRT "New Product Launch Planning" {
// The main objective we want to achieve
node obj1: Objective "Successfully launch product by Q3";
// Obstacles blocking the main objective
node obs1: Obstacle "Development team lacks required skills";
node obs2: Obstacle "Marketing budget not approved";
node obs3: Obstacle "No distribution channel established";
// Intermediate objectives to overcome obstacles
node io1: IntermediateObjective "Train team on new technology";
node io2: IntermediateObjective "Hire experienced developers";
node io3: IntermediateObjective "Present ROI analysis to leadership";
node io4: IntermediateObjective "Partner with existing retailer";
node io5: IntermediateObjective "Build direct-to-consumer channel";
// OR junctor for alternative paths
node or1: OR;
node or2: OR;
// Further obstacles blocking intermediate objectives
node obs4: Obstacle "Training budget limited";
node obs5: Obstacle "Talent pool is competitive";
// Obstacles block the main objective
edge obs1 -> obj1: obstacle_blocks_objective;
edge obs2 -> obj1: obstacle_blocks_objective;
edge obs3 -> obj1: obstacle_blocks_objective;
// Alternative ways to overcome skill obstacle (via OR)
edge io1 -> or1: intermediate_objective_to_or;
edge io2 -> or1: intermediate_objective_to_or;
edge or1 -> obs1: or_to_obstacle;
// ROI analysis overcomes budget obstacle
edge io3 -> obs2: intermediate_objective_overcomes_obstacle;
// Alternative distribution solutions
edge io4 -> or2: intermediate_objective_to_or;
edge io5 -> or2: intermediate_objective_to_or;
edge or2 -> obs3: or_to_obstacle;
// Recursive obstacles blocking intermediate objectives
edge obs4 -> io1: obstacle_blocks_intermediate_objective;
edge obs5 -> io2: obstacle_blocks_intermediate_objective;
}
Note: PRT graphs flow bottom-to-top like other TOC tools. The main Objective sits at the top, with Obstacles directly below showing what blocks it. IntermediateObjectives below the obstacles show what needs to be achieved to overcome them. The OR junctor indicates alternative paths - only one of the connected intermediate objectives needs to be achieved. PRT embodies "necessary condition thinking" - working backward from the goal to identify all prerequisites.
Example 14: Transition Tree (TRT)
A step-by-step implementation planning graph showing how actions lead to desired outcomes:
vgraph agileTransition: TRT "Agile Transformation Implementation" {
// Given conditions (the context we're working within)
node g1: Given "Company has 5 development teams";
node g2: Given "Current waterfall process causes delays";
// Changeable causes (actions we will take)
node c1: Changeable "Introduce daily standups";
node c2: Changeable "Implement CI/CD pipeline";
node c3: Changeable "Create cross-functional teams";
node c4: Changeable "Train teams on Scrum practices";
// Intermediate effects (stepping stones from actions)
node ie1: IntermediateEffect "Teams communicate more frequently";
node ie2: IntermediateEffect "Code integration happens daily";
node ie3: IntermediateEffect "Teams have diverse skillsets";
node ie4: IntermediateEffect "Teams follow iterative process";
node ie5: IntermediateEffect "Silos are broken down";
// And junctors for combined conditions
node and1: AndJunctor "";
node and2: AndJunctor "";
// Desirable effects (the goals we achieve)
node de1: DesirableEffect "Faster time to market";
node de2: DesirableEffect "Higher quality releases";
node de3: DesirableEffect "Better team collaboration";
// Actions lead to intermediate effects
edge c1 -> ie1: changeable_causes_intermediate;
edge c2 -> ie2: changeable_causes_intermediate;
edge c3 -> ie3: changeable_causes_intermediate;
edge c4 -> ie4: changeable_causes_intermediate;
// Given context combines with cross-functional teams
edge g1 -> and1: given_to_and_junctor;
edge ie3 -> and1: intermediate_to_and_junctor;
edge and1 -> ie5: and_junctor_causes_intermediate;
// Breaking silos leads to collaboration
edge ie5 -> de3: intermediate_causes_desirable;
// Communication helps collaboration too
edge ie1 -> de3: intermediate_causes_desirable;
// CI/CD + iterative process combine for quality
edge ie2 -> and2: intermediate_to_and_junctor;
edge ie4 -> and2: intermediate_to_and_junctor;
edge and2 -> de2: and_junctor_causes_desirable;
// Quality and collaboration lead to speed
edge de2 -> de1: desirable_causes_desirable;
edge de3 -> de1: desirable_causes_desirable;
// Given waterfall context is addressed by iterative process
edge g2 -> ie4: given_causes_intermediate;
}
Note: TRT graphs flow bottom-to-top like other TOC tools. The focus is on detailed implementation planning - answering "HOW TO CAUSE the change?" Unlike FRT which validates that solutions will work, TRT provides the step-by-step action sequence needed to implement those solutions. Changeable nodes represent the specific actions to take, and the graph shows how those actions combine through intermediate effects to achieve desirable outcomes. The AndJunctor indicates multiple conditions must occur together for an effect.
Example 15: Attack-Defense Tree (ADTree)
A security modelling graph showing how defenses protect a system and how attacks can circumvent them. Based on the data confidentiality scenario from Kordy et al. (2014):
vgraph dataConfidentiality: ADTree "Data Confidentiality" {
// Defense nodes (defender's goals)
node dataConf: Defense "Data Confidentiality";
node networkSec: Defense "Network Security";
node physicalSec: Defense "Physical Security";
node accessControl: Defense "Access Control";
node passwords: Defense "Passwords";
node strongPasswords: Defense "Strong Passwords";
node lock1: Defense "Lock";
node screening: Defense "Screening";
node securityGuard: Defense "Security Guard";
node videoCameras: Defense "Video Cameras";
// Attack nodes (attacker's goals)
node employeeAttack: Attack "Employee Attack";
node breakIn: Attack "Break In";
node corruption: Attack "Corruption";
node socialEngineering: Attack "Social Engineering";
node dictionaryAttack: Attack "Dictionary Attack";
node backDoor: Attack "Back Door";
node defeatLock: Attack "Defeat Lock";
node forceOpen: Attack "Force Open";
node acquireKeys: Attack "Acquire Keys";
node defeatGuard: Attack "Defeat Guard";
node bribe: Attack "Bribe";
node overpower: Attack "Overpower";
node stealKeys: Attack "Steal Keys";
node outnumber: Attack "Outnumber";
node useWeapons: Attack "Use Weapons";
// AND junctors for conjunctive refinement
node andDataConf: AndJunctor;
node andOverpower: AndJunctor;
// Defense refines into sub-defenses via AND junctor (both required)
edge networkSec -> andDataConf: defense_to_and_junctor;
edge physicalSec -> andDataConf: defense_to_and_junctor;
edge andDataConf -> dataConf: and_junctor_to_defense;
edge accessControl -> networkSec: defense_refines_defense;
edge passwords -> accessControl: defense_refines_defense;
// Attack refines into sub-attacks (solid edges)
edge corruption -> employeeAttack: attack_refines_attack;
edge socialEngineering -> employeeAttack: attack_refines_attack;
edge backDoor -> breakIn: attack_refines_attack;
edge forceOpen -> defeatLock: attack_refines_attack;
edge acquireKeys -> defeatLock: attack_refines_attack;
edge bribe -> defeatGuard: attack_refines_attack;
edge overpower -> defeatGuard: attack_refines_attack;
edge stealKeys -> defeatGuard: attack_refines_attack;
// Countermeasure: defense counters attack (dotted edges)
edge strongPasswords -> dictionaryAttack: defense_counters_attack;
edge lock1 -> backDoor: defense_counters_attack;
edge screening -> corruption: defense_counters_attack;
edge securityGuard -> breakIn: defense_counters_attack;
edge videoCameras -> defeatGuard: defense_counters_attack;
// Countermeasure: attack counters defense (dotted edges)
edge employeeAttack -> dataConf: attack_counters_defense;
edge breakIn -> physicalSec: attack_counters_defense;
edge dictionaryAttack -> passwords: attack_counters_defense;
edge defeatLock -> lock1: attack_counters_defense;
edge defeatGuard -> securityGuard: attack_counters_defense;
// AND junctor: conjunctive refinement
edge outnumber -> andOverpower: attack_to_and_junctor;
edge useWeapons -> andOverpower: attack_to_and_junctor;
edge andOverpower -> overpower: and_junctor_to_attack;
}
Note: ADTree graphs flow bottom-to-top with the root goal at the top and leaf actions at the bottom. The key feature is the distinction between refinement edges (solid lines for same-type decomposition) and countermeasure edges (dotted lines for opposite-type countering). This allows modelling the ongoing arms race between attacker and defender at any level of the tree. The root node can be either an Attack or Defense node, determining whether the proponent is the attacker or defender.
Best Practices
- Use Meaningful IDs: Choose descriptive node IDs like
security_questioninstead ofn1 - Organize with Groups: Use groups to organize related nodes and improve readability
- Leverage Type Inference: Omit edge types when they can be inferred from node types
- Add Labels: Always provide labels for better human readability
- Comment Your Graphs: Use comments to explain complex relationships or decisions
- Keep It Simple: Start with minimal syntax and add attributes only when needed
- Consistent Naming: Use a consistent naming convention for IDs (e.g., snake_case or camelCase)
- Hierarchical Organization: Use nested groups to reflect the natural hierarchy of your domain
Error Handling
VGL provides clear error messages for common issues:
- Duplicate Node ID: Each node ID must be unique
- Undefined Node Reference: Edges can only reference existing nodes
- Invalid Node Type: Node types must exist in the chosen notation (creates "unknown" type)
- Invalid Edge Type: Edge types must be valid for the connected node types (creates "unknown" edge type)
- Syntax Errors: Missing semicolons, braces, or other syntax requirements
When a node type or edge type is not found in the notation, VGL will create an "unknown" type to allow the graph to be processed, but you should verify that the type names are correct.