Natalie Parde

68 papers A* 8A 3B 8C 2Misc 1Journal 17Unranked 29
YearRankTypeTitle / Venue / Authors
2026 J jnl
CoRR
Shweta Parihar, Guangliang Liu, Natalie Parde, Lu Cheng
2026 J jnl
CoRR
Lei Jiang, Yue Zhou, Natalie Parde
2025 conf
ACL (Findings)
Gyeongeun Lee, Zhu Wang, Sathya N. Ravi, Natalie Parde
2025 J jnl
Comput. Speech Lang.
Gyu-Ho Shin, Natalie Parde
2025 conf
IJCNLP-AACL (long papers)
Calliope Chloe Bandera, Gyeongeun Lee, Natalie Parde
2024 conf
LREC/COLING
Gyeongeun Lee, Natalie Parde
2024 J jnl
CoRR
Hoang H. Nguyen, Chenwei Zhang, Ye Liu, Natalie Parde, Eugene Rohrbaugh, Philip S. Yu
2024 conf
LREC/COLING
Hoang Nguyen, Chenwei Zhang, Ye Liu, Natalie Parde, Eugene Rohrbaugh, Philip S. Yu
2024 A* conf
EMNLP
Shahla Farzana, Ivana Lucero, Vivian Villegas, Vera C. Kaelin, Mary A. Khetani, Natalie Parde
2024 conf
LREC/COLING
Mina Valizadeh, Vera C. Kaelin, Mary A. Khetani, Natalie Parde
2024 J jnl
CoRR
Casey Kennington, Malihe Alikhani, Heather Pon-Barry, Katherine Atwell, Yonatan Bisk, Daniel Fried, Felix Gervits, Zhao Han, Mert Inan, Michael Johnston, Raj Korpan, Diane J. Litman, Matthew Marge, Cynthia Matuszek, Ross Mead, Shiwali Mohan, Raymond J. Mooney, Natalie Parde, Jivko Sinapov, Angela Stewart, Matthew Stone, Stefanie Tellex, Tom Williams
2024 conf
EMNLP (Findings)
Shahla Farzana, Natalie Parde
2024 conf
WASSA
Gyeongeun Lee, Zhu Wang, Sathya N. Ravi, Natalie Parde
2024 conf
LREC/COLING
Youheng W. Wong, Natalie Parde, Erdem Koyuncu
2024 conf
ACL (1)
Gyeongeun Lee, Christina Wong, Meghan Guo, Natalie Parde
2024 conf
LREC/COLING
Shahla Farzana, Edoardo Stoppa, Alex Leow, Tamar Gollan, Raeanne Moore, David Salmon, Douglas Galasko, Erin Sundermann, Natalie Parde
2024 conf
LREC/COLING
Baris Karacan, Ankit Aich, Avery Quynh, Amy E. Pinkham, Philip D. Harvey, Colin A. Depp, Natalie Parde
2024 conf
SemEval@NAACL
Sharad Chandakacherla, Vaibhav Bhargava, Natalie Parde
2024 J jnl
CoRR
Ankit Aich, Avery Quynh, Pamela Osseyi, Amy E. Pinkham, Philip D. Harvey, Brenda Curtis, Colin Depp, Natalie Parde
2023 A* conf
CHI
Ja Eun Yu, Natalie Parde, Debaleena Chattopadhyay
2023 C conf
ICMLA
Gyeongeun Lee, Xunfei Jiang, Natalie Parde
2023 conf
BHI
Edoardo Stoppa, Guido Walter Di Donato, Isabella Poles, Eleonora D'Arnese, Natalie Parde, Marco Domenico Santambrogio
2023 conf
ACL (Findings)
Maja Popovic, Mohammad Arvan, Natalie Parde, Anya Belz
2023 A conf
INTERSPEECH
Mohammad Arvan, A. Seza Dogruöz, Natalie Parde
2023 J jnl
CoRR
Mohammad Arvan, A. Seza Dogruöz, Natalie Parde
2023 B conf
CogSci
Mohammad Arvan, Mina Valizadeh, Parian Haghighat, Toan Nguyen, Heejin Jeong, Natalie Parde
2023 J jnl
CoRR
Anya Belz, Craig Thomson, Ehud Reiter, Gavin Abercrombie, Jose Maria Alonso-Moral, Mohammad Arvan, Jackie Chi Kit Cheung, Mark Cieliebak, Elizabeth Clark, Kees van Deemter, Tanvi Dinkar, Ondrej Dusek, Steffen Eger, Qixiang Fang, Albert Gatt, Dimitra Gkatzia, Javier González-Corbelle, Dirk Hovy, Manuela Hürlimann, Takumi Ito, John D. Kelleher, Filip Klubicka, Huiyuan Lai, Chris van der Lee, Emiel van Miltenburg, Yiru Li, Saad Mahamood, Margot Mieskes, Malvina Nissim, Natalie Parde, Ondrej Plátek, Verena Rieser, Pablo Mosteiro Romero, Joel R. Tetreault, Antonio Toral, Xiaojun Wan, Leo Wanner, Lewis Watson, Diyi Yang
2023 J jnl
J. Heal. Informatics Res.
Vera C. Kaelin, Andrew D. Boyd, Martha M. Werler, Natalie Parde, Mary A. Khetani
2023 conf
ACL (1)
Shahla Farzana, Natalie Parde
2023 A conf
EACL
Mina Valizadeh, Xing Qian, Pardis Ranjbar-Noiey, Cornelia Caragea, Natalie Parde
2022 B conf
SIGDIAL
Shahla Farzana, Natalie Parde
2022 conf
RTSI
Edoardo Stoppa, Guido Walter Di Donato, Natalie Parde, Marco Domenico Santambrogio
2022 B conf
COLING
Ankit Aich, Souvik Bhattacharya, Natalie Parde
2022 conf
SemEval@NAACL
Charic Farinango Cuervo, Natalie Parde
2022 conf
BioNLP@ACL
Shahla Farzana, Ashwin Deshpande, Natalie Parde
2022 A* conf
EMNLP
Mohammad Arvan, Luís Pina, Natalie Parde
2022 B conf
LREC
Ankit Aich, Natalie Parde
2022 conf
ACL (1)
Mina Valizadeh, Natalie Parde
2022 conf
EMNLP (Findings)
Ankit Aich, Avery Quynh, Varsha D. Badal, Amy E. Pinkham, Philip D. Harvey, Colin A. Depp, Natalie Parde
2022 B conf
LREC
Megan Herrera, Ankit Aich, Natalie Parde
2021 conf
NAACL-HLT
Mina Valizadeh, Pardis Ranjbar-Noiey, Cornelia Caragea, Natalie Parde
2021 J jnl
CoRR
Philip Hossu, Natalie Parde
2020 conf
AI4TV@MM
Natalie Parde
2020 A conf
INTERSPEECH
Shahla Farzana, Natalie Parde
2020 conf
Preregister@NeurIPS
Cade Gordon, Natalie Parde
2020 J jnl
CoRR
Cade Gordon, Natalie Parde
2020 B conf
LREC
Shahla Farzana, Mina Valizadeh, Natalie Parde
2020 conf
SemEval@COLING
Philip Hossu, Natalie Parde
2019 conf
AIED (2)
Natalie Parde, Rodney D. Nielsen
2019 J jnl
CoRR
Natalie Parde, Rodney D. Nielsen
2019 conf
ACL (2)
Flavio Di Palo, Natalie Parde
2019 J jnl
CoRR
Flavio Di Palo, Natalie Parde
2019 J jnl
CoRR
Yatri Modi, Natalie Parde
2018 J jnl
CoRR
Natalie Parde, Rodney D. Nielsen
2018 B conf
LREC
Natalie Parde, Rodney D. Nielsen
2018 B conf
INLG
Natalie Parde, Rodney Nielsen
2018 A* conf
AAAI
Natalie Parde, Rodney D. Nielsen
2018 A* conf
AAAI
Natalie Parde
2017 Misc conf
FLAIRS
Natalie Parde, Rodney D. Nielsen
2017 A* conf
EMNLP
Natalie Parde, Rodney D. Nielsen
2017 C conf
SACMAT
Masoud Narouei, Hamed Khanpour, Hassan Takabi, Natalie Parde, Rodney D. Nielsen
2015 A* conf
AAAI
Natalie Parde, Michalis Papakostas, Konstantinos Tsiakas, Rodney D. Nielsen
2015 conf
PETRA
Michalis Papakostas, Konstantinos Tsiakas, Natalie Parde, Vangelis Karkaletsis, Fillia Makedon
2015 A* conf
IJCAI
Natalie Parde, Adam Hair, Michalis Papakostas, Konstantinos Tsiakas, Maria Dagioglou, Vangelis Karkaletsis, Rodney D. Nielsen
2013 conf
IPDPS Workshops
Anil Kumar Sistla, Natalie Parde, Krunalkumar Patel, Gayatri Mehta
2013 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Gayatri Mehta, Krunalkumar Patel, Natalie Parde, Nancy S. Pollard
2013 conf
MSE
Gayatri Mehta, Xiaozhong Luo, Natalie Parde, Krunalkumar Patel, Brandon Rodgers, Anil Kumar Sistla
2013 J jnl
ACM Trans. Reconfigurable Technol. Syst.
Gayatri Mehta, Carson Crawford, Xiaozhong Luo, Natalie Parde, Krunalkumar Patel, Brandon Rodgers, Anil Kumar Sistla, Anil Yadav, Marc Reisner
tests/unit/test_decompile_medium_level.py
← Index tests/unit/test_decompile_medium_level.py python
# tests/unit/test_decompile_medium_level.py
"""Unit tests (mocked BN) for bninja/analysis/medium_level.py
   and bninja/analysis/medium_level_normalization.py."""
