Các lượt nộp
    Danh sách bài
    Trang chủ
    Báo lỗi

    solution

    Đề bài: [Trình biên dịch] Phân loại định nghĩa tới được

    Cho một đồ thị luồng điều khiển (CFG) gồm nnn khối cơ bản đánh số 1..n1..n1..n và mmm cạnh có hướng. Khối 111 là khối bắt đầu (entry): quy ước IN[1]=∅IN[1] = \emptysetIN[1]=∅ luôn luôn, bất kể có cạnh nào đi vào khối 1 hay không.

    Mỗi khối iii có một danh sách các định nghĩa (assignment) xảy ra theo thứ tự bên trong khối; mỗi định nghĩa là một cặp (tên biến, id định nghĩa) với id là số nguyên duy nhất toàn chương trình (cho sẵn trong input). Định nghĩa cuối cùng của mỗi biến trong khối iii mới được khối đó "sinh ra" ở đầu ra: GEN[i]GEN[i]GEN[i] = tập id của định nghĩa CUỐI CÙNG (trong khối iii) của mỗi biến được định nghĩa trong khối iii. KILL[i]KILL[i]KILL[i] = tập TẤT CẢ các id định nghĩa (ở BẤT KỲ khối nào trong toàn chương trình, kể cả khối iii) của các biến mà khối iii có định nghĩa, TRỪ đi các id thuộc GEN[i]GEN[i]GEN[i].

    Bài toán định nghĩa tới được (reaching definitions) được tính bằng lặp tới điểm cố định:

    IN[i]=⋃p→iOUT[p](IN[1]=∅),OUT[i]=GEN[i]∪(IN[i]∖KILL[i])IN[i] = \bigcup_{p \to i} OUT[p] \quad (IN[1] = \emptyset), \qquad OUT[i] = GEN[i] \cup (IN[i] \setminus KILL[i])IN[i]=⋃p→i​OUT[p](IN[1]=∅),OUT[i]=GEN[i]∪(IN[i]∖KILL[i])

    Với mỗi truy vấn gồm một khối qqq và một biến vvv, hãy cho biết trạng thái của biến vvv tại đầu vào (IN[q]IN[q]IN[q]) của khối qqq khi đạt điểm cố định — đây chính là thông tin trình biên dịch cần để quyết định có thể lan truyền hằng số/copy an toàn tại điểm đó hay không:

    • Nếu không có định nghĩa nào của vvv trong IN[q]IN[q]IN[q]: in UNDEFINED.
    • Nếu có đúng một định nghĩa của vvv trong IN[q]IN[q]IN[q]: in UNIQUE <id>.
    • Nếu có từ hai định nghĩa trở lên của vvv trong IN[q]IN[q]IN[q] (không an toàn để suy ra một hằng số/nguồn duy nhất): in AMBIGUOUS <k> <id_1> <id_2> ... <id_k> với kkk là số định nghĩa và các id liệt kê tăng dần.
    • Định dạng đầu vào:

      Dòng 1: hai số nguyên nnn, mmm (1≤n≤2001 \le n \le 2001≤n≤200, 0≤m≤5000 \le m \le 5000≤m≤500). mmm dòng tiếp theo, mỗi dòng "ppp qqq" là một cạnh có hướng p→qp \to qp→q (1≤p,q≤n1 \le p, q \le n1≤p,q≤n). Tiếp theo nnn dòng, dòng thứ iii mô tả khối iii: số nguyên kik_iki​ (số định nghĩa trong khối) rồi kik_iki​ cặp "tên_biến id" theo đúng thứ tự xuất hiện trong khối (nếu ki=0k_i = 0ki​=0, chỉ có số 0). Mọi id định nghĩa trên toàn chương trình đôi một khác nhau. Dòng tiếp theo: số nguyên QQQ — số truy vấn. QQQ dòng sau, mỗi dòng "qqq vvv" là một truy vấn (khối, tên biến).

    • Định dạng đầu ra:

      In ra đúng QQQ dòng, mỗi dòng là kết quả truy vấn tương ứng theo đúng thứ tự, ở một trong ba dạng UNDEFINED, UNIQUE <id>, hoặc AMBIGUOUS <k> <id_1> ... <id_k> như mô tả.

    Ví dụ:

    Đầu vào:

    4 4
    1 2
    1 3
    2 4
    3 4
    2 x 1 y 2
    1 x 3
    1 x 4
    0
    2
    4 x
    4 y
    

    Đầu ra:

    AMBIGUOUS 2 3 4
    UNIQUE 2
    

    Đầu vào:

    1 0
    2 x 1 x 2
    1
    1 x
    

    Đầu ra:

    UNDEFINED
    

    Đang tải editor...