Đồ thị luồng dữ liệu (data flow graph) là mộl sự mở rộng của đồ thị luồng điều khiển bằng cách bổ sung thêm xử lí dữ liệu trong chương trình. Việc xử lí dữ liệu trong một chương trình được thực hiện thông qua sự định nghĩa và sử dụng các biến. Định nghĩa được kí hiệu def, là vị trí mà giá trị của biến được lưu trữ trong bộ nhớ (lệnh gán truyền tham số...). Sử dụng, được kí hiệu là use, là vị trí mà biến được truy cập.
Để xây dựng đồ thị luồng dữ liệu, chúng ta tích hợp định nghĩa và sử dụng các biến tại mỗi đỉnh hay cung của đồ thị luồng điều khiển. Chúng ta kí hiệu :
+ def(n): tập các biến được định nghĩa tại đỉnh n. + def(e): tập các biển được định nghĩa tại cung e. + use(n): tập các biến được sử dụng tại đỉnh n, + use(e): tập các biến được sử dụng tại cung e.
Hình 3.24. Minh hoạ đồ thị luồng dử liệu với các định nghĩa và sử dụng biến tại các đỉnh và cung
Hình 3.24. Minh hoạđồ thị luồng dử liệu
Trong đồ thị này các biến liên quan đến đỉnh quyết định được xem là sử dụng tại các cung liên quan, như thế các biến a và b được sử dụng tại các cung (n1,n2) và (n1,n3)
Một trong những khái niệm cơ bản khi thảo luận các tiêu chí bao phủ dựa trên đồ thị luồng dữ liệu là sự định nghĩa biến có thể hoặc không thể đạt đến được sự sử dụng của biến đó. Lí do thường gặp là định nghĩa biến v tại trí trí li, (một vị trí có thể là một đỉnh hay cung) sẽ không đạt đến được sự sử dụng biến tại một vị trí li, bởi vì không có lộ trình từ li đến li. Một lí do khác có thể giá trị biến bịthay đổi trước khi nó đạt đến được sự sử dụng. Như thế một lộ trình từ li đến li, là định nghĩa rõ, được ký hiệu def-clear, đối với biến v nếu đối với mọi đỉnh nk và mọi cung ek trên lộ trình, k≠i và k≠j, v không thuộc def(nk và def(ek). Nghĩa là, không có vị trí nào giữa li và lj, thay đổi giá trị của biến. Nếu một lộ trình là def-clear đi từ li đến lj đối với biến v chúng ta nói rằng định nghĩa của biến v tại li đạt đến được sử dụng tại lj
Chúng ta định nghĩa lộ trình định nghĩa sử dụng, được ký hiệu du-path, đối với một biến v là một lộ trình def-clear đối với biến v từ vị trí li mà v thuộc def(li) đến vị trí lj mà v thuộc user(lj). Lưu ý rằng một du-path luôn gắn liền với một biến v nhất định. Chẳng hạn, đối với đồ thị trong hình 4.16 lộ trình [n0,n1,n2] là du-path đối với biến b, bởi vì biến b được đỉnh n0, được sử dụng tại đỉnh n2 và trên lộ trình này biến v không được định nghĩa lại.
Tiêu chí bao phủ cho đồ thì luồng dữ liệu sẽ được định nghĩa dựa trên khái niệm du-path. Vì vậy, trước hết chúng ta chia các du-path thành các du-path thành các
nhóm, để đơn giản, chúng ta chỉ xem xét du-path từ một đỉnh đến một đỉnh nhóm du- path thứ nhất liên quan đến định nghĩa biến, gồm các du-path đối với một biến được định nghĩa tại một đỉnh gọi du (n1,v) là tập các du-path đối với biến v, xuất phát từ đỉnh ni, nhóm du-path đối với một biến được định nghĩa tại một đỉnh và được sử dụng tại một đỉnh khách. Gọi du (ni,nj, v là tập các du-path đối với biến v xuất phát từ đỉnh ni và kết thúc tại đỉnh nj. Chúng ta dễ dàng nhận thấy quan hệ giữa du(ni,v) và du(ni,nj,v) : du(ni,y = Un, du(ni,nj,y).
Để minh họa các nhóm du-path, chúng ta xem xét các du-path đối với biến a trong hình 4.16 có các du-path đối với biến a từđỉnh n0-đỉnh n2 và các cung (n1,n2 và (n1,n3).
Các du-path đối với biến a tại đỉnh n0 gồm :
du(n0,a) = {[n0,n1,n2],[n0,(n1,n2)], n0,(n1,n3)]}
Tập các du-path này có thể chia thành các du-path theo vị trí (đỉnh hoặc cung kết thúc :
du (n0,n2,a)={[n0,n1,n2]}
du (n0(n1,n2),a)={[n0,n1,n2]}
du (n1,n2,a)={[n0,n1,n3]}
Bây giờ, chúng ta sẽ định nghĩa một số các tiêu chí bao phủ cơ bản dự trên đồ thị luồn dữ liệu