Wei Yao

137 papers A* 7A 2B 2C 2Misc 1Journal 97Unranked 26
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Shen Chen, Chaohou Liu, Wei Yao, Jisong Wang, Shuaipo Guo, Zeng Liu, Jinjun Liu
2026 J jnl
Int. J. Hum. Comput. Interact.
Suzhou Wei, Jiahao Li, Yilong Zhang, Xiao Liang, Haopeng Sun, Yan Zhang, Wei Yao, Shusong Xing, Haining Zhang, Binhui Wang
2026 J jnl
Pervasive Mob. Comput.
Jiahao Li, Yilong Zhang, Suzhou Wei, Zibo Zhang, Xiaolei Hong, Wei Yao, Yiyu Yao, Shusong Xing, Haining Zhang, Binhui Wang
2026 J jnl
Comput. Appl. Math.
Yaoliang Xu, Wei Yao, Lingqiang Li
2026 A* conf
AAAI
Wei Yao, Yunlian Sun, Hongwen Zhang, Yebin Liu, Jinhui Tang
2026 J jnl
CoRR
Chao Yin, Hongzhe Yue, Qing Han, Difeng Hu, Zhenyu Liang, Fangzhou Lin, Bing Sun, Boyu Wang, Mingkai Li, Wei Yao, Jack C. P. Cheng
2026 J jnl
IEEE Internet Things J.
Haiyi Wu, Kai Zhao, Yong Xiong, Wei Yao, Xu Chi
2026 J jnl
CoRR
Chao Yin, Qing Han, Zhiwei Hou, Yue Liu, Anjin Dai, Hongda Hu, Ji Yang, Wei Yao
2025 J jnl
CoRR
Yaowei Bai, Ruiheng Zhang, Yu Lei, Xuhua Duan, Jingfeng Yao, Shuguang Ju, Chaoyang Wang, Wei Yao, Yiwan Guo, Guilin Zhang, Chao Wan, Qian Yuan, Lei Chen, Wenjuan Tang, Biqiang Zhu, Xinggang Wang, Tao Sun, Wei Zhou, Dacheng Tao, Yongchao Xu, Chuansheng Zheng, Huangxuan Zhao, Bo Du
2025 J jnl
CoRR
Tianshu Chu, Dachuan Xu, Wei Yao, Chengming Yu, Jin Zhang
2025 J jnl
IEEE Trans. Affect. Comput.
Fei Ma, Yifan Xie, Yukan Li, Ying He, Yi Zhang, Hongwei Ren, Zhou Liu, Wei Yao, Fuji Ren, Fei Richard Yu, Shiguang Ni
2025 J jnl
Swarm Evol. Comput.
Wei Yao, Xin Shen, Guo Zhang, Zezhong Lu, Jiaying Wang, Yanjie Song, Zhiwei Li
2025 J jnl
Int. J. Imaging Syst. Technol.
Huangchi Liu, Xiaoxiao Chen, Wenqian Zhang, Wei Yao, Shengzhou Xu
2025 J jnl
CoRR
Shen Chen, Yanlong Li, Jiamin Cui, Wei Yao, Jisong Wang, Yixin Tian, Chaohou Liu, Yang Yang, Jiaxi Ying, Zeng Liu, Jinjun Liu
2025 J jnl
Univers. Access Inf. Soc.
Wei Yao, Lei Wang, Deyang Liu
2025 J jnl
Appl. Math. Lett.
Wei Yao, Pin Lyu, Seakweng Vong
2025 J jnl
Signal Image Video Process.
Tianhong Luo, Wei Yao, Shuang Liang, Xiangyu Ma, Yang Li, Qi Tuo
2025 A* conf
EMNLP
Wenyu Qiu, Yuxiong Wang, Jiajun Tan, Hanchao Hou, Qinda Liu, Wei Yao, Shiguang Ni
2025 A* conf
ICML
Youran Dong, Junfeng Yang, Wei Yao, Jin Zhang
2025 J jnl
CoRR
Youran Dong, Junfeng Yang, Wei Yao, Jin Zhang
2025 A conf
ICME
Weixiang Zhang, Wei Yao, Shuzhao Xie, Shijia Ge, Chen Tang, Zhi Wang
2025 J jnl
Signal Image Video Process.
Xingzhu Liang, Wei Yao, Xianjin Fang, Chunjiong Zhang
2025 J jnl
CoRR
Yaowei Bai, Ruiheng Zhang, Yu Lei, Jingfeng Yao, Shuguang Ju, Chaoyang Wang, Wei Yao, Yiwan Guo, Guilin Zhang, Chao Wan, Qian Yuan, Xuhua Duan, Xinggang Wang, Tao Sun, Yongchao Xu, Chuansheng Zheng, Huangxuan Zhao, Bo Du
2025 J jnl
CoRR
Wei Yao, Yunlian Sun, Hongwen Zhang, Yebin Liu, Jinhui Tang
2025 J jnl
CoRR
Guoqing Wang, Sunhao Dai, Guangze Ye, Zeyu Gan, Wei Yao, Yong Deng, Xiaofeng Wu, Zhenzhe Ying
2025 J jnl
IEEE Trans. Geosci. Remote. Sens.
Xin Shen, Zezhong Lu, Litao Li, Yaxin Chen, Xufei Li, Jiaying Wang, Wei Yao
2025 J jnl
Informatica (Slovenia)
Wei Yao, Jiajun Zhu Zhu
2025 A* conf
ICLR
Wei Yao, Haian Yin, Shangzhi Zeng, Jin Zhang
2025 J jnl
CoRR
Wei Yao, Yunlian Sun, Chang Liu, Hongwen Zhang, Jinhui Tang
2025 J jnl
Soft Comput.
Wei Yao, Chang-Jie Zhou
2025 J jnl
CoRR
Wei Yao, Shuzhao Xie, Letian Li, Weixiang Zhang, Zhixin Lai, Shiqi Dai, Ke Zhang, Zhi Wang
2025 J jnl
CoRR
Yifei Jia, Shiyu Cheng, Yu Dong, Guan Li, Dong Tian, Ruixiao Peng, Xuyi Lu, Yu Wang, Wei Yao, Guihua Shan
2025 J jnl
Educ. Inf. Technol.
Wei Yao, Hanchao Hou, Peng Yang, Shiguang Ni
2025 A* conf
ICLR
Sheng Fang, Yongjin Liu, Wei Yao, Chengming Yu, Jin Zhang
2025 J jnl
CoRR
Sheng Fang, Yong-Jin Liu, Wei Yao, Chengming Yu, Jin Zhang
2024 J jnl
CoRR
Fei Ma, Yukan Li, Yifan Xie, Ying He, Yi Zhang, Hongwei Ren, Zhou Liu, Wei Yao, Fuji Ren, Fei Richard Yu, Shiguang Ni
2024 J jnl
Int. J. Artif. Intell. Tools
Yuanyuan Lin, Chao Huang, Xi Zhang, Xin Li, Wei Yao
2024 conf
CIS-RAM
Jiguang Li, Nandu Li, William Holderbaum, Wei Yao
2024 J jnl
Computer
Wei Yao, Nicholas Gorlewski, Fadi P. Deek, Guiling Wang
2024 A* conf
ICLR
Wei Yao, Chengming Yu, Shangzhi Zeng, Jin Zhang
2024 J jnl
CoRR
Wei Yao, Chengming Yu, Shangzhi Zeng, Jin Zhang
2024 conf
ICAC
Jiguang Li, Wei Yao
2024 J jnl
Remote. Sens.
Zuojun Zheng, Jianghao Yuan, Wei Yao, Hongxun Yao, Qingzhi Liu, Leifeng Guo
2024 conf
ICCT
Wei Yao, Shengliang Peng, Libo Chen, Zhi-Bin Zhang
2024 J jnl
IEEE Access
Yayan Pan, Fangying Dong, Wei Yao, Xiaoqin Meng, Yongan Xu
2024 J jnl
CoRR
Weixiang Zhang, Shuzhao Xie, Shijia Ge, Wei Yao, Chen Tang, Zhi Wang
2024 J jnl
Cybern. Syst.
Wei Yao, Lei Su, Yan Wang, Jing Wang, Hao Shen
2024 conf
ICPR (28)
Xu Shi, Wei Yao, Chuanchen Luo, Junran Peng, Hongwen Zhang, Yunlian Sun
2024 J jnl
CoRR
A M. Muntasir Rahman, Junyi Ye, Wei Yao, Wenpeng Yin, Grace Guiling Wang
2024 J jnl
Int. J. Hum. Comput. Interact.
Binhui Wang, BaiMa QvZhen, Zibo Zhang, Yang Li, Wei Yao, Suzhou Wei, Shusong Xing
2024 J jnl
Comput. Informatics
Wei Yao, Shen Chen, Jiamin Cui, Yaolin Lou
2024 J jnl
Eng. Appl. Artif. Intell.
Shaoying Li, Wei Yao, Yuan Gao, Yinchi Ma, Bo Liu
2024 J jnl
Comput. Electron. Agric.
Bangyu Wang, Jianxi Zhu, Xinlong Chai, Bo Liu, Guangwei Zhang, Wei Yao
2024 conf
DASFAA (6)
Jiakai Tang, Zuxu Sun, Wei Yao, Xu Chen
2024 A* conf
ICML
Tianshu Chu, Dachuan Xu, Wei Yao, Jin Zhang
2024 J jnl
CoRR
Tianshu Chu, Dachuan Xu, Wei Yao, Jin Zhang
2024 J jnl
IEEE Trans. Circuits Syst. Video Technol.
Wei Yao, Hongwen Zhang, Yunlian Sun, Jinhui Tang
2024 J jnl
CoRR
Wei Yao, Hongwen Zhang, Yunlian Sun, Jinhui Tang
2024 conf
EC-TEL (2)
Marshall An, Mufei He, Wei Yao, John C. Stamper
2024 J jnl
Int. J. Appl. Earth Obs. Geoinformation
Zezhong Lu, Xin Shen, Deren Li, Shaoyuan Cheng, Jiaying Wang, Wei Yao
2024 J jnl
Expert Syst. Appl.
Qingsong Song, Wei Yao, Haojiang Tian, Yidan Guo, Ravie Chandren Muniyandi, Yisheng An
2023 conf
ICONIP (7)
Jiajie Luo, Lin Xiao, Ping Tan, Jiguang Li, Wei Yao, Jichun Li
2023 J jnl
J. Signal Process. Syst.
Bowei Qi, YuanYuan Li, Wei Yao, Zhibo Li
2023 J jnl
Biomed. Signal Process. Control.
Wenqi Liang, Fanjie Wang, Ao Fan, Wenrui Zhao, Wei Yao, Pengfei Yang
2023 J jnl
IEEE Access
Qinglin Meng, Yan Song, Jian Mu, Yuanxu Lv, Jiachen Yang, Liang Xu, Jin Zhao, Junwei Ma, Wei Yao, Rui Wang, Maoxiang Xiao, Qingyu Meng
2023 J jnl
Sensors
Wenqi Liang, Fanjie Wang, Ao Fan, Wenrui Zhao, Wei Yao, Pengfei Yang
2023 J jnl
Int. J. Pattern Recognit. Artif. Intell.
Wei Yao, Xu Zhou, Guanghua Tan, Shenghong Yang, Kenli Li
2023 J jnl
J. Intell. Fuzzy Syst.
Puyu Han, Wei Yao, Xian Jiang
2023 J jnl
CoRR
Lei Wang, Yinchi Ma, Peng Luan, Wei Yao, Congcong Li, Bo Liu
2023 J jnl
J. Inf. Sci.
Yuanyuan Lin, Chao Huang, Wei Yao, Yifei Shao
2023 J jnl
Signal Process.
Wei Yao, Shu-Li Sun
2023 J jnl
IEEE Access
Wei Yao, Fadi P. Deek, Renita Murimi, Guiling Wang
2023 conf
LOD (2)
Zijun Liu, Xinxin Wu, Wei Yao
2023 J jnl
Complex Intell. Syst.
Shaoying Li, Jie Li, Bincheng Wang, Wei Yao, Bo Liu
2023 J jnl
Sensors
Wei Yao, Aiming Wang, Yifan Nie, Zhengyan Lv, Shuai Nie, Congwei Huang, Zhenyu Liu
2023 J jnl
J. Intell. Fuzzy Syst.
Bei Zhang, Chang-Jie Zhou, Wei Yao
2023 B conf
GLOBECOM
Wei Yao, Yuhong Liu, Fadi P. Deek, Guiling Wang, Ying Wu
2023 J jnl
CoRR
Wei Yao, Yuhong Liu, Fadi P. Deek, Guiling Wang
2023 J jnl
CoRR
Wei Yao, Hongwen Zhang, Yunlian Sun, Jinhui Tang
2023 conf
Blockchain
Wei Yao, Yuhong Liu, Fadi P. Deek, Guiling Wang
2022 J jnl
CoRR
Mingze Sun, Haoxiang Wang, Wei Yao, Jiawang Liu
2022 J jnl
Signal Image Video Process.
Li Cheng, Wei Yao
2022 conf
EMBC
Fiona Boyd, M. A. Ledingham, Wei Yao
2022 J jnl
Remote. Sens.
Wei Yao, Lu Li, Hongyu Ni, Wei Li, Ran Tao
2022 J jnl
ISPRS Int. J. Geo Inf.
Ping Tu, Wei Yao, Zhiyuan Zhao, Pengzhou Wang, Sheng Wu, Zhixiang Fang
2022 J jnl
Soft Comput.
Ninghua Gao, Zixuan Cao, Qingguo Li, Wei Yao, Haojie Jiang
2022 conf
CDCEO@IJCAI
Fahong Zhang, Yilei Shi, Qingsong Xu, Zhitong Xiong, Wei Yao, Xiao Xiang Zhu
2022 J jnl
Multim. Tools Appl.
Yuanyuan Li, Lingyu Hou, Ming Tang, Qichun Sun, Jiahang Chen, Wanqing Song, Wei Yao, Le Cao
2022 conf
CAIBDA
Jie Sun, Wei Yao, Fakuan Guo, Yan Su
2021 J jnl
Sci. Program.
Le Cao, Wenyan Zhang, Xiu Kan, Wei Yao
2021 J jnl
CoRR
Wei Yao, Junyi Ye, Renita Murimi, Guiling Wang
2021 J jnl
Adv. Robotics
Min Li, Bo He, Xingang Zhao, Jun Xie, Wei Yao, Guanghua Xu
2021 J jnl
Fuzzy Sets Syst.
Wei Yao, Yueli Yue
2021 J jnl
Frontiers Robotics AI
Min Li, Jiazhou Chen, Guoying He, Lei Cui, Chaoyang Chen, Emanuele Lindo Secco, Wei Yao, Jun Xie, Guanghua Xu, Helge A. Wurdemann
2021 J jnl
Sci. Program.
Wei Yao, Stefanie Thomas
2021 J jnl
IEEE Access
Mengfei Yuan, Xiu Kan, Chi-Hung Chi, Le Cao, Huisheng Shu, Yixuan Fan, Wei Yao
2021 J jnl
J. Intell. Fuzzy Syst.
Wei Yao, Ye Chen
2020 J jnl
Complex.
Xiu Kan, Dan Yang, Le Cao, Huisheng Shu, YuanYuan Li, Wei Yao, Xiafeng Zhang
2020 J jnl
Rev. d'Intelligence Artif.
Jinjin Cai, Jie Li, Bo Liu, Wei Yao
2020 J jnl
Neural Comput. Appl.
Wei Yao, Fazlullah Khan, Mian Ahmad Jan, Nadir Shah, Izaz Ur Rahman, Abid Yahya, Ateeq Ur Rehman
2020 J jnl
Comput. Electr. Eng.
Xiang Yong, Xinxin Tian, Zhou Su, Wei Yao, Chen Rui
2020 J jnl
Adv. Robotics
Min Li, Yueyan Zhuo, Jiazhou Chen, Bo He, Guanghua Xu, Jun Xie, Xingang Zhao, Wei Yao
2020 J jnl
CoRR
Shen Chen, Mingwei Zhang, Jiamin Cui, Wei Yao
2020 J jnl
CoRR
Wei Yao, Shen Chen, Jiamin Cui, Yaolin Lou
2020 conf
ICTA
Zenan Lin, Mingyi Chen, Jian Zhao, Wei Yao, Ma Zhu
2019 J jnl
IEEE Access
Wei Yao, Abid Yahya, Fazlullah Khan, Zhiyuan Tan, Ateeq Ur Rehman, Joseph Monamati Chuma, Mian Ahmad Jan, Muhammad Babar
2019 J jnl
IEEE Access
Bin Li, Bing Sun, Wei Yao, Yuqing He, Guanggang Song
2019 C conf
IGARSS
Wei Yao
2018 conf
ICARM
Feng Ding, Jian Huang, Wei Yao, Shunfan He
2018 conf
ESSDERC
Umanath Kamath, Tao Yu, Wei Yao, Edward Cullen, John Jennings, Susan Wu, Peng Lim, Brendan Farley, Robert Bogdan Staszewski
2018 conf
ICC
Guowei Zhang, Fei Shen, Yang Yang, Hua Qian, Wei Yao
2018 J jnl
Biomed. Signal Process. Control.
Xiaoyu Liu, Hongqiang Huo, Yuanjie Zhu, Lizhen Wang, Aoran Sun, Wei Yao, Yubo Fan
2018 J jnl
IEEE Syst. J.
Jiguo Li, Wei Yao, Jinguang Han, Yichen Zhang, Jian Shen
2017 conf
COMPSAC (2)
Feng Ma, Xiaodong Liu, Ying Yang, Wei Yao, Jinjin Cai, Fang Wang
2017 J jnl
IEEE Trans. Serv. Comput.
Jiguo Li, Wei Yao, Yichen Zhang, Huiling Qian, Jinguang Han
2016 J jnl
J. Inf. Sci. Eng.
Jiguo Li, Xuexia Zhao, Yichen Zhang, Wei Yao
2016 conf
ROBIO
Wei Yao, Hu Jin, Chunshan Liu, Min Xu, Jie Yang, Erbao Dong
2016 conf
Trustcom/BigDataSE/ISPA
Xin Pei, Yongjian Wang, Wei Yao, Jiuchuan Lin, Ruxiang Peng
2015 conf
ICIA
Lele Wei, Wei Yao
2014 J jnl
J. Multim.
Wenjing Zhang, Wei Yao, Donglai Ma
2014 J jnl
J. Networks
Wenjing Zhang, Donglai Ma, Wei Yao
2013 conf
ISDT
Wei Yao, Bin Zhao
2013 C conf
DASC
Jianhua Che, Wei Yao, Shougang Ren, Haoyun Wang
2013 A conf
MoDELS
Xiaodong Zhang, Xing Chen, Ying Zhang, Yihan Wu, Wei Yao, Gang Huang, Qiang Lin
2012 conf
ISIE
Xue Zhang, Wei You, Wei Yao, Shen Chen, Zhengyu Lu
2012 conf
ISIE
Shaofeng Yin, Zhengyu Lu, Wei Yao
2012 J jnl
Neurocomputing
Min Han, Xinrong Zhu, Wei Yao
2011 J jnl
IEEE Trans. Ind. Electron.
Wei Yao, Min Chen, José Matas, Josep M. Guerrero, Zhao-Ming Qian
2011 conf
ICDMA
Tianbiao Yu, Jing Wang, Tianrui Zhang, Da Ha, Wei Yao, Wanshan Wang
2010 J jnl
Ind. Robot
Wei Yao, Jian S. Dai, Anthony J. Medland, Glen Mullineux
2010 J jnl
Ecol. Informatics
Wei Yao, Min Han, Shiguo Xu
2010 Misc conf
ICNC
Hui Peng, Ping Huang, Wei Yao
2009 B conf
SMC
Min Han, Wei Yao
2009 conf
HPCA (China)
Hui Peng, Wei Yao, Ping Huang
2008 J jnl
Fuzzy Sets Syst.
Wei Yao
2008 J jnl
Kybernetes
Yuehua Chen, Wei Yao
2008 conf
ISIP
Jin Chen, Wei Yao, Yubing He, Xin Jin
tests/unit/test_cfg_features.py
← Index tests/unit/test_cfg_features.py python
"""
Unit tests for cfg_features.py — all new CFG feature computations.

These tests use plain Python data structures (index-based adjacency lists)
and require no Binary Ninja dependency.
"""
import pytest

