在Eiffel中确保有关语法的子句

时间:2016-01-11 23:15:37

标签: eiffel

 find(c: CHARACTER; position: INTEGER): INTEGER

此功能通过从位置i开始并搜索来查找字符。一旦找到索引就输出它。但是,如果单词中不存在这样的字符,则输出0

问题: 后置条件必须断言查询返回范围pos ... word.count中字符c的索引,如果没有这样的字符则返回零。

我的代码:

find(c: CHARACTER; position: INTEGER): INTEGER
   require
            .....
   do

            .....
   ensure 
        across word as w
        some
             (w.item = c and w.cursor_index >= position)
        end
   end

这个布尔相等的问题是当使用find(c,pos)并且没有找到任何内容时,该功能会抛出一个条件违规。

我试图让它仅在单词中不存在给定的c字符时才允许输出该功能

2 个答案:

答案 0 :(得分:1)

假设它应该是一个完整的后置条件,让我们根据具体情况来看问题:

  1. Q值。允许的输出值范围是多少?
    答:结果可以是0word中从position开始的任何有效排名:

    valid_result_range: Result = 0 or position <= Result and Result <= word.count
    

    这里我们假设position是非负的(希望这是在前提条件中指定的)。

  2. Q值。如果没有匹配的字符,输出值是多少? A.输出为0。索引从position开始的所有字符都不匹配:

    zero_if_not_found: (Result = 0) =
        across word as wc all
            position <= wc.target_index implies wc.item /= c
        end
    
  3. Q值。如果有匹配的字符,输出值是多少?
    答:这是从position开始的相应字符的第一个位置:

    non_zero_if_found: (Result /= 0) implies
       (
          word [Result] = c
       and
          across word as wc all
             (position <= wc.target_index and w.target_index < Result) implies
             wc.item /= c
          end
       )
    

    这个后置条件有两个部分。一个人检查是否找到了角色。另一个检查在该位置之前没有匹配的字符 编辑:原始代码以(Result /= 0) = ...而不是(Result /= 0) implies ...开头。当word [Result]时,这会导致Result = 0中的断言违规。如果implies之前的表达式为implies,则False之前的表达式为non_zero_if_found,则Result之后的表达式不会被评估。

  4. 最后的后置条件是上面所有断言的组合。断言的顺序很重要,因为word依赖于(1, 21, 2, 7, 6,16)((1),(21), (2), (7), (6),(16))的有效索引这一事实。

答案 1 :(得分:1)

我会稍微改变亚历山大的答案:

zero_if_not_found :(结果= 0)暗示...... non_zero_if_found :(结果/ = 0)暗示......

要了解原因,请考虑当Result = 0时会发生什么,我们评估Alexander的non_zero_if_found:

(结果/ = 0)评估为False 然后单词[Result] = c计算前提条件失败(valid_index - 我假设word是STRING类型)。 (将[结果]更改为单词[结果],因为这是亚历山大的错字,我认为)

使用隐形可以防止这种情况,因为RHS没有得到评估。