Возможны ли иные операции на графах кроме тех, что уже используются? Возможны.

В первую очередь хотелось бы сказать, что суть очень проста. Используется запись Y=F(X) или, другими словами, next_state=action(current_state).

Два графа. Первый задан тремя вершинами {С, A, B} и тремя ребрами {(С,A), (A,B) (B,C)}, каждое из которых суть действие F. Имеем множество переходов {A=F(C), B=F(A), C=F(B)} и переменную Т, значением которой будет одно из состояний (вершин графа). Аналогично для нижнего графа. Переменная С будет принимать одно из состояний {R,W}. Таким образом, С является как переменной, так и состоянием (значением) переменной T. Что позволяет конструировать иерархические структуры.

Феномен науки. рис. 7.3 //В.Турчин
Феномен науки. рис. 7.3 //В.Турчин

В частности, описывать выражения языка типа: деревянный стол, стол отца или же функцию глагола как смену состояний. Подробнее здесь

Демонстрация раскрытия переменной
import tkinter as tk
import time

root=tk.Tk()
root.title('Раскрытие переменной на графе')

canvas=tk.Canvas(root,width=460,height=300)
canvas.pack()

canvas_text_T = canvas.create_text(
            50, 30, font="DejavuSansLight",
            text="T"
        )
        
canvas_text_C = canvas.create_text(
            50, 180, font="DejavuSansLight",
            text="C"
        )
        
canvas.create_oval(50,50,80,80,outline="blue",fill="white")
canvas.create_oval(90,90,120,120,outline="blue",fill="white")
canvas.create_oval(150,50,180,80,outline="blue",fill="white")

canvas.create_line(75, 75, 95, 95, arrow=tk.LAST)
canvas.create_line(118, 97, 155, 75, arrow=tk.LAST)
canvas.create_line(150, 65, 80, 65, arrow=tk.LAST)

canvas_text_c = canvas.create_text(35, 80, text="C")
canvas_text_f = canvas.create_text(90, 130, text="A")
canvas_text_b = canvas.create_text(190, 70, text="B")

circle_t = canvas.create_oval(50,50,80,80,outline="white",fill="blue")

###
canvas.create_oval(50,200,80,230,outline="blue",fill="white")
canvas.create_oval(150,200,180,230,outline="blue",fill="white")

canvas.create_line(80, 205, 153, 205, arrow=tk.LAST)
canvas.create_line(80, 225, 153, 225, arrow=tk.FIRST)

canvas_text_R = canvas.create_text(45, 235, text="R")
canvas_text_W = canvas.create_text(185, 235, text="W")

canvas.create_text(120, 215, text="E")

circle_c = canvas.create_oval(50,200,80,230,outline="white",fill="blue")

###

canvas.create_line(300, 70, 440, 70)
canvas.create_line(340, 40, 340, 110)
canvas.create_text(320, 50, text="T", font="DejavuSansLight", fill="blue")
canvas.create_text(360, 50, text="C", font="DejavuSansLight")
canvas.create_text(390, 50, text="A", font="DejavuSansLight")
canvas.create_text(420, 50, text="B", font="DejavuSansLight")
canvas.create_text(320, 90, text="F", font="DejavuSansLight")
canvas.create_text(360, 90, text="A", font="DejavuSansLight")
canvas.create_text(390, 90, text="B", font="DejavuSansLight")
canvas.create_text(420, 90, text="C", font="DejavuSansLight")

canvas.create_line(300, 230, 410, 230)
canvas.create_line(340, 200, 340, 270)
canvas.create_text(320, 210, text="C", font="DejavuSansLight", fill="blue")
canvas.create_text(360, 210, text="R", font="DejavuSansLight")
canvas.create_text(390, 210, text="W", font="DejavuSansLight")
canvas.create_text(320, 250, text="E", font="DejavuSansLight")
canvas.create_text(360, 250, text="W", font="DejavuSansLight")
canvas.create_text(390, 250, text="R", font="DejavuSansLight")