from redb.extractors.decompiler.bninja.analysis.cfg_features import (
    bfs_order,
    bfs_max_depth,
    count_back_edges,
    compute_topology_hash,
    compute_md_index_topdown,
    compute_md_index_bottomup,
    compute_prime_product,
    build_block_features,
    compute_cfg_feature_tlsh,
    compute_wl_minhash,
    pack_adjacency,
    LLIL_OP_CATEGORIES,
    CAT_ARITHMETIC,
    CAT_LOGIC,
    CAT_CALL,
    CAT_MEMORY,
    NUM_WL_MINHASH_PERMS,
)


# ===================================================================
# Helper: common graph topologies
# ===================================================================

def _linear_chain(n):
    """0 -> 1 -> 2 -> ... -> (n-1)"""
    return [[i + 1] if i < n - 1 else [] for i in range(n)]


def _diamond():
    """
    0 -> 1, 0 -> 2, 1 -> 3, 2 -> 3
    (classic if/else diamond)
    """
    return [[1, 2], [3], [3], []]


def _predecessors_from_successors(successors, n):
    preds = [[] for _ in range(n)]
    for src, targets in enumerate(successors):
        for tgt in targets:
            preds[tgt].append(src)
    return preds


# ===================================================================
# TestBfsOrder
# ===================================================================