# tests/unit/test_decompile_medium_level.py
import sys
from unittest.mock import MagicMock, patch

# Installa gli stubs BN
from tests.unit.conftest_binja_stubs import install_binja_stubs
install_binja_stubs()

# ── Definisci MockMLILInstruction PRIMA di importare il modulo ──
class MockMLILInstruction:
    def __init__(self, operation, address=0, operands=None):
        self.operation = operation
        self.address = address
        self.operands = operands or []

# ── Patcha il modulo BN in modo che isinstance() funzioni ──
sys.modules["binaryninja"].MediumLevelILInstruction = MockMLILInstruction
sys.modules["binaryninja"].SSAVariable = type("SSAVariable", (), {})
sys.modules["binaryninja"].Variable = type("Variable", (), {})
sys.modules["binaryninja"].ILIntrinsic = type("ILIntrinsic", (), {})

# Ora importa il modulo — vede già i tipi corretti
from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
    MediumLevelNormalization,
)	

class MockMLILFunction:
    def __init__(self, instructions):
        self._instructions = instructions

    @property
    def instructions(self):
        return iter(self._instructions)

    @property
    def basic_blocks(self):
        # one block containing all instructions, good enough for MinHasher
        block = MagicMock()
        block.__iter__ = lambda self_: iter([])  # not used by MediumLevelAnalysis
        return [block]


