Yazılım Test Süreçleri

Testçiler için Graf Teorisi

Dr. Öğr. Üyesi Oğuz Emre Kural

2026

Öğrenim Çıktıları

  • Bu bölümün sonunda şunları yapabileceksiniz:
    • Graf teorisinin temel kavramlarını (düğüm, kenar, derece, yol, döngü, bağlılık vb.) tanımlayabileceksiniz.
    • Yönsüz ve yönlü graflar arasındaki farkı açıklayabileceksiniz.
    • Bir yazılım sisteminin akışını (control flow) veya durum geçişlerini graf olarak modelleyebileceksiniz.
    • Graf teorisi kavramlarını (çevrimsel karmaşıklık, bağlılık, yol kapsamı) test tasarımına uygulayabileceksiniz.
    • StateChart, Petri ağı gibi modelleme notasyonlarının graf temelli yapısını anlayabileceksiniz.

Testçiler için Graf Teorisi

  • Graf teorisi, topolojinin bir dalıdır; bazen “rubber sheet geometry” (lastik levha geometrisi) olarak da anılır.
  • Topolojideki “lastik levha” sezgisi, graf teorisinin çoğu problemini doğrudan açıklamaz.
  • Buna rağmen graf teorisi:
    • özellikle yönlü graflar (directed graphs),
    • ve graf temelli test yaklaşımları için testte çok güçlü bir araçtır.

Neden Graf Teorisi? (Test Bağlantısı)

  • Bu bölümün odağı “soyut teori” değil; testte işe yarayan kavramlardır.
  • Graf teorisi testte özellikle şunları modellemek için kullanılır:
    • program akışı (control flow)
    • durum makineleri / ekran akışları (state/transition)
    • olay güdümlü sistemler (event-driven)
    • bağlantı/iletişim ağları (integration topology)
  • Kitaptaki yaklaşım: kavramları test örnekleriyle ilişkilendirerek vermek.

Bu Bölümde Nasıl İlerliyoruz?

  • İki temel graf türü vardır:
    • yönsüz (undirected) graflar
    • yönlü (directed) graflar
  • Yönlü graflar testte daha sık görünür.
  • Ancak yönlü grafların birçok fikri, yönsüz grafların özel durumu gibi düşünülebilir.
  • Bu yüzden:
    • önce yönsüz graflarla başlayacağız,
    • sonra aynı kavramları yönlü graflara aktaracağız.

Graflar (Graphs)

  • Bir graf (graph), iki küme ile tanımlanan soyut bir yapıdır:
    • düğüm kümesi (nodes / vertices)
    • kenar kümesi (edges)
  • Kenarlar, düğümler arasında bağlantı/ilişki kurar.
  • Örnek: Bir bilgisayar ağı, doğal bir graf örneğidir.

Tanım: Graf \(G=(V,E)\)

Bir graf:

\[ G=(V,E) \]

  • \(V\): sonlu ve boş olmayan düğüm (node) kümesi
  • \(E\): düğüm çiftlerinden oluşan kenar (edge) kümesi

Düğüm Kümesi (Nodes)

Düğümler (vertices) bir küme olarak yazılır:

\[ V=\{n_1,n_2,\ldots,n_k\} \]

Kenar Kümesi (Edges)

Yönsüz graf için her kenar bir yönsüz çifttir:

\[ E=\{e_1,e_2,\ldots,e_\ell\} \]

Her kenar şu biçimdedir:

\[ e_i=\{n_p,n_q\} \]

  • \(\{n_p,n_q\}\) sırasızdır: \(\{n_p,n_q\}=\{n_q,n_p\}\)

Terminoloji: Aynı Kavram, Farklı Adlar

  • node = vertex (düğüm)
  • edge = arc (kenar)
  • Düğümlere bazen “points” (nokta) da denir.
  • Diyagramlarda:
    • düğümler genelde daire,
    • kenarlar çizgi olarak gösterilir.

Örnek Graf: 7 Düğüm, 5 Kenar

\[ V=\{n_1,n_2,n_3,n_4,n_5,n_6,n_7\} \]

\[ E=\{e_1,e_2,e_3,e_4,e_5\} \]

Kenarları Düğüm Çiftleriyle Yazmak

Aynı \(E\) kümesini, “hangi düğümler bağlı?” şeklinde de yazabiliriz:

\[ E=\{\{n_1,n_2\},\{n_1,n_4\},\{n_3,n_4\},\{n_2,n_5\},\{n_4,n_6\}\} \]

  • Yönsüz graf olduğu için çiftler sırasızdır.

Testte Graf Nasıl Kullanılır?

  • Pratikte önce bir düğüm kümesi tanımlarız (çoğu zaman düğümler program öğeleridir):
    • program ifadeleri (statements)
    • bloklar (basic blocks)
    • ekranlar/durumlar (states)
  • Sonra kenarları tanımlarız:
    • kontrol akışı (control flow)
    • olay/ekran geçişi (event/transition)
    • tanım-kullanım ilişkileri (define/use)

Düğüm Derecesi (Degree of a Node)

  • Bir düğümün derecesi (degree):
    • o düğümün uç noktası olduğu kenar sayısıdır.
  • Gösterim:

\[ deg(n) \]

  • \(deg(n)\) “n’in popülerliği” gibi yorumlanabilir:
    • daha çok kenar → daha çok bağlantı

Tanım

Bir düğüm \(n\) için:

\[ deg(n)=|\{e \in E : n \in e\}| \]

  • Yani: “uç noktası \(n\) olan kenarların sayısı”

Sezgi: Derece Ne Anlatır?

  • Sosyal ağ grafında:
    • düğümler = insanlar
    • kenarlar = arkadaşlık/iletişim
    • derece → kişinin “bağlantı sayısı”
  • Yazılım grafında (nesne-iletişim):
    • düğümler = nesneler
    • kenarlar = mesajlar/çağrılar
    • derece → nesnenin entegrasyon yoğunluğu hakkında ipucu verebilir

Örnek Graf İçin Düğüm Dereceleri

Şekil 4.1’deki düğümlerin dereceleri:

\[ deg(n_1)=2 \]

\[ deg(n_2)=2 \]

\[ deg(n_3)=1 \]

\[ deg(n_4)=3 \]

\[ deg(n_5)=1 \]

\[ deg(n_6)=1 \]

\[ deg(n_7)=0 \]

İnsidans Matrisleri (Incidence Matrices)

  • Graflar sadece çizimle değil, matrislerle de temsil edilebilir.
  • Test açısından bu temsil değerlidir:
    • grafın yapısını “hesaplanabilir” hale getirir
    • bazı hataları (tutarsızlıkları) hızlı yakalamayı sağlar

Tanım: İnsidans Matrisi

\(G=(V,E)\) grafında:

  • \(|V|=m\) düğüm
  • \(|E|=n\) kenar

İnsidans matrisi \(I\), boyutu:

\[ m \times n \]

  • satırlar: düğümler
  • sütunlar: kenarlar

Matris Elemanı \(I[i,j]\)

  • \(I[i,j]=1\) ise: \(n_i\), \(e_j\) kenarının bir uç noktasıdır.
  • Aksi halde:

\[ I[i,j]=0 \]

Özet:

\[ I[i,j]= \begin{cases} 1, & n_i \text{, } e_j \text{’nin uç noktasıysa} \\ 0, & \text{aksi halde} \end{cases} \]

Şekil 4.1’in İnsidans Matrisi

\(e_1\) \(e_2\) \(e_3\) \(e_4\) \(e_5\)
\(n_1\) 1 1 0 0 0
\(n_2\) 1 0 0 1 0
\(n_3\) 0 0 1 0 0
\(n_4\) 0 1 1 0 1
\(n_5\) 0 0 0 1 0
\(n_6\) 0 0 0 0 1
\(n_7\) 0 0 0 0 0

Hızlı Gözlemler (1): Sütun Toplamı = 2

  • Yönsüz basit graf için her kenarın iki uç noktası vardır.
  • Bu yüzden her sütunun toplamı:

\[ \sum_{i=1}^{m} I[i,j] = 2 \]

  • Eğer bir sütunda toplam 2 değilse:
    • graf tanımında bir hata vardır (integrity check gibi düşünülebilir)

Hızlı Gözlemler (2): Satır Toplamı = Derece

  • Bir satırdaki 1’lerin sayısı, ilgili düğümün derecesidir:

\[ deg(n_i)=\sum_{j=1}^{n} I[i,j] \]

  • Eğer \(deg(n_i)=0\) ise:
    • \(n_i\) izole (isolated) düğümdür
    • grafın geri kalanına bağlı değildir

Test Bağlantısı: İzole Düğüm Ne Anlama Gelebilir?

  • İzole düğüm:
    • ulaşılamayan kod (unreachable code) benzeri bir probleme işaret edebilir
    • ya da “tanımlanmış ama hiç kullanılmayan” bir nesne/ekran/durum olabilir

Komşuluk Matrisleri (Adjacency Matrices)

  • Komşuluk matrisi (adjacency matrix), insidans matrisini tamamlayan güçlü bir gösterimdir.
  • Özellikle “hangi düğüm kime bağlı?” sorusunu doğrudan kodlar.
  • Birçok graf kavramının (yol, bağlılık vb.) temelinde komşuluk bilgisi vardır.

Komşuluk Matrisi

\(G=(V,E)\) grafında \(|V|=m\) düğüm olsun.

Komşuluk matrisi \(A\), boyutu:

\[ m \times m \]

  • satırlar: düğümler
  • sütunlar: düğümler

Matris Elemanı \(A[i,j]\)

  • \(A[i,j]=1\) ise: \(n_i\) ile \(n_j\) arasında bir kenar vardır.
  • Aksi halde:

\[ A[i,j]=0 \]

Özet:

\[ A[i,j]= \begin{cases} 1, & \{n_i,n_j\}\in E \\ 0, & \text{aksi halde} \end{cases} \]

Özellikler (Yönsüz Graf)

  • Simetriktir:

\[ A[i,j]=A[j,i] \]

  • Köşegen elemanlar (basit graf için) sıfırdır:

\[ A[i,i]=0 \]

  • Bir satır toplamı, düğüm derecesini verir:

\[ deg(n_i)=\sum_{j=1}^{m} A[i,j] \]

Şekil 4.1’in Komşuluk Matrisi

\(n_1\) \(n_2\) \(n_3\) \(n_4\) \(n_5\) \(n_6\) \(n_7\)
\(n_1\) 0 1 0 1 0 0 0
\(n_2\) 1 0 0 0 1 0 0
\(n_3\) 0 0 0 1 0 0 0
\(n_4\) 1 0 1 0 0 1 0
\(n_5\) 0 1 0 0 0 0 0
\(n_6\) 0 0 0 1 0 0 0
\(n_7\) 0 0 0 0 0 0 0

Hızlı Gözlem: İzole Düğüm

  • \(n_7\) satırı (ve sütunu) tamamen 0’dır.
  • Bu, \(n_7\)’nin izole olduğunu gösterir:

\[ deg(n_7)=0 \]

  • Test yorumu:
    • ulaşılamayan kod bloğu / hiç bağlanmamış ekran gibi durumlara işaret edebilir.

4.1.4 Yollar (Paths)

  • Graf teorisini testte kullanmanın temel nedeni: yürütme yolları (paths).
  • Kod-temelli test yaklaşımları (özellikle Bölüm 8 ve 9) büyük ölçüde:
    • bir programdaki yol türleri üzerine kuruludur.
  • Burada, “yorumdan bağımsız” (interpretation-free) biçimde graf üzerinde yol tanımlıyoruz.

Tanım: Yol (Path)

Bir yol, kenarlardan oluşan bir dizidir:

\[ p=\langle e_1,e_2,\ldots,e_k\rangle \]

Şart:

  • Ardışık her iki kenar, ortak bir uç noktayı paylaşır:

\[ \forall i\ (1 \le i < k):\ e_i \text{ ve } e_{i+1} \text{ ortak bir düğüm paylaşır} \]

Yolun Gösterimi: Kenar Dizisi vs Düğüm Dizisi

  • Yollar iki şekilde ifade edilebilir:
    • kenar dizisi (edge sequence)
    • düğüm dizisi (node sequence)
  • Pratikte daha yaygın olan: düğüm dizisi ile yazmaktır.

Örnek (düğüm dizisi):

\[ \langle n_1,n_2,n_5\rangle \]

Şekil 4.1 Üzerinde Örnek Yollar

Yol Düğüm Dizisi (Node Sequence) Kenar Dizisi (Edge Sequence)
\(n_1\) ile \(n_5\) arası \(\langle n_1,n_2,n_5\rangle\) \(\langle e_1,e_4\rangle\)
\(n_1\) ile \(n_5\) arası \(\langle n_1,n_4,n_3,n_4,n_1,n_2,n_5\rangle\) \(\langle e_2,e_3,e_3,e_2,e_1,e_4\rangle\)
\(n_3\) ile \(n_2\) arası \(\langle n_3,n_4,n_1,n_2\rangle\) \(\langle e_3,e_2,e_1\rangle\)

Komşuluk Matrisi ile Yol Fikri

  • Komşuluk matrisi \(A\), “tek adım bağlantıları” verir.
  • Matris çarpımıyla:
    • \(A^2\): iki adımlık bağlantılar
    • \(A^k\): \(k\) adımlık bağlantılar
  • Bu, hangi düğümler arasında yol olabileceğini analiz etmeye yarar (detay cebiri burada hedefimiz değil).

Döngü (Loop / Circuit) Notu

  • Bu graf “tam genel” değildir:
    • hiç bir düğümün bir yol içinde tekrar edilmediği durumları göstermez.
  • Eğer bir düğüm yol içinde tekrar ederse:
    • yol bir döngü (loop) / devre (circuit) içerebilir.
  • Örnek: \(n_1 \rightarrow n_4 \rightarrow n_1\) bir döngü üretir.

Bağlılık (Connectedness)

  • “Yol (path)” kavramı, hangi düğümlerin birbirine bağlı (connected) olduğunu tanımlamamızı sağlar.
  • Bu bağlılık fikri, testçiler için güçlü bir basitleştirme aracına dönüşür:
    • grafı parçalara ayırıp ayrı ayrı ele alabiliriz.

Tanım: Bağlı Düğümler

İki düğüm bağlıdır ancak ve ancak aralarında bir yol varsa:

\[ n_i \sim n_j \ \Longleftrightarrow\ \text{$n_i$ ile $n_j$ aynı yol üzerinde yer alabilir} \]

(Pratik okuma: “\(n_i\)’den \(n_j\)’ye giden bir path var.”)

Bağlılık Bir Eşdeğerlik İlişkisidir

Bağlılık (\(\sim\)) düğüm kümesi üzerinde bir eşdeğerlik ilişkisidir:

  1. Yansımalı (reflexive):
    • Her düğüm kendisiyle bağlıdır.

\[ n \sim n \]

  1. Simetrik (symmetric):
    • \(n_i\) ile \(n_j\) bağlıysa, \(n_j\) ile \(n_i\) de bağlıdır.

\[ n_i \sim n_j \Rightarrow n_j \sim n_i \]

  1. Geçişli (transitive):
    • \(n_i\) ile \(n_j\) bağlı ve \(n_j\) ile \(n_k\) bağlıysa, \(n_i\) ile \(n_k\) de bağlıdır.

\[ (n_i \sim n_j)\ \wedge\ (n_j \sim n_k)\ \Rightarrow\ (n_i \sim n_k) \]

Sonuç: Bağlılık → Bölümleme (Partition)

  • Eşdeğerlik ilişkileri bir bölümleme üretir.
  • Bu yüzden bağlılık, düğüm kümesini bağlı bileşenlere (components) ayırır:
    • her düğüm tam olarak bir bileşene aittir
    • bileşenler birbirini örtmez

Bileşen (Component)

Bir grafın bileşeni, bağlı düğümlerin oluşturduğu maksimal kümedir:

  • kümenin içindeki her düğüm çifti bağlıdır
  • kümeye dışarıdan yeni bir düğüm ekleyemezsiniz (maksimal)

Örnek Graf İçin Bileşenler

Şekil 4.1’de iki bileşen vardır:

\[ S_1=\{n_1,n_2,n_3,n_4,n_5,n_6\} \]

\[ S_2=\{n_7\} \]

  • \(n_7\) izole olduğu için tek başına bir bileşendir.

Yoğunlaştırma Grafları (Condensation Graphs)

  • Test için önemli bir basitleştirme:
    • her bileşeni tek bir “özet düğüme” indirgeriz.
  • Bu şekilde elde edilen yeni grafa yoğunlaştırma grafı (condensation graph) denir.

Tanım: Yoğunlaştırma Grafı

Verilen \(G=(V,E)\) grafı için:

  • Her bileşeni tek bir düğümle değiştir.
  • Bileşenler arası kenarları bu yeni düğümler arasında göster.

Sonuç: bileşenleri temsil eden düğümlerden oluşan daha küçük bir graf elde edilir.

Örnek Graf İçin Yoğunlaştırma Grafı (Sezgi)

  • Bileşenler:
    • \(S_1=\{n_1,n_2,n_3,n_4,n_5,n_6\}\)
    • \(S_2=\{n_7\}\)
  • Bu graf yönsüz olduğu için:
    • \(S_2\) izole kalır
    • yoğunlaştırma grafı iki düğümlü ve kopuk olur

Test Yorumu: Bileşenler Ayrı Test Edilebilir

  • Bileşenler “önemli bir anlamda” bağımsızdır:
    • bir bileşende dolaşırken diğerine geçiş yoktur.
  • Bu yüzden:
    • her bileşen için test tasarımı ayrı yapılabilir
    • kapsama ve yol analizi daha yönetilebilir hale gelir

Yoğunlaştırma Grafları (Condensation Graphs)

  • Yoğunlaştırma grafı, testçiler için önemli bir basitleştirme mekanizmasıdır.
  • Temel fikir: Grafın her bileşenini (component) tek bir düğüm gibi ele almak.

Tanım: Yoğunlaştırma Grafı

Verilen bir \(G=(V,E)\) grafı için, yoğunlaştırma grafı şu şekilde elde edilir:

  • \(G\) içindeki her bileşeni, tek bir “yoğunlaştırma düğümü” ile değiştir.
  • Bileşenler arasındaki bağlantıları, bu yeni düğümler arasında göster.

Bu işlem algoritmiktir (ambiguous değildir): bileşenleri bul, sonra grafı küçült.

Önemli Özellik: Sonuç Grafı Tekildir

  • Yoğunlaştırma grafı benzersizdir (unique):
    • aynı \(G\) için aynı bileşenler bulunur
    • dolayısıyla aynı yoğunlaştırma grafı elde edilir
  • Bu, yapılan basitleştirmenin “grafın önemli bir özelliğini” koruduğunu ima eder.

Şekil 4.1 İçin Bileşenler

Önce bileşenler:

\[ S_1=\{n_1,n_2,n_3,n_4,n_5,n_6\} \]

\[ S_2=\{n_7\} \]

Neden “Bileşen Düğümü”ne Kenar Çizmek Mantıksız Olabilir?

Yönsüz (ordinary/undirected) grafın yoğunlaştırma grafında, kenarlar iki nedenle sorun çıkarabilir:

  1. Kenarlar, uç noktası olarak tek tek düğümleri kullanır; küme kullanmaz.
    • yani \(\{n_i,n_j\}\) mantıklıdır ama \(\{S_1,S_2\}\) kenarı, “küme uç noktası” gibi durur.
  2. “Kenar var” demek, iki bileşen arasında bir yol var demektir.
    • bu da bileşenlerin aslında ayrı değil, tek bir büyük bileşen olması anlamına gelir.
    • yani bileşen tanımıyla çelişir (maksimallik bozulur).

Test Yorumu: Bileşenler Bağımsız Test Edilebilir

  • Bileşenler önemli bir anlamda bağımsızdır:
    • bir bileşenin içinde yol varken diğerine geçiş yoktur.
  • Bu yüzden:
    • test tasarımı bileşen bazında bölünebilir
    • kapsam analizi daha yönetilebilir hale gelir

Çevrimsel Karmaşıklık (Cyclomatic Number)

  • Grafların çevrimsel karmaşıklığı test için güçlü sonuçlar doğurur.
  • Bu kavram, özellikle kod temelli testte (path/branch kapsamı) tekrar karşımıza çıkacak.

Tanım: Çevrimsel Sayı \(V(G)\)

Bir grafın çevrimsel sayısı:

\[ V(G)=e-n+p \]

Burada:

  • \(e\): kenar sayısı
  • \(n\): düğüm sayısı
  • \(p\): bileşen (component) sayısı

Örnek Graf İçin Hesap

Şekil 4.1’de:

  • \(e=5\)
  • \(n=7\)
  • \(p=2\)

\[ V(G)=5-7+2=0 \]

Test Notu (İleride Bağlanacak)

  • \(V(G)\) sezgisel olarak “bağımsız yol sayısı / bölge sayısı” gibi yorumlanır.
  • Bölüm 8’de, kodun çevrimsel karmaşıklığı ile test kapsamı arasında doğrudan bağ kuracağız.

Yönlü Graflar (Directed Graphs)

  • Yönlü graflar (directed graphs / digraphs), sıradan (yönsüz) grafların geliştirilmiş halidir:
    • kenarlara yön kazandırır.
  • Yönsüz grafın sırasız çifti \(\{n_i,n_j\}\) iken, yönlü grafın kenarı sıralı ikilidir:

\[ \langle n_i,n_j\rangle \]

  • Bu, “\(n_i\)’den \(n_j\)’ye giden bir kenar” demektir.

Tanım: Yönlü Graf (Digraph)

Bir yönlü graf:

\[ D=(V,E) \]

  • \(V=\{n_1,n_2,\ldots,n_k\}\): sonlu, boş olmayan düğüm kümesi
  • \(E=\{e_1,e_2,\ldots,e_\ell\}\): yönlü kenar kümesi

Her kenar:

\[ e=\langle n_p,n_q\rangle \]

  • \(n_p\): başlangıç (initial / from) düğümü
  • \(n_q\): bitiş (terminal / to) düğümü

Neden Testte Yönlü Graf?

Yönlü graflar, yazılım kavramlarına doğal olarak uyar:

  • sıralı/ardışıl davranış (sequential behavior)
  • zorunlu akış (imperative programming)
  • olay güdümlü akışlar (event-driven)
  • durum geçişleri (state transitions)

Bu nedenle testte yönlü graflar, yönsüz graflardan daha sık kullanılır.

Programlama Dili Bağlantısı

  • Imperative diller (COBOL, FORTRAN, Pascal, C, Java, Ada):
    • deyim sırası yürütmeyi etkiler → doğal model: yönlü graf
  • Deklaratif diller:
    • “yürütme akışı” daha az görünür olabilir
    • bu yüzden sadece “izlenebilir yollar” üzerinden sınırlı graf yaklaşımı kalabilir
  • Not: Yazılımda en yaygın paradigma imperative olduğu için, testte yönlü grafların gücü daha çok kullanılır.

ER Modelleme Notu

  • ER (Entity-Relationship) modellemede de graf kullanılır:
    • varlıklar düğüm, ilişkiler kenar gibi düşünülebilir.
  • Ancak ER grafı çoğu zaman:
    • yönlü akış değil, “ilişki yapısı” temsil eder.
  • Bu nedenle bu bölümün odağı:
    • yürütme sırası içeren yönlü graflardır.

Yönlü Graf Örneği

Yönlü Graf Örneği İçin \(V\) ve \(E\)

Düğüm kümesi:

\[ V=\{n_1,n_2,n_3,n_4,n_5,n_6,n_7\} \]

Kenar kümesi:

\[ E=\{e_1,e_2,e_3,e_4,e_5\} \]

Kenarları Sıralı İkililerle Yazmak

Yönlü graflarda kenar kümesi şu şekilde yazılır:

\[ E=\{\langle n_1,n_2\rangle,\langle n_1,n_4\rangle,\langle n_3,n_4\rangle,\langle n_2,n_5\rangle,\langle n_4,n_6\rangle\} \]

  • Burada sıra önemlidir:
    • \(\langle n_i,n_j\rangle \ne \langle n_j,n_i\rangle\)

Giriş Derecesi ve Çıkış Derecesi (Indegrees & Outdegrees)

  • Yönsüz graf için tek bir derece vardı: \(deg(n)\)
  • Yönlü graf için derece “yön”e göre ayrıştırılır:
    • giriş derecesi (indegree)
    • çıkış derecesi (outdegree)

Tanım: Giriş Derecesi \(indeg(n)\)

Bir düğüm \(n\) için:

  • \(indeg(n)\): \(n\)’de sonlanan (terminal node) kenar sayısıdır.

\[ indeg(n)=|\{\langle x,n\rangle \in E\}| \]

Tanım: Çıkış Derecesi \(outdeg(n)\)

Bir düğüm \(n\) için:

  • \(outdeg(n)\): \(n\)’den başlayan (initial node) kenar sayısıdır.

\[ outdeg(n)=|\{\langle n,y\rangle \in E\}| \]

Bağlantı: Yönsüz Derece ile İlişki

  • Yönlü grafı “yönleri unutulmuş” halde düşünürsek:

\[ deg(n)=indeg(n)+outdeg(n) \]

Yönlü Graf Örneği İçin \(indeg\) ve \(outdeg\)

\[ indeg(n_1)=0 \quad outdeg(n_1)=2 \]

\[ indeg(n_2)=1 \quad outdeg(n_2)=1 \]

\[ indeg(n_3)=0 \quad outdeg(n_3)=1 \]

\[ indeg(n_4)=2 \quad outdeg(n_4)=1 \]

\[ indeg(n_5)=1 \quad outdeg(n_5)=0 \]

\[ indeg(n_6)=1 \quad outdeg(n_6)=0 \]

\[ indeg(n_7)=0 \quad outdeg(n_7)=0 \]

Düğüm Türleri (Types of Nodes)

  • Yönlü graflar, “düğüm rollerini” tanımlamamıza izin verir:
    • başlangıç/bitiş sınırları gibi.

Tanım: Source / Sink / Transfer

Bir düğüm \(n\) için:

  • source node (kaynak):
    • \(indeg(n)=0\)
  • sink node (lavabo/çıkış):
    • \(outdeg(n)=0\)
  • transfer node (aktarıcı / iç düğüm):
    • \(indeg(n)>0 \ \wedge\ outdeg(n)>0\)

Yönlü Graf Örneği Üzerinden Örnekler

  • Source (kaynak): \(n_1\), \(n_3\)
  • Sink (çıkış): \(n_5\), \(n_6\)
  • Transfer (iç düğüm): \(n_2\), \(n_4\)
  • Hem source hem sink olan (izole): \(n_7\)

Test Yorumu: Sınırlar Neyi Temsil Eder?

  • source ve sink düğümler, grafın “dış sınırını” (external boundary) oluşturur.
  • Bir program akış grafında:
    • source genelde giriş noktası (start)
    • sink genelde çıkış/sonlanma (end) noktasıdır
  • Bu sınırların belirlenmesi:
    • yol tabanlı test hedeflerini tanımlamayı kolaylaştırır.

Yönlü Grafın Komşuluk Matrisi (Adjacency Matrix)

  • Kenarlara yön eklemek, komşuluk matrisinin tanımını da değiştirir.
  • (Not) Yönlü graflarda insidans matrisi de değişir; ancak pratikte daha az kullanılır.

Tanım: Komşuluk Matrisi \(A\)

Yönlü graf \(D=(V,E)\) ve \(|V|=m\) olsun.

Komşuluk matrisi:

\[ A=(a(i,j)) \]

boyutu:

\[ m \times m \]

Eleman Tanımı: \(a(i,j)\)

\[ a(i,j)= \begin{cases} 1, & \langle n_i,n_j\rangle \in E \\ 0, & \text{aksi halde} \end{cases} \]

  • Yani: \(n_i\)’den \(n_j\)’ye doğrudan kenar varsa 1.

Önemli Farklar (Yönlü Graf)

  • Matris simetrik olmak zorunda değildir:

\[ a(i,j)\ \ne\ a(j,i) \]

  • Satır toplamı: çıkış derecesi verir:

\[ outdeg(n_i)=\sum_{j=1}^{m} a(i,j) \]

  • Sütun toplamı: giriş derecesi verir:

\[ indeg(n_j)=\sum_{i=1}^{m} a(i,j) \]

Yönlü Graf Örneği İçin Komşuluk Matrisi

\(n_1\) \(n_2\) \(n_3\) \(n_4\) \(n_5\) \(n_6\) \(n_7\)
\(n_1\) 0 1 0 1 0 0 0
\(n_2\) 0 0 0 0 1 0 0
\(n_3\) 0 0 0 1 0 0 0
\(n_4\) 0 0 0 0 0 1 0
\(n_5\) 0 0 0 0 0 0 0
\(n_6\) 0 0 0 0 0 0 0
\(n_7\) 0 0 0 0 0 0 0

Kısa Not: İlişki (Relationship) Kaydı

  • Yönlü graflar sıkça “ilişki yönünü” kaydetmek için kullanılır:
    • örn. soy ağacı (ancestor/descendant)
    • bağımlılık grafı (dependency)
  • Bu tür durumlarda komşuluk matrisi:
    • yönlü yolların varlığını analiz etmeye yardımcı olur.

Yollar ve Yarıyollar (Paths and Semipaths)

  • Yön, “yol” kavramını daha kesin hale getirir:
    • tek yönlü / çift yönlü sokak benzetmesi gibi düşünebilirsiniz.
  • Yönlü graf üzerinde iki farklı kavram kullanacağız:
    • yönlü yol (directed path)
    • yarıyol (semipath)

Tanım: Yönlü Yol (Directed Path)

Bir yönlü yol, kenarlardan oluşan bir dizidir:

\[ p=\langle e_1,e_2,\ldots,e_k\rangle \]

Şart:

  • Ardışık her iki kenar için, ilk kenarın bitiş düğümü ikinci kenarın başlangıç düğümü olmalıdır.

\[ \forall i\ (1 \le i < k):\ terminal(e_i)=initial(e_{i+1}) \]

Tanım: Yarıyol (Semipath)

Bir yarıyol, yön kısıtını gevşetir:

  • Ardışık iki kenar, en az bir düğümü ortak paylaşır.

\[ \forall i\ (1 \le i < k):\ e_i \text{ ve } e_{i+1} \text{ en az bir uç noktayı paylaşır} \]

Sezgi: Yarıyol, “yönleri görmezden gelerek” bağlantı var mı diye bakar.

Tanım: Zincir (Chain)

Bir zincir (chain):

  • düğümlerden oluşan bir dizidir
  • her iç düğüm için:

\[ indeg(n)=1 \ \wedge\ outdeg(n)=1 \]

  • zincirin uç düğümlerinin dereceleri farklı olabilir.

Örnekler (Şekil 4.2 Üzerinden)

Bu örnekte (tümü listelenmemiştir):

  • \(n_1\)’den \(n_6\)’ya bir yönlü yol vardır.
  • \(n_1\) ile \(n_3\) arasında bir yarıyol vardır.
  • \(n_2\) ile \(n_4\) arasında bir yarıyol vardır.
  • \(n_3\) ile \(n_6\) arasında bir yarıyol vardır.

Ulaşılabilirlik Matrisi (Reachability Matrix)

  • Bir uygulamayı yönlü grafla modellediğimizde sıkça şu soruyu sorarız:
    • “\(n_i\) düğümünden başlayınca \(n_j\) düğümüne ulaşabilir miyim?”
  • Bu, testte çok kritik bir yetenektir:
    • hangi yolların mümkün olduğunu analiz etmeyi sağlar.

Tanım: Ulaşılabilirlik Matrisi \(R\)

Yönlü graf \(D=(V,E)\) ve \(|V|=m\) olsun.

Ulaşılabilirlik matrisi:

\[ R=(r(i,j)) \]

boyutu:

\[ m \times m \]

  • \(r(i,j)=1\) ⇔ \(n_i\)’den \(n_j\)’ye en az bir yönlü yol vardır
  • aksi halde \(r(i,j)=0\)

Komşuluk Matrisinden Türetme

Yönlü grafın komşuluk matrisi \(A\) ile:

\[ R = I + A + A^2 + \cdots + A^k \]

  • \(I\): birim matris (identity matrix)
  • \(k\): graf içindeki en uzun yolun uzunluğu (üst sınır)

Yorum: \(A^t\), \(t\) adımda ulaşılabilirliği kodlar.

Şekil 4.2 İçin Ulaşılabilirlik Matrisi

\(n_1\) \(n_2\) \(n_3\) \(n_4\) \(n_5\) \(n_6\) \(n_7\)
\(n_1\) 1 1 0 1 1 1 0
\(n_2\) 0 1 0 0 1 0 0
\(n_3\) 0 0 1 1 0 1 0
\(n_4\) 0 0 0 1 0 1 0
\(n_5\) 0 0 0 0 1 0 0
\(n_6\) 0 0 0 0 0 1 0
\(n_7\) 0 0 0 0 0 0 1

Matris Nasıl Okunur?

    1. satır:
    • \(n_1\)’den \(n_2, n_4, n_5, n_6\)’ya ulaşılabilir
    1. satır:
    • \(n_3\)’ten \(n_4\) ve \(n_6\)’ya ulaşılabilir
  • \(n_7\) izole olduğu için yalnızca kendisine ulaşır.

\(n\)-Bağlılık (\(n\)-Connectedness)

  • Yönsüz graflardaki “bağlılık” fikri, yönlü graflarda daha zengin bir kavrama dönüşür.
  • Yön, iki düğüm arasındaki ilişkinin “ne kadar güçlü” olduğunu ayırt etmemizi sağlar.

Tanım: 0/1/2/3-Bağlılık

Yönlü graf üzerinde iki düğüm \(n_i\) ve \(n_j\) için:

  • 0-bağlı (0-connected):
    • Ne \(n_i \rightarrow n_j\) yolu var, ne de \(n_j \rightarrow n_i\) yolu var.
  • 1-bağlı (1-connected):
    • \(n_i\) ile \(n_j\) arasında yarıyol (semipath) var,
    • ama hiçbir yönde yönlü yol yok.
  • 2-bağlı (2-connected):
    • En az bir yönde (tek yönlü) yönlü yol vardır:
      • \(n_i \rightarrow n_j\) veya \(n_j \rightarrow n_i\)
  • 3-bağlı (3-connected):
    • Her iki yönde de yönlü yol vardır:
      • \(n_i \rightarrow n_j\) ve \(n_j \rightarrow n_i\)
    • (Sezgi: aynı “strongly connected” fikri)

Not: Bu modelde 3’ten büyük bağlılık derecesi yoktur.

Döngülü Yönlü Graf

  • 3-bağlılığı göstermek için örnek grafa bir kenar daha eklenir:
    • graf içinde bir döngü (cycle) oluşur.

Döngülü Yönlü Graf Üzerinde Örnekler

Bu graf için (tümü listelenmemiştir):

  • \(n_1\) ve \(n_7\) 0-bağlı
  • \(n_2\) ve \(n_6\) 1-bağlı
  • \(n_1\) ve \(n_6\) 2-bağlı
  • \(n_3\) ve \(n_4\) 3-bağlı

Tek Yönlü Sokak Sezgisi

  • Tek yönlü sokaklar gibi düşünürsek:
    • “gidiş var, dönüş yok” → 2-bağlı
    • “gidiş de var dönüş de var” → 3-bağlı
  • Örnek sezgi:
    • \(n_2\)’den \(n_6\)’ya gidemezsiniz (tek yön kısıtı yüzünden).

Güçlü Bileşenler (Strong Components)

  • Önceki bölümde tanımlanan \(n\)-bağlılık iki farklı “eşdeğerlik” fikri verir:
    • 1-bağlılık: yönü görmezden gelir → “zayıf bağlılık” (weak connection) sezgisi
    • 3-bağlılık: iki yönlü ulaşılabilirlik → “güçlü bağlılık” (strong connection)
  • 3-bağlı düğümler, yönlü graf için temel parçaları verir: güçlü bileşenler.

Tanım: Güçlü Bileşen (Strong Component)

Yönlü graf üzerinde bir güçlü bileşen:

  • maksimal bir düğüm kümesidir
  • kümedeki her düğüm çifti 3-bağlıdır (iki yönde de yol vardır)

Sezgi:

  • “Aynı kümedeki düğümler arasında gidip gelebiliyorsanız, aynı güçlü bileşendesiniz.”

Döngülü Yönlü Graf İçin Güçlü Bileşenler

Örnek graf için güçlü bileşenler:

\[ S_1=\{n_3,n_4,n_6\} \]

\[ S_2=\{n_1\},\ \{n_2\},\ \{n_5\},\ \{n_7\} \]

  • Tek başına kalan düğümler, kendi başlarına güçlü bileşen sayılır.

Yoğunlaştırma Grafı (Condensation Graph) — Yönlü Durum

  • Güçlü bileşenleri tek düğüme indirgersek yoğunlaştırma grafı elde ederiz.
  • Bu yoğunlaştırma, yönlü graflarda özellikle önemlidir:
    • çünkü döngüleri “tek düğüme” sıkıştırır.

Yoğunlaştırma Grafı

Kritik Özellik: Döngü Yok (DAG)

  • Yoğunlaştırma grafında döngü (cycle) bulunmaz.

  • Eğer döngü olsaydı:

    • o döngüdeki düğümler zaten tek bir güçlü bileşende birleşmiş olurdu.
  • Bu nedenle yoğunlaştırma grafı her zaman bir:

  • DAG (Directed Acyclic Graph)

Test Yorumu: Neden İşe Yarar?

  • Yolların patlaması (path explosion) çoğu zaman:
    • iç içe döngülerden kaynaklanır.
  • Güçlü bileşenleri tek düğüm gibi ele almak:
    • döngü karmaşıklığını “lokal” hale getirir
    • büyük graf üzerinde akıl yürütmeyi kolaylaştırır.

Test İçin Graflar (Graphs for Testing)

  • Bu bölüm şimdiye kadar “yorumdan bağımsız” (interpretation-free) graf kavramlarını verdi.
  • Testte ise graflar genelde belirli bir anlama bağlanır:
    • en yaygın olanı: program grafı (program graph)
  • Ayrıca sistem seviyesi davranış için:
    • sonlu durum makineleri (FSM)
    • statecharts
    • Petri netler gibi modeller de kullanılır.

Program Grafları (Program Graphs)

  • Amaç: yazılım test literatüründe sık geçen “program grafı” kavramını netleştirmek.
  • Programlama dili imperative ise, program grafı doğal olarak yönlü graftır.

Tanım: Program Grafı (Geleneksel)

Imperative bir program için program grafı:

  • düğümler (nodes): program ifadeleri (statements)
  • kenarlar (edges): kontrol akışı (control flow)

Bir kenar vardır:

  • \(n_i \rightarrow n_j\)
  • eğer \(n_i\) ifadesinden sonra \(n_j\) ifadesi hemen yürütülebiliyorsa.

Tanım: Program Grafı (İyileştirilmiş)

İyileştirilmiş tanım, düğümleri daha esnek yapar:

  • düğümler: ifadeler veya ifade parçaları (statement fragments)
  • kenarlar: kontrol akışı

Amaç:

  • karmaşık ifadeleri (özellikle koşullu/çok parçalı ifadeleri) daha iyi modellemek.

Notasyon Konvansiyonu

  • “İfade” yerine, hem ifadeyi hem de ifade parçasını kapsayan ortak terim kullanacağız:

  • statement (ifade)

  • Böylece “statement vs fragment” ayrımı akışı bölmez, notasyon sade kalır.

Yapılandırılmış Programlama Yapıları ve Digraph

  • Yapılandırılmış programlama yapıları:
    • sıra (sequence)
    • seçim (if / if-then-else / case)
    • tekrar (loops)
  • Bu yapıların her biri, program grafında tipik bir “alt yapı” (subgraph) üretir.

Yapılandırılmış Yapıların Digraph’ları

Test Açısından Neden Önemli?

  • Gerçek program grafı:
    • basit yapıların birleşimidir (birleştirme / zincirleme)
  • Özellikle:
    • döngüler (loops)
    • karar noktaları (decisions) yol sayısını hızla büyütür (path explosion).
  • Bu yüzden program grafı, kod-temelli testte:
    • yol hedeflerini tanımlamak
    • kapsama metriklerini konuşmak için temel araçtır.

Ek Not: “Mümkün Yol” vs “Anlamlı Yol”

  • Program grafında teorik olarak görünen her yol, semantik olarak gerçekten çalışabilir olmayabilir.
  • Bu ayrım (feasible vs infeasible paths) testte kritiktir; detayını ileride tekrar ele alacağız.

Sonlu Durum Makineleri (Finite State Machines)

  • Sonlu durum makineleri (FSM), gereksinim belirtiminde yaygın bir gösterimdir.
  • Yapılandırılmış analiz (structured analysis) ve gerçek-zamanlı sistemler:
    • çoğu zaman FSM veya benzeri bir modeli içerir.
  • FSM, program grafına benzer biçimde bir yönlü graf gibi görülebilir:
    • düğümler: durumlar (states)
    • kenarlar: geçişler (transitions)

FSM’de Etiketleme: Olay / Aksiyon

  • Bir geçişin üzerinde genelde şu biçimde bir etiket vardır:

\[ e/a \]

  • \(e\) (event): geçişi tetikleyen olay
  • \(a\) (action): geçiş sırasında yapılan aksiyon

Not: Aksiyon her zaman zorunlu değildir; olay gerçekleşse bile “aksiyon yok” olabilir.

Garaj Kapısı Kontrolcüsü için FSM

Olaylar (Input Events)

Bu FSM’de kullanılan örnek olaylar:

  • \(e_1\): kontrol düğmesine basıldı
  • \(e_2\): aşağı yönde yol sonuna ulaşıldı
  • \(e_3\): aşağı yönde yol sonuna ulaşıldı (track hit)
  • \(e_4\): yukarı yönde yol sonuna ulaşıldı
  • \(e_5\): engel algılandı
  • \(e_6\): ışık bariyeri kesildi

Aksiyonlar (Output Events / Actions)

Geçişlerdeki örnek aksiyonlar:

  • \(a_1\): motoru aşağı başlat
  • \(a_2\): motoru yukarı başlat
  • \(a_3\): motoru durdur
  • \(a_4\): motora güç ver
  • \(a_5\): kapı açılmaya devam eder
  • \(a_6\): kapı kapanmaya devam eder

FSM Çalıştırımı: Başlangıç Durumu ve Yürütme

  • FSM’in bir başlangıç durumu (initial state) vardır.
  • Zaman ilerledikçe olaylar oluşur ve makine bir geçiş izler:
    • olay dizisi → durum dizisi (yol) seçer
  • Bu yüzden FSM testi, doğal olarak:
    • olay dizileri
    • geçiş kapsaması
    • durum kapsaması üzerine kurulur.

Test Açısından Notlar

  • FSM’ler:
    • sistem seviyesi davranışı netleştirir
    • “hangi olay hangi durumda ne yapar?” sorusunu görünür kılar
  • Test tasarımında tipik hedefler:
    • her geçişi en az bir kez çalıştırmak
    • kritik döngüleri ve güvenlik geçişlerini zorlamak

Petri Ağları (Petri Nets)

  • Petri ağları, Carl Adam Petri’nin doktora çalışmasından (1963) gelir.
  • Amaç: eşzamanlılık (concurrency) ve dağıtık işlem içeren sistemleri modellemek.
  • Petri ağı, özel bir yönlü graf türüdür:
    • iki parçalı (bipartite) yönlü graf

Tanım: İki Parçalı (Bipartite) Yönlü Graf

  • Düğümler iki ayrık kümeye ayrılır:
    • \(P\) (places / yerler)
    • \(T\) (transitions / geçişler)
  • Kenarlar sadece şu yönlerde olabilir:
    • \(P \rightarrow T\) (girdi kenarları)
    • \(T \rightarrow P\) (çıktı kenarları)

Aynı türden düğümler arasında (P→P veya T→T) kenar yoktur.

Tanım: Petri Ağı

Bir Petri ağı şu beşli ile tanımlanır:

\[ N=(P,T,In,Out) \]

  • \(P\) ve \(T\) ayrık düğüm kümeleridir
  • \(In \subseteq P \times T\) (place → transition)
  • \(Out \subseteq T \times P\) (transition → place)

Örnek Petri Ağı (Şekil 4.7)

Örnek İçin Kümeler

Şekil 4.7 için:

\[ P=\{p_1,p_2,p_3,p_4,p_5\} \]

\[ T=\{t_1,t_2,t_3\} \]

\[ In=\{\langle p_1,t_1\rangle,\langle p_5,t_1\rangle,\langle p_2,t_2\rangle,\langle p_5,t_2\rangle,\langle p_3,t_3\rangle\} \]

\[ Out=\{\langle t_1,p_3\rangle,\langle t_2,p_4\rangle,\langle t_3,p_4\rangle\} \]

Tanım: İşaretli Petri Ağı (Marked Petri Net)

Bir işaretli Petri ağı:

\[ M=(P,T,In,Out,m) \]

  • \((P,T,In,Out)\) bir Petri ağıdır
  • \(m\) bir işaretleme (marking) fonksiyonudur:
    • her place için token sayısını verir
    • \(m: P \rightarrow \mathbb{Z}_{\ge 0}\)

Token (Jeton) Sezgisi

  • Token’lar (tokens) place’lerin içinde duran soyut “işaretler”dir.
  • \(m(p_i)\):
    • \(p_i\) yerindeki token sayısını gösterir.
  • Token yorumu bağlama göre değişebilir:
    • kaynak sayısı
    • “doğru/aktif” olma durumu
    • kuyruktaki iş sayısı, vb.

İşaretli Örnek (Şekil 4.8)

Tanım: Etkin (Enabled) Geçiş

Bir geçiş \(t\) etkindir (enabled) eğer:

  • \(t\)’nin tüm giriş place’lerinde en az bir token varsa.

Tanım: Ateşleme (Firing)

Etkin bir geçiş \(t\) ateşlendiğinde (fires):

  • her giriş place’inden 1 token çıkar
  • her çıkış place’ine 1 token eklenir

Bu işlem, sistemin “bir adım” ilerlemesi gibi okunur.

Şekil 4.9: \(t_2\) Ateşlemeden Önce / Sonra

Petri Ağı Test Yorumu

  • FSM’ler sıralı akışları iyi temsil eder.
  • Petri ağları ise:
    • eşzamanlılık,
    • yarış durumları (conflict),
    • kaynak paylaşımı gibi durumları modellemede daha uygundur.
  • Not: FSM’ler, belirli koşullarda Petri ağlarının özel bir durumu gibi görülebilir.

Olay Güdümlü Petri Ağları (Event-Driven Petri Nets — EDPN)

  • Temel Petri ağlarına iki ek ile EDPN (Event-Driven Petri Nets) elde edilir:
    1. Olay güdümlü sistemleri daha yakından ifade eder.
    2. Petri ağını, OO uygulamalardaki nesne etkileşimi gibi senaryolara daha uygun hale getirir.
  • Sonuç: Yazılım gereksinimlerine daha “operasyonel” (çalıştırılabilir) bir bakış sağlar.