class TestBfsOrder:
    def test_empty_graph(self):
        assert bfs_order([], 0) == []

    def test_single_node(self):
        assert bfs_order([[]], 1) == [0]

    def test_linear_chain(self):
        succs = _linear_chain(4)
        assert bfs_order(succs, 4) == [0, 1, 2, 3]

    def test_diamond(self):
        succs = _diamond()
        order = bfs_order(succs, 4)
        assert order[0] == 0
        assert order[-1] == 3
        assert set(order) == {0, 1, 2, 3}

    def test_unreachable_nodes(self):
        # 0 -> 1, node 2 is unreachable
        succs = [[1], [], []]
        order = bfs_order(succs, 3)
        assert order[:2] == [0, 1]
        assert 2 in order  # unreachable appended

    def test_all_nodes_visited(self):
        succs = _diamond()
        order = bfs_order(succs, 4)
        assert len(order) == 4


# ===================================================================
# TestBfsMaxDepth
# ===================================================================

class TestBfsMaxDepth:
    def test_empty_graph(self):
        assert bfs_max_depth([], 0) == 0

    def test_single_block(self):
        assert bfs_max_depth([[]], 1) == 0

    def test_linear_chain(self):
        succs = _linear_chain(5)
        assert bfs_max_depth(succs, 5) == 4

    def test_diamond(self):
        succs = _diamond()
        assert bfs_max_depth(succs, 4) == 2

    def test_wide_graph(self):
        # 0 -> 1, 0 -> 2, 0 -> 3 (all at depth 1)
        succs = [[1, 2, 3], [], [], []]
        assert bfs_max_depth(succs, 4) == 1


# ===================================================================
# TestCountBackEdges
# ===================================================================

class TestCountBackEdges:
    def test_empty_graph(self):
        assert count_back_edges([], 0) == 0

    def test_no_loops(self):
        succs = _linear_chain(3)
        assert count_back_edges(succs, 3) == 0

    def test_single_loop(self):
        # 0 -> 1 -> 2 -> 0 (one back edge: 2->0)
        succs = [[1], [2], [0]]
        assert count_back_edges(succs, 3) == 1

    def test_nested_loops(self):
        # 0 -> 1 -> 2 -> 1 (inner), 2 -> 3 -> 0 (outer)
        succs = [[1], [2], [1, 3], [0]]
        assert count_back_edges(succs, 4) == 2

    def test_self_loop(self):
        # 0 -> 0 (self-loop)
        succs = [[0]]
        assert count_back_edges(succs, 1) == 1

    def test_diamond_no_loops(self):
        succs = _diamond()
        assert count_back_edges(succs, 4) == 0

    def test_single_node_no_loop(self):
        succs = [[]]
        assert count_back_edges(succs, 1) == 0


# ===================================================================
# TestTopologyHash
# ===================================================================

class TestTopologyHash:
    def test_same_graph_same_hash(self):
        succs = _diamond()
        bfs = bfs_order(succs, 4)
        h1 = compute_topology_hash(succs, bfs, 4)
        h2 = compute_topology_hash(succs, bfs, 4)
        assert h1 == h2

    def test_different_graphs_different_hash(self):
        succs1 = _linear_chain(3)
        bfs1 = bfs_order(succs1, 3)
        h1 = compute_topology_hash(succs1, bfs1, 3)

        succs2 = _diamond()
        bfs2 = bfs_order(succs2, 4)
        h2 = compute_topology_hash(succs2, bfs2, 4)

        assert h1 != h2

    def test_returns_16_bytes(self):
        succs = _diamond()
        bfs = bfs_order(succs, 4)
        h = compute_topology_hash(succs, bfs, 4)
        assert isinstance(h, bytes)
        assert len(h) == 16

    def test_isomorphic_graphs_same_hash(self):
        # Graph A: 0->1, 0->2, 1->3, 2->3 (diamond with successors [1,2])
        succs_a = [[1, 2], [3], [3], []]
        # Graph B: same structure but successors listed as [2,1]
        # BFS from 0 will visit them in different order, but after remapping
        # the canonical form should be identical for isomorphic graphs
        succs_b = [[2, 1], [3], [3], []]

        bfs_a = bfs_order(succs_a, 4)
        bfs_b = bfs_order(succs_b, 4)

        h_a = compute_topology_hash(succs_a, bfs_a, 4)
        h_b = compute_topology_hash(succs_b, bfs_b, 4)
        assert h_a == h_b

    def test_empty_graph(self):
        h = compute_topology_hash([], [], 0)
        assert h == b'\x00' * 16

    def test_single_node(self):
        succs = [[]]
        bfs = bfs_order(succs, 1)
        h = compute_topology_hash(succs, bfs, 1)
        assert isinstance(h, bytes)
        assert len(h) == 16


