From: Mark Wilson <markwilson@wilsonnet.technology>
Subject: Re: Postcondition on Strings.Maps.To_Sequence
Date: Fri, 3 Sep 2021 04:46:09 -0700 (PDT) [thread overview]
Message-ID: <7df72bca-16f6-4aac-9f95-ef09cf0bbca3n@googlegroups.com> (raw)
In-Reply-To: <4fc90fe9-f75e-437c-babd-05ea194d42e6n@googlegroups.com>
Good morning,
It's fairly easy to prove the positive case (level 2, latest AdaCore community edition) that if a character is in a set, it's also in a sequence
--------------------------------------------------------------------------------
function Element
(Set : in Character_Set;
Value : in Character)
return Boolean
with
Ghost,
Global => null,
Depends => (Element'Result => (Set, Value));
--------------------------------------------------------------------------------
function Element
(Set : in Character_Set;
Value : in Character)
return Boolean
is
(Set (Value));
--------------------------------------------------------------------------------
function To_Sequence
(Set : in Character_Set)
return Character_Sequence
with
Global => null,
Depends => (To_Sequence'Result => (Set)),
Post => (for all m in Character'Range =>
(if Element (Set, m) then
(for some n in To_Sequence'Result'Range =>
To_Sequence'Result(n) = m)));
--------------------------------------------------------------------------------
function To_Sequence
(Set : in Character_Set)
return Character_Sequence
is
Result : String (1 .. Character'Pos (Character'Last) + 1)
with Relaxed_Initialization;
Count : Natural := 0;
begin
for Char in Set'Range loop
pragma Warnings (Off);
pragma Loop_Invariant
(Count <= Character'Pos (Char));
pragma Loop_Invariant
(Result (Result'First .. Count)'Initialized);
pragma Loop_Invariant
(if Char > Set'First then
(for all m in Set'First .. Character'Pred (Char) =>
(if Element (Set, m) then
(for some n in Result'First .. Count =>
Result(n) = m))));
pragma Warnings (On);
if Set(Char) then
Count := Count + 1;
Result(Count) := Char;
end if;
end loop;
return Result (1 .. Count);
end To_Sequence;
--------------------------------------------------------------------------------
The pragma Warnings (Off); are there since the Ada compiler doesn't understand Relaxed_Initialization. We have to enclose the entire set of Loop_Invariants since Spark requires them all to be next to each other, and if we insert the pragma Warnings just around the 'Initialized invariant, we get warnings.
Of course, we turn them back on as soon as we can.
Respectively, the loop invariants prove three things, here:
(i) That count is in range
(ii) That we're initializing Result as we go along
(iii) If a character is in the Set, then it's in the sequence
This is a *partial proof*. (At least) two more things to do here:
(i) Prove that sequence is ordered - the original Ada design, whilst not specifying that the sequence is ordered, always returned it ordered, and you know - I mean you *just* know, that someone relies on that!
(ii) Prove that if a character is not in the set, then it's not in the sequence
This should get you going.
Cheers,
M
next prev parent reply other threads:[~2021-09-03 11:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-29 9:38 Postcondition on Strings.Maps.To_Sequence mockturtle
2021-09-01 21:07 ` Stephen Leake
2021-09-02 19:17 ` mockturtle
2021-09-03 11:46 ` Mark Wilson [this message]
2021-09-03 11:53 ` Mark Wilson
2021-09-03 12:05 ` Mark Wilson
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox