如何在Dafny中编写简洁的非空集合最小值函数?附代码求助
Great question! Your initial recursive approach is solid, but we can simplify it significantly by leveraging Dafny's built-in utilities and reducing redundant assertions that the verifier can infer automatically. Here are two streamlined versions:
1. Simplified Recursive Version
This keeps your core recursive logic but cuts down on boilerplate and unnecessary assertions:
method minimum(s: set<int>) returns (out: int) requires |s| >= 1 ensures forall t: int :: t in s ==> out <= t { var y :| y in s; out := if |s| > 1 then min(y, minimum(s - {y})) else y; }
Key Improvements:
- Replaced the manual conditional check for
y < mwith Dafny's built-inminfunction for integers, making the code more readable. - Removed redundant assertions like
assert |s| == 1orassert s - {y} == {}—Dafny's verifier can automatically deduce these facts from the precondition and branch condition. - Collapsed the if-else block into a single expression for conciseness.
2. Ultra-Concise Selection Expression Version
If you want to skip explicit recursion entirely, Dafny supports direct selection of the minimum element using a choice expression, which aligns with the mathematical definition of a set's minimum:
method minimum(s: set<int>) returns (out: int) requires |s| >= 1 ensures forall t: int :: t in s ==> out <= t { out :| out in s && forall t: int :: t in s ==> out <= t; }
How This Works:
- The
:|operator tells Dafny to select an elementoutfrom the set that satisfies the following predicate:outis ins, and every element insis greater than or equal toout. - The precondition
|s| >= 1guarantees that such an element exists, so the choice is valid. - This version is extremely compact and directly mirrors the formal specification of the minimum value.
Both implementations will pass Dafny's verification, with the second option being the most concise while still being fully verifiable.
内容的提问来源于stack exchange,提问作者smithjonesjr

