-
Notifications
You must be signed in to change notification settings - Fork 1
/
059-largest-prime-factor.dfy
58 lines (56 loc) · 1.35 KB
/
059-largest-prime-factor.dfy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
method is_prime(k: int) returns (result: bool)
// pre-conditions-start
requires k >= 2
// pre-conditions-end
// post-conditions-start
ensures result ==> forall i :: 2 <= i < k ==> k % i != 0
ensures !result ==> exists j :: 2 <= j < k && k % j == 0
// post-conditions-end
{
// impl-start
var i := 2;
result := true;
while i < k
// invariants-start
invariant 2 <= i <= k
invariant !result ==> exists j :: 2 <= j < i && k % j == 0
invariant result ==> forall j :: 2 <= j < i ==> k % j != 0
// invariants-end
{
if k % i == 0 {
result := false;
}
i := i + 1;
}
// impl-end
}
predicate is_prime_pred(k: int)
{
forall i :: 2 <= i < k ==> k % i != 0
}
method largest_prime_factor(n: int) returns (largest: int)
// pre-conditions-start
requires n >= 2
// pre-conditions-end
// post-conditions-start
ensures 1 <= largest <= n && (largest == 1 || (largest > 1 && is_prime_pred(largest)))
// post-conditions-end
{
// impl-start
largest := 1;
var j := 2;
while j <= n
// invariants-start
invariant 2 <= j <= n + 1
invariant 1 <= largest < j
invariant largest == 1 || (largest > 1 && is_prime_pred(largest))
// invariants-end
{
var flag := is_prime(j);
if n % j == 0 && flag {
largest := if largest > j then largest else j;
}
j := j + 1;
}
// impl-end
}