class MockFunction:
    def __init__(self, name="func", start=0x1000, mlil=None):
        self.name = name
        self.start = start
        self.mlil = mlil



class TestMediumLevelNormalization:
    def setup_method(self):
        from redb.extractors.decompiler.bninja.analysis.medium_level_normalization import (
            MediumLevelNormalization,
        )
        self.norm = MediumLevelNormalization()

    def test_normalize_skeleton_single_instruction(self):
        il = MockMLILInstruction(operation=42, operands=[])
        result = self.norm.normalize_instruction_all_levels(il)
        assert result == [42]

    def test_normalize_skeleton_nested(self):
        inner = MockMLILInstruction(operation=7, operands=[])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [1, 7]

    def test_normalize_skeleton_with_list_operand(self):
        inner_a = MockMLILInstruction(operation=10, operands=[])
        inner_b = MockMLILInstruction(operation=11, operands=[])
        outer = MockMLILInstruction(operation=2, operands=[[inner_a, inner_b]])
        result = self.norm.normalize_instruction_all_levels(outer)
        assert result == [2, 10, 11]

    def test_normalize_skeleton_none(self):
        result = self.norm.normalize_instruction_all_levels(None)
        # collect on None should leave ops empty
        assert result == []

    def test_normalize_typed_appends_leaf_types(self):
        # operand is a plain int -> "CONST"
        il = MockMLILInstruction(operation=3, operands=[42])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [3, "CONST"]

    def test_normalize_typed_bool_before_int(self):
        # bool must be detected before int (since bool is an int subclass)
        il = MockMLILInstruction(operation=4, operands=[True])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [4, "BOOL"]

    def test_normalize_typed_float(self):
        il = MockMLILInstruction(operation=5, operands=[1.5])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [5, "FLOAT_CONST"]

    def test_normalize_typed_str(self):
        il = MockMLILInstruction(operation=6, operands=["hello"])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [6, "STR"]

    def test_normalize_typed_unknown_falls_back_to_typename(self):
        class Weird:
            pass
        il = MockMLILInstruction(operation=8, operands=[Weird()])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [8, "WEIRD"]

    def test_normalize_typed_nested_mlil(self):
        inner = MockMLILInstruction(operation=99, operands=[7])
        outer = MockMLILInstruction(operation=1, operands=[inner])
        result = self.norm.normalize_instr_with_operands(outer)
        assert result == [1, 99, "CONST"]

    def test_normalize_typed_list_mixed(self):
        inner = MockMLILInstruction(operation=50, operands=[])
        il = MockMLILInstruction(operation=2, operands=[[inner, 99]])
        result = self.norm.normalize_instr_with_operands(il)
        assert result == [2, 50, "CONST"]