# ===================================================================
# TestMdIndex
# ===================================================================

class TestMdIndex:
    def test_single_block_topdown(self):
        succs = [[]]
        preds = [[]]
        bfs = [0]
        result = compute_md_index_topdown(succs, preds, bfs)
        assert isinstance(result, int)
        assert result > 0

    def test_single_block_bottomup(self):
        succs = [[]]
        preds = [[]]
        result = compute_md_index_bottomup(succs, preds, 1)
        assert isinstance(result, int)
        assert result > 0

    def test_linear_chain_topdown_vs_bottomup(self):
        succs = _linear_chain(4)
        preds = _predecessors_from_successors(succs, 4)
        bfs = bfs_order(succs, 4)
        td = compute_md_index_topdown(succs, preds, bfs)
        bu = compute_md_index_bottomup(succs, preds, 4)
        # Top-down and bottom-up should be different for a linear chain
        # (entry has in_deg=0, exit has out_deg=0, so the sequences differ)
        assert td != bu

    def test_deterministic(self):
        succs = _diamond()
        preds = _predecessors_from_successors(succs, 4)
        bfs = bfs_order(succs, 4)
        td1 = compute_md_index_topdown(succs, preds, bfs)
        td2 = compute_md_index_topdown(succs, preds, bfs)
        assert td1 == td2

    def test_different_graphs_different_index(self):
        succs1 = _linear_chain(3)
        preds1 = _predecessors_from_successors(succs1, 3)
        bfs1 = bfs_order(succs1, 3)
        td1 = compute_md_index_topdown(succs1, preds1, bfs1)

        succs2 = _diamond()
        preds2 = _predecessors_from_successors(succs2, 4)
        bfs2 = bfs_order(succs2, 4)
        td2 = compute_md_index_topdown(succs2, preds2, bfs2)

        assert td1 != td2

    def test_topdown_empty(self):
        assert compute_md_index_topdown([], [], []) == 0

    def test_bottomup_empty(self):
        assert compute_md_index_bottomup([], [], 0) == 0


# ===================================================================
# TestPrimeProduct
# ===================================================================

class TestPrimeProduct:
    def test_empty(self):
        assert compute_prime_product([]) == 0

    def test_known_sequence(self):
        # Use actual LLIL enum values from conftest_binja_stubs:
        # LLIL_NOP=0 -> prime 1, LLIL_LOAD=4 -> prime 5
        from redb.extractors.decompiler.bninja.analysis.cfg_features import LLIL_OP_PRIMES
        nop_val = 0   # LLIL_NOP
        load_val = 4  # LLIL_LOAD
        expected = LLIL_OP_PRIMES.get(nop_val, 1) * LLIL_OP_PRIMES.get(load_val, 1)
        result = compute_prime_product([nop_val, load_val])
        assert result == expected

    def test_order_independence(self):
        # LLIL_LOAD=4, LLIL_STORE=5, LLIL_ADD=13
        ops_a = [4, 5, 13]
        ops_b = [13, 4, 5]
        assert compute_prime_product(ops_a) == compute_prime_product(ops_b)

    def test_unknown_ops_map_to_1(self):
        # Unknown ops get prime 1, so they don't change the product
        result_known = compute_prime_product([4])  # LLIL_LOAD -> 5
        result_with_unknown = compute_prime_product([4, 9999])  # LOAD * unknown(1)
        assert result_known == result_with_unknown

    def test_mod_2_64(self):
        # Product should be mod 2^64
        result = compute_prime_product([4] * 1000)  # LLIL_LOAD
        assert 0 <= result < 2**64

    def test_single_op(self):
        # LLIL_STORE=5 -> prime 7
        assert compute_prime_product([5]) == 7


