【问题标题】:Use CrossHair to distinguish between automata and python function使用 CrossHair 区分自动机和 python 函数
【发布时间】:2021-01-05 07:31:52
【问题描述】:

我有一个定义语言的函数,让我们调用 L,这个函数获取一个单词并返回 True 或 False。

我还有一个确定性的有限 autumata,它假设接受语言中的单词并后悔语言 L 中的单词。

我的任务是获得一个反例来区分 dfa 和 python 函数。

我想知道 CrossHair 对这项任务是否有用。

我期待这样的东西:

counterexmaple = checker(dfa, func)

谢谢

【问题讨论】:

    标签: python solver finite-automata model-checking


    【解决方案1】:

    总结

    您也许可以使用CrossHair 来解决此类问题。但是,执行确定性有限自动机 (DFA) 将涉及很多分支行为,并且 CrossHair 在这种情况下表现不佳。在大多数情况下,您最好使用hypothesis 的随机测试方法。我将描述这两种方法。

    预赛

    首先,您需要能够在 python 中表达您的 DFA 以比较实现。这是一个例子:

    from typing import Tuple, Dict
    
    # We construct a DFA that accepts any string that ends                                                                                                                        
    # with "abc":                                                                                                                                                                 
    _TRANSITION_TABLE: Dict[Tuple[int, str], int] = {
        # state #0: we have not yet seen "a" (initial state)                                                                                                                      
        (0, 'a'): 1,
        # state #1: we've seen "a"                                                                                                                                                
        (1, 'a'): 1,
        (1, 'b'): 2,
        # state #2: we've seen "ab"                                                                                                                                               
        (2, 'a'): 1,
        (2, 'c'): 3,
        # state #3: we've seen "abc" (final state)                                                                                                                                
        (3, 'a'): 1,
    }
    
    def dfa_checker(s: str) -> bool:
        state = 0
        for char in s:
            state = _TRANSITION_TABLE.get((state, char), 0)
        return state == 3
    
    def correct_custom_checker(s: str) -> bool:
        return s.endswith("abc")
    
    def incorrect_custom_checker(s: str) -> bool:
        return s.endswith("bc")
    

    CrossHair 解决方案

    您可以给自定义实现一个合同,声明其结果与 DFA 相同:

    def incorrect_custom_checker(s: str) -> bool:
        ''' post: __return__ == dfa_checker(s) '''
        return bool(re.fullmatch('[abc]*', s) and s.endswith("bc"))
    

    虽然实际功能不需要,但为我们的字母表 (abc) 添加正则表达式有助于 CrossHair 找到解决方案。现在我们可以让 CrossHair 尝试反驳合同:

    $ crosshair check example.py
    example.py:29:error:false when calling incorrect_custom_checker(s = 'bc') (which returns True)
    

    它会找到反例“bc”,它被不正确的_custom_checker() 接受但被 DFA 拒绝。

    此外,还有一个非常新的、基本上没有记录的十字准线命令,它使这类事情变得更加容易。您可以使用以下方法比较任意两个 Python 函数:

    $ crosshair diffbehavior example.incorrect_custom_checker example.dfa_checker
      given: (s='bc')
    - returns: True
    + returns: False
    

    如果您需要完全以编程方式执行此操作,您可以访问执行此操作的 CrossHair 内部组件here。随着 CrossHair 代码库的发展,这种方法将失效,但为了完整起见,我将其包含在此处。

    假设解

    正如我之前提到的,进行大量随机测试可能对您更有效。这是假设的一种方法:

    import hypothesis
    from hypothesis.strategies import text
    @hypothesis.given(text(alphabet="abc"))
    def test_checkers_equivalent(s: str) -> None:
        assert dfa_checker(s) == incorrect_custom_checker(s)
    

    运行pytest example.py 将找到相同的“bc”反例。

    【讨论】:

    • 感谢您的详细回答,根据假设解决方案,有没有办法将其作为测试而不是作为项目的标准运行来运行?
    • 可悲的是,我不知道内联运行假设的方法。可能适合作为另一个堆栈溢出问题?假设社区非常活跃和友好。
    • 根据您所写的“如果您需要完全以编程方式执行此操作,您可以在此处访问执行此操作的 CrossHair 内部”我想知道是否可以将“pre:”选项添加到 AnalysisOptions谢谢
    猜你喜欢
    • 2019-07-17
    • 2011-07-09
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    相关资源
    最近更新 更多