UPDATEDSchleifeninvariante nicht stark genug, um bei der Manipulation (Array) Felder dieser
Probleme auf einigen dafny Probleme zu lösen, mit der gegebenen Klasse und jeweiligen Verfahren beschrieben. Wenn Sie etwas anderes brauchen, bitte sagen Sie mir, ich danke Ihnen im Voraus. Auch der Link wird mit diesem Code in Rise4fun aktualisiert.
class TextEdit {
var text:array<char>; //conteúdo
var scrap: array<char>; //conteúdo temporariamente guardado para copy/paste
var tlen:int; //length di text
var slen:int; //length di scrap
var at:int; //current position
var sellen:int; //length of the selection
method key(ch:char)
modifies this, text;
requires TextInv();
requires tlen+1<text.Length && sellen == 0;
ensures TextInv();
{
var tempChar:array<char> := new array<char>;
tempChar[0] := ch;
insert(text, tlen, tempChar, 1, at);
at := at + 1;
tlen := tlen + 1;
}
method select(sel:int, sl:int)
modifies this;
requires TextInv() && 0 <= sel && 0 <= sl && 0 <= sel+sl <= tlen;
ensures TextInv();
{
at := sel;
sellen := sl;
}
method copy()
modifies this,scrap;
requires TextInv() && sellen > 0;
requires scrap != null;
ensures TextInv();
ensures slen == sellen;
{
//emptying scrap
delete(scrap, slen, 0, slen);
slen := 0;
var i:int := 0;
while(i<sellen)
invariant 0<=i<=sellen;
invariant slen == i;
//cada posição do scrap estará vazia
//invariant forall j :: 0<=j<i ==> scrap[j] == ' ';
//só depois será preenchida
invariant forall k :: i<=k<sellen ==> scrap[k] == text[at+k];
{
scrap[i] := text[at+i];
slen := slen + 1;
i := i + 1;
}
}
method cut()
requires scrap!=null && text!=null;
modifies this,text, scrap;
requires TextInv() && sellen > 0;
ensures TextInv();
ensures slen == sellen;
{
//emptying scrap
delete(scrap, slen, 0, slen);
slen := 0;
var i:int := 0;
while(i<sellen)
invariant i<=0<=sellen;
//cada posição do scrap estará vazia
// invariant forall j :: 0<=j<i ==> scrap[j] == ' ';
//só depois será preenchida
invariant forall k :: i<=k<sellen ==> scrap[k] == text[at+k];
{
scrap[i] := text[at+i];
slen := slen + 1;
i := i + 1;
}
delete(text, tlen, at, sellen);
tlen := tlen - slen;
}
method paste()
modifies this,text;
requires TextInv() && 0 <= slen+tlen < text.Length && sellen == 0;
ensures TextInv();
ensures tlen == old(tlen)+slen;
ensures at == old(at)+slen;
{
if(slen>0)
{
insert(text, tlen, scrap, slen, at);
tlen := tlen + slen;
at := at + slen;
}
}
function TextInv():bool
reads this;
{
text != null && 0 <= tlen <= text.Length && scrap != text &&
0 <= at <= tlen && 0 <= sellen && 0 <= at+sellen <= tlen &&
scrap != null && 0 <= slen <= scrap.Length == text.Length
}
method insert(line:array<char>, l:int, nl:array<char>, p:int, at:int)
requires line != null && nl != null
requires 0 <= l+p <= line.Length // line has enough space
requires 0 <= p <= nl.Length // string in nl is shorter than nl
requires 0 <= at <= l // insert position within line
modifies line
ensures line != null;
ensures forall i :: (0<=i<p) ==> line[at+i] == nl[i] // ok now
{
ghost var initialLine := line[..];
// first we need to move the characters to the right
var i:int := l;
while(i>at)
invariant line[0..i] == initialLine[0..i]
invariant line[i+p..l+p] == initialLine[i..l]
invariant at<=i<=l
{
i := i - 1;
line[i+p] := line[i];
}
assert line[0..at] == initialLine[0..at];
assert line[at+p..l+p] == initialLine[at..l];
i := 0;
while(i<p)
invariant 0<=i<=p
invariant line[0..at] == initialLine[0..at]
invariant line[at..at+i] == nl[0..i]
invariant line[at+p..l+p] == initialLine[at..l]
{
line[at + i] := nl[i];
i := i + 1;
}
assert line[0..at] == initialLine[0..at];
assert line[at..at+p] == nl[0..p];
assert line[at+p..l+p] == initialLine[at..l];
}
method delete(line:array<char>, l:nat, at:nat, p:nat)
requires line!=null
requires l <= line.Length
requires at+p <= l
modifies line
ensures line!=null
ensures line[..at] == old(line[..at])
ensures line[at..l-p] == old(line[at+p..l])
ensures forall i :: l-p <= i < l ==> line[i] == ' '
{
var i:nat := 0;
while(i < l-(at+p))
invariant i <= l-(at+p)
invariant at+p+i >= at+i
invariant line[..at] == old(line[..at])
invariant line[at..at+i] == old(line[at+p..at+p+i])
invariant line[at+i..l] == old(line[at+i..l]) // future is untouched
{
line[at+i] := line[at+p+i];
i := i+1;
}
var j:nat := l-p;
while(j < l)
invariant l-p <= j <= l
invariant line[..at] == old(line[..at])
invariant line[at..l-p] == old(line[at+p..l])
invariant forall i :: l-p <= i < j ==> line[i] == ' '
{
line[j] := ' ';
j := j+1;
}
}
}
Ich denke, es gibt einige Teile aus dem Code fehlt. Vielleicht kannst du es auf rise4fun (http://rise4fun.com/Dafny/) setzen und es zu dem Punkt bringen, wo die relevanten Fehler dort angezeigt werden. Aktualisieren Sie dann die Frage mit einem Link zu diesem Code.Es sieht so aus als ob die Methoden "Einfügen" und "Löschen" fehlen. – lexicalscope
ok Ich habe gerade die Frage aktualisiert – pmpc2
@lexicalscope Dies ist der Link zu der neuesten Version des Codes http://rise4fun.com/Dafny/0rit – MMrj