# ===================================================================
# TestBuildBlockFeatures
# ===================================================================

class TestBuildBlockFeatures:
    def test_empty_llil(self):
        succs = [[1], []]
        features = build_block_features([[], []], succs, 2)
        assert len(features) == 2
        # All zeros except successor_count
        assert features[0] == [0, 0, 0, 0, 0, 0, 0, 1]  # 1 successor
        assert features[1] == [0, 0, 0, 0, 0, 0, 0, 0]  # 0 successors

    def test_correct_categorization(self):
        # Set up categories for testing
        import redb.extractors.decompiler.bninja.analysis.cfg_features as cf
        old_cats = cf.LLIL_OP_CATEGORIES.copy()
        cf.LLIL_OP_CATEGORIES.update({
            100: CAT_ARITHMETIC,
            101: CAT_ARITHMETIC,
            200: CAT_LOGIC,
            300: CAT_CALL,
            400: CAT_MEMORY,
        })
        try:
            block_ops = [[100, 101, 200, 300, 400]]
            succs = [[]]
            features = build_block_features(block_ops, succs, 1)
            assert features[0][0] == 5   # instr_count
            assert features[0][1] == 2   # arithmetic
            assert features[0][2] == 1   # logic
            assert features[0][4] == 1   # call
            assert features[0][6] == 1   # memory
        finally:
            cf.LLIL_OP_CATEGORIES.clear()
            cf.LLIL_OP_CATEGORIES.update(old_cats)

    def test_cap_at_65535(self):
        # More than 65535 ops in one block
        huge_ops = [0] * 70000  # NOP x 70000
        succs = [[]]
        features = build_block_features([huge_ops], succs, 1)
        assert features[0][0] == 65535  # capped

    def test_missing_block_ops(self):
        # block_llil_ops shorter than n
        succs = [[1], [2], []]
        features = build_block_features([[1, 2]], succs, 3)
        assert len(features) == 3
        # Block 1 and 2 get empty ops since block_llil_ops only has 1 entry
        assert features[1] == [0, 0, 0, 0, 0, 0, 0, 1]
        assert features[2] == [0, 0, 0, 0, 0, 0, 0, 0]


# ===================================================================
# TestCfgFeatureTlsh
# ===================================================================