###
time1 = 0
time2 = 0

def new():
    global time1, time2
    
    if time1 %3 == 0:
        canvas.move(circle_t,40,40)
        canvas.itemconfigure(canvas_text_T, text="T=A")
    if time1 %3 == 1:
        canvas.move(circle_t,60,-40)
        canvas.itemconfigure(canvas_text_T, text="T=B")
    if time1 %3 == 2:
        canvas.move(circle_t,-100,0)
        canvas.itemconfigure(canvas_text_T, text="T=C")
        if time2 %2 == 0:
            canvas.itemconfigure(canvas_text_c, text="C=W")
            canvas.itemconfigure(canvas_text_C, text="C=W")
            canvas.move(circle_c,100,0)
        else:
            canvas.itemconfigure(canvas_text_c, text="C=R")
            canvas.itemconfigure(canvas_text_C, text="C=R")
            canvas.move(circle_c,-100,0)
        time2 +=1
    
    time1 +=1

def redraw():
   canvas.after(1000,redraw)
   new()
   
canvas.after(1000,redraw)
root.mainloop()

В диаграммах состояниях UML  часто рисуют кружок с чёрной точкой внутри. Смысл - отобразить прекращёние существования объекта, а не только отдельных состояний.

Вот типичный пример. Как только телефонный разговор перейдёт в состояние final state, то этого телефонного разговора уже нет, его ноль. Как такое выразить аналитически? Всегда ложной формулой (Х != Х). И наоборот, о телефонном разговоре можно сказать, что он есть, выразив формулой, которая всегда истина (Х == Х).

Более того, если мы говорим, что нет ничего третьего, предполагая смену разных состояний (Y после Х), то как это выразить аналитически? Так же! Всегда ложной формулой (X == Y),  показывающей, что не бывает такого Х, которое было бы not X, и не бывает такого Y, которое было бы  not Y. Подробнее здесь.

P.S. Спираль логики)) О выше сказанном.
n = int(input()) #размерность 
mat = [[0]*n for i in range(n)] #матрица будет заполнена нулями
 
def spr(arr, k=0, num=1, t=0):
    '''arr - заполняемая матрица
    k - номер квадрата: если матрица 5*5, то 3 квадрата 
    (внешний, т.е. самый большой имеет k=0)
    t - величина уменьшения стороны квадрата
    num - число от 1 до n'''
    
    n = len(arr) #размерность матрицы
    
    for i in range(n-1 -t): #верхкняя сторона квадрата
        arr[k][i+k] = num; num +=1
    for i in range(n-1 -t): #правая сторона квадрата
        arr[i+k][n-1 -k] = num; num +=1
    for i in range(n-1 -t, 0, -1): #нижняя сторона квадрата
        arr[n-1 -k][i+k] = num; num +=1      
    for i in range(n-1 -t, 0, -1): #левая сторона квадрата
        arr[i+k][k] = num; num +=1 
        
    if not n%2 and num > n**2: #выход из рекурсии
        return 
    
    if n%2 and num == n**2:
        arr[n//2][n//2] = n**2
        return 
         
    spr(arr, k+1, num, t+2) #рекурсия   
          
spr(mat)

for i in mat:
    print(*i)

По сути, речь идёт о фазовом пространстве. Разница лишь в том, что каждое из состояний может либо быть, либо не быть. Это вырождённый случай количественных отношений в отношении (только) 0 и 1, в которых эти состояния могут находиться.

Маршруты на фазовом пространстве как последовательность переходов
Маршруты на фазовом пространстве как последовательность переходов

Для справки ... Фазовое пространство в математике и физике - пространство, каждая точка которой соответсвует одному и только одному состоянию из множества всех возможных состояний системы. Точка пространства, соответствующая состоянию системы называется изображающей или представляющей.

Причем, каждое из состояний или действий этого фазового пространства может быть переменной.