class TestMediumLevelAnalysis:
    def _make_analysis(self, instructions=None, mlil=True, start=0x1000):
        from redb.extractors.decompiler.bninja.analysis.medium_level import (
            MediumLevelAnalysis,
        )
        mlil_func = MockMLILFunction(instructions or []) if mlil else None
        func = MockFunction(name="testfunc", start=start, mlil=mlil_func)
        bv = MagicMock()
        return MediumLevelAnalysis(func, bv, MagicMock())

    def test_collect_returns_empty_when_no_mlil(self):
        a = self._make_analysis(mlil=False)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk == [] and sk_addr == [] and ty == [] and ty_addr == []

    def test_collect_skeleton_and_typed_basic(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        sk, sk_addr, ty, ty_addr = a._collect_mlil_skeleton_and_typed()

        assert sk == [[1], [2]]
        assert ty == [[1], [2, "CONST"]]
        assert sk_addr == [(0, [1]), (4, [2])]
        assert ty_addr == [(0, [1]), (4, [2, "CONST"])]

    def test_collect_negative_offset_clamped_to_zero(self):
        instrs = [
            MockMLILInstruction(operation=1, address=0x900, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        _, sk_addr, _, ty_addr = a._collect_mlil_skeleton_and_typed()
        assert sk_addr[0][0] == 0
        assert ty_addr[0][0] == 0

    def test_log_error_records_entry(self):
        a = self._make_analysis()
        a.log_error("boom", "fname", 0x1234, ValueError("x"), "loc")
        assert len(a.errors) == 1
        err = a.errors[0]
        assert err["function_name"] == "fname"
        assert err["function_address"] == "4660"  # hex 0x1234
        assert err["error_location"] == "loc"
        assert err["error_message"] == "boom"
        assert err["error_type"] == "ValueError"
        assert "timestamp" in err

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_returns_expected_keys(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = [1, 2, 3]

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[]),
            MockMLILInstruction(operation=2, address=0x1004, operands=[42]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[]),
        ]
        a = self._make_analysis(instructions=instrs, start=0x1000)
        result, errors = a.analyze()

        expected_keys = {
            "function_address",
            "body_mlil_skeleton_vector",
            "sha256_mlil_skeleton",
            "tlsh_mlil_skeleton",
            "minhash_mlil_skeleton",
            "body_mlil_typed_vector",
            "sha256_mlil_typed",
            "tlsh_mlil_typed",
            "minhash_mlil_typed",
        }
        assert set(result.keys()) == expected_keys
        assert result["function_address"] == 0x1000
        assert result["minhash_mlil_skeleton"] == [1, 2, 3]
        assert result["minhash_mlil_typed"] == [1, 2, 3]
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_empty_mlil(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []
        a = self._make_analysis(mlil=False)
        result, errors = a.analyze()
        assert result["body_mlil_skeleton_vector"] == []
        assert result["body_mlil_typed_vector"] == []
        assert errors == []

    @patch(
        "redb.extractors.decompiler.bninja.analysis.medium_level.MinHasher"
    )
    def test_analyze_sha256_differs_skeleton_vs_typed(self, mock_minhasher):
        mock_minhasher.return_value.calculateMinHash.return_value = []

        instrs = [
            MockMLILInstruction(operation=1, address=0x1000, operands=[42]),
            MockMLILInstruction(operation=2, address=0x1004, operands=["foo"]),
            MockMLILInstruction(operation=3, address=0x1008, operands=[True]),
        ]
        a = self._make_analysis(instructions=instrs)
        result, _ = a.analyze()
        # skeleton ignores operand leaves, typed includes them -> different hashes
        assert result["sha256_mlil_skeleton"] != result["sha256_mlil_typed"]


class TestMinHasherMLILKinds:
    def _make_func(self, instrs):
        # MinHasher iterates basic_blocks then over each block
        block = MagicMock()
        block.__iter__ = lambda self_: iter(instrs)
        f = MagicMock()
        f.basic_blocks = [block]
        return f

    def test_mlil_skeleton_uses_medium_normalizer(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=i, operands=[]) for i in range(5)
        ]
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        result = hasher.calculateMinHash()
        # 5 instructions -> 3 trigrams -> non-empty signature
        assert result != []

    def test_typed_mlil_differs_from_skeleton(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [
            MockMLILInstruction(operation=1, operands=[42]),
            MockMLILInstruction(operation=2, operands=["s"]),
            MockMLILInstruction(operation=3, operands=[True]),
            MockMLILInstruction(operation=4, operands=[1.5]),
        ]
        func = self._make_func(instrs)
        skel = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL).calculateMinHash()
        typed = MinHasher(seed=42, il_function=func, kind=TokenKind.TYPED_MLIL).calculateMinHash()
        # Same seed, same instructions, but typed has extra leaf tokens
        # -> hashes should generally differ
        assert skel != typed

    def test_mlil_too_few_instructions(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import (
            MinHasher, TokenKind,
        )
        instrs = [MockMLILInstruction(operation=1, operands=[])] * 2
        func = self._make_func(instrs)
        hasher = MinHasher(seed=42, il_function=func, kind=TokenKind.MLIL)
        assert hasher.calculateMinHash() == []

    def test_unsupported_kind_raises(self):
        from redb.extractors.decompiler.bninja.similarity.minhasher import MinHasher
        func = self._make_func([])
        hasher = MinHasher(seed=42, il_function=func, kind="bogus")
        with pytest.raises(ValueError):
            hasher.calculateMinHash()