class TestCfgFeatureTlsh:
    def test_too_few_blocks_returns_none(self):
        # 5 blocks = 5 * 9 bytes = 45 < 50
        bb_features = [[10, 1, 0, 2, 0, 1, 1, 2]] * 5
        bfs = list(range(5))
        result = compute_cfg_feature_tlsh(bb_features, bfs)
        assert result is None

    def test_uniform_data_returns_none(self):
        # 7 identical blocks — TLSH returns TNULL for low-entropy input
        bb_features = [[10, 1, 0, 2, 0, 1, 1, 2]] * 7
        bfs = list(range(7))
        result = compute_cfg_feature_tlsh(bb_features, bfs)
        assert result is None

    def test_varied_data_returns_string(self):
        # 20 blocks with varied features — enough entropy for TLSH
        bb_features = [
            [i * 7 + 3, (i * 13) % 50, (i * 17) % 30, (i * 23) % 40,
             (i * 11) % 20, (i * 7) % 25, (i * 19) % 35, (i * 3) % 10]
            for i in range(20)
        ]
        bfs = list(range(20))
        result = compute_cfg_feature_tlsh(bb_features, bfs)
        assert isinstance(result, str)
        assert len(result) > 0
        assert result.startswith("T1")


# ===================================================================
# TestWlMinhash
# ===================================================================

class TestWlMinhash:
    def test_empty_function(self):
        result = compute_wl_minhash([], [], [], 0)
        assert result == [255] * NUM_WL_MINHASH_PERMS

    def test_returns_128_elements(self):
        succs = _diamond()
        preds = _predecessors_from_successors(succs, 4)
        bb_feats = [[5, 1, 0, 2, 0, 1, 1, 2]] * 4
        result = compute_wl_minhash(succs, preds, bb_feats, 4)
        assert len(result) == 128

    def test_all_uint8(self):
        succs = _linear_chain(3)
        preds = _predecessors_from_successors(succs, 3)
        bb_feats = [[3, 1, 0, 1, 0, 0, 1, 1]] * 3
        result = compute_wl_minhash(succs, preds, bb_feats, 3)
        assert all(0 <= v <= 255 for v in result)

    def test_identical_graphs_same_signature(self):
        succs = _diamond()
        preds = _predecessors_from_successors(succs, 4)
        bb_feats = [[5, 1, 0, 2, 0, 1, 1, 2]] * 4
        sig1 = compute_wl_minhash(succs, preds, bb_feats, 4)
        sig2 = compute_wl_minhash(succs, preds, bb_feats, 4)
        assert sig1 == sig2

    def test_different_graphs_different_signatures(self):
        # Graph 1: linear chain
        succs1 = _linear_chain(4)
        preds1 = _predecessors_from_successors(succs1, 4)
        bb_feats1 = [[5, 1, 0, 2, 0, 1, 1, i] for i in range(4)]
        sig1 = compute_wl_minhash(succs1, preds1, bb_feats1, 4)

        # Graph 2: diamond
        succs2 = _diamond()
        preds2 = _predecessors_from_successors(succs2, 4)
        bb_feats2 = [[10, 3, 2, 1, 0, 0, 0, i] for i in range(4)]
        sig2 = compute_wl_minhash(succs2, preds2, bb_feats2, 4)

        assert sig1 != sig2

    def test_single_node(self):
        succs = [[]]
        preds = [[]]
        bb_feats = [[1, 0, 0, 0, 0, 0, 0, 0]]
        result = compute_wl_minhash(succs, preds, bb_feats, 1)
        assert len(result) == 128


# ===================================================================
# TestPackAdjacency
# ===================================================================

class TestPackAdjacency:
    def test_empty(self):
        assert pack_adjacency([]) == []

    def test_single_edge(self):
        succs = [[1], []]
        edges = pack_adjacency(succs)
        assert len(edges) == 1
        assert edges[0] == (0 << 16) | 1

    def test_correct_packing(self):
        succs = _diamond()
        edges = pack_adjacency(succs)
        assert len(edges) == 4
        # 0->1, 0->2, 1->3, 2->3
        expected = {
            (0 << 16) | 1,
            (0 << 16) | 2,
            (1 << 16) | 3,
            (2 << 16) | 3,
        }
        assert set(edges) == expected

    def test_roundtrip(self):
        """Unpack edges and verify source/target pairs."""
        succs = [[1, 2], [3], [3], []]
        edges = pack_adjacency(succs)
        unpacked = [(e >> 16, e & 0xFFFF) for e in edges]
        expected = [(0, 1), (0, 2), (1, 3), (2, 3)]
        assert sorted(unpacked) == sorted(expected)

    def test_large_index_filtered(self):
        # Create a successor list where index >= 65536
        succs = [[] for _ in range(65537)]
        succs[0] = [65536]  # target is exactly 65536 — should be filtered
        edges = pack_adjacency(succs)
        assert len(edges) == 0

    def test_max_valid_index(self):
        # Index 65535 is the maximum valid
        succs = [[] for _ in range(65536)]
        succs[0] = [65535]
        edges = pack_adjacency(succs)
        assert len(edges) == 1
        assert edges[0] == (0 << 16) | 65535