using System.Collections;
using System.Collections.Generic;
using System.Windows.Threading;
public static void Main()
var sd = new StateDiagram();
var hungry = new State("Hungry");
var satisfied = new State("Satisfied");
var sick = new State("Sick");
sd.ConnectStates(hungry, satisfied, "eat");
sd.ConnectStates(satisfied, sick, "eat too much");
sd.ConnectStates(sick, hungry, "wait");
Console.WriteLine(sd.ExportToStateMachineCat());
public string Name { get; set; }
public List<Transition> Transitions { get; set; }
public bool IsInitial { get; set; }
public bool IsFinal { get; set; }
public State(string name, bool isInitial = false, bool isFinal = false)
Transitions = new List<Transition>();
public void AddTransition(State toState, string label = null, Func<bool> guard = null)
Transitions.Add(new Transition(toState, label, guard));
public State ToState { get; set; }
public string Label { get; set; }
public Func<bool> Guard { get; set; }
public Transition(State toState, string label = null, Func<bool> guard = null)
public class LabeledChoice
public string Label { get; set; }
public bool Value { get; set; }
public LabeledChoice(string label, bool value)
public class StateDiagram
public List<State> States { get; set; }
public List<LabeledChoice> LabeledChoices { get; set; }
States = new List<State>();
LabeledChoices = new List<LabeledChoice>();
public void AddState(State state)
public void AddLabeledChoice(LabeledChoice labeledChoice)
LabeledChoices.Add(labeledChoice);
public void ConnectStates(State fromState, State toState, string label = null, Func<bool> guard = null)
fromState.AddTransition(toState, label, guard);
public string ExportToStateMachineCat()
var builder = new StringBuilder();
builder.AppendLine(string.Join(",", States.Select(s => s.Name)) + ";");
foreach (var state in States)
foreach (var transition in state.Transitions)
builder.Append(state.Name);
builder.Append(transition.ToState.Name);
if (!string.IsNullOrEmpty(transition.Label))
builder.Append(transition.Label);
if (transition.Guard != null)
builder.Append(transition.Guard);
var initialState = States.FirstOrDefault(s => s.IsInitial);
if (initialState != null)
builder.AppendLine("initial => " + initialState.Name);
return builder.ToString();