Tanım: EDPN Yapısı

Bir EDPN, üç parçalı (tripartite) yönlü bir graftır:

\[ (P, D, S, In, Out) \]

  • \(P\): port olayları (port events)
  • \(D\): veri yerleri (data places)
  • \(S\): geçişler (transitions)

In ve Out Kümeleri

  • \(In\), \((P \cup D)\)’den \(S\)’ye giden sıralı ikililer kümesidir:

\[ In \subseteq (P \cup D)\times S \]

  • \(Out\), \(S\)’den \((P \cup D)\)’ye giden sıralı ikililer kümesidir:

\[ Out \subseteq S \times (P \cup D) \]

EDPN’de “Thread” (İş Parçacığı) Sezgisi

  • \(S\) kümesindeki geçişler, sıradan Petri netlerdeki gibi yorumlanır.
  • Bir thread, \(S\) içindeki geçişlerden oluşan bir dizidir.
  • Port olayları (\(P\)) ve veri yerleri (\(D\)):
    • geçişlerin giriş/çıkışları olarak görev yapar.

EDPN Örneği

Şekil 4.10 Öğeleri (Özet)

  • Port giriş olayları:
    • \(p_3\): kadranı saat yönünde çevirme
    • \(p_4\): kadranı saat yönünün tersine çevirme
  • Veri yerleri (kadran konumu):
    • \(d_5\): konum 1
    • \(d_6\): konum 2
    • \(d_7\): konum 3
  • Geçişler:
    • \(s_7\): \(d_5 \rightarrow d_6\)
    • \(s_8\): \(d_6 \rightarrow d_7\)
    • \(s_9\): \(d_7 \rightarrow d_6\)
    • \(s_{10}\): \(d_6 \rightarrow d_5\)

Tanım: EDPN İşaretleme (Marking)

Bir EDPN işaretlemesi \(M\):

  • zaman içinde değişen bir durum dizisi gibi düşünülebilir.
  • her adım bir \(m_i\) işaretlemesi olsun:

\[ M=\langle m_1,m_2,\ldots,m_k\rangle \]

  • her \(m_i\), \(P\) ve \(D\) üzerindeki token dağılımını (snapshot) temsil eder.

EDPN’de Etkinlik (Enabled) ve Ateşleme (Firing)

  • Temel fikir Petri net ile aynıdır:
    • bir geçişin girişlerinde gereken token’lar varsa enabled olur,
    • ateşlenince girişlerden token eksilir, çıkışlara token eklenir.
  • EDPN’de kritik fark:
    • olay sıraları (event sequence) doğrudan modele taşınır.

Olay Sessizliği (Event Quiescence) ve Deadlock

  • EDPN’lerde:
    • hiçbir geçiş enabled değilse “olay sessizliği” (event quiescence) oluşur.
  • Bu durum, klasik Petri netlerdeki “deadlock” sezgisine yakındır:
    • sistem ilerleyemez, olaylar akışı durur.

Test Bağlantısı

  • EDPN, FSM’den daha güçlüdür:
    • olay + veri durumu birlikte modellenir.
  • Testte EDPN ile:
    • olay dizileri üzerinden yol seçimi
    • etkin geçişlerin izlenmesi
    • sessizlik/deadlock durumlarının aranması hedeflenebilir.

StateCharts

  • David Harel’in geliştirdiği StateChart notasyonu, iki şeyi birlikte hedefler:
    • hiyerarşiyi (iç içe durumlar) göstermek
    • eşzamanlılığı (concurrency) ifade etmek
  • Böylece klasik FSM’lerdeki iki temel problem ele alınır:
    • state explosion (durum patlaması)
    • karmaşık eşzamanlı akışlar

“Blob” Kavramı (Temel Yapı Taşı)

  • Harel, StateChart’ın temel birimini blob olarak adlandırır.
  • Bir blob:
    • bir veya daha çok durumu içerebilir
    • blob içindeki düğümler kenarlarla bağlanmış olabilir
  • Sezgi:
    • blob = “bir alt sistem / bir alt durum kümesi” gibi düşünülebilir.

StateChart’ta Blob’lar

Hiyerarşi: Üst Durum ve Alt Durumlar

  • Blob’lar sayesinde durumlar hiyerarşik modellenir:
    • üst durum: \(A\)
    • alt durumlar: \(B\), \(C\) (A’nın içinde)
  • Grafik yorumu:
    • düğümler “durumlar”, kenarlar “geçişler” olarak okunur.

Başlangıç (Initial State) Gösterimi

  • StateChart’ta “başlangıç” özel bir işaretle gösterilir:
    • bir kenar, “kaynağı olmayan” bir noktadan başlar.
  • Bu kenar, StateChart’ın başlangıç durumunu işaret eder.

Başlangıç Durumu

Varsayılan Giriş (Default Entry) Mantığı

  • Bir üst duruma girildiğinde (örn. \(A\)):
    • alt durumlardan hangisinin aktif olacağı net olmalıdır.
  • Konvansiyon:
    • üst durumun sınırında (contour) başlayan bir geçiş, varsayılan alt durumu belirler.

Alt Duruma Varsayılan Giriş

Eşzamanlı Durumlar (Concurrent States)

  • StateChart’ta bir durum içinde paralel bölgeler tanımlanabilir:
    • aynı anda birden fazla alt durum aktif olabilir.
  • Bu, Petri netlerdeki “birden çok place’in işaretli olması” sezgisine benzer.

Eşzamanlı Durumlar

Test Perspektifi: Neden Önemli?

  • StateChart’lar, FSM’e göre daha ifade gücü yüksek olduğu için:
    • gereksinimlerdeki karmaşık akışları daha doğru yakalar.
  • Ancak test açısından sonuç:
    • hiyerarşi + eşzamanlılık → kapsam hedeflerini planlamak daha kritiktir
    • özellikle “paralel bölgelerin kombinasyonları” durum patlaması üretebilir.

Alıştırmalar (Exercises)

  1. Bir graf üzerinde “yol uzunluğu” için bir tanım öner.
  2. Şekil 4.1’de \(n_3\) ile \(n_6\) arasına bir kenar eklersen hangi döngüler oluşur?
  3. 3-bağlılığın bir eşdeğerlik ilişkisi olduğunu göster.
  4. Yapılandırılmış programlama yapılarına ait grafların çevrimsel karmaşıklığını hesapla.
  5. Şekil 4.15’teki yönlü graflar için çevrimsel karmaşıklığı hesapla ve değişimi açıkla.
  6. İnsanları düğüm, “konuşuyor” ilişkisini kenar alarak sosyal etkileşim grafı kur; “popülerlik, klikler, yalnızlar” gibi kavramların graf karşılıklarını tartış.

Şekil 4.15: Alıştırma Grafları