The question is rather simple: why does the assertion bellow return "assertion violation".
method test()
{
var a := new int[5];
a[0] := 1;
a[1] := 1;
a[2] := 2;
a[3] := 3;
a[4] := 3;
var b := new int[3];
b[0] := 1;
b[1] := 2;
b[2] := 3;
assert(forall i :: exists j :: ((0 <= i < 5) && (0 <= j < 3)) ==> (a[i] == b[j]));
}
Here's one way to fix it. Add the following assertions before your assertion.
assert b[0] == 1;
assert b[1] == 2;
It seems that under a quantifier can only remember the value of the most recent assignment to b, which explains why no extra assertion about b[2] is required.
Related
I have a combination of data of RGBA values in a memory table I got from Rest Response Adapter like these for each row:
"R", "A"
"B"
"A","R"
"R","G"
"B"
...
I need to sort these data based on the maximum of occurrence or repeat inside the table. For example values "R","A" = "A","Rthis mean the count of this value is 2 and so on.
I was thinking to use Dictionary but it does not have a method to count values and consider RA = AR. And if I loop for each value it will take very long time so how I should solve this problem ?
It seems that you have something highly specific. In this case you can optimize it using bit operations:
type
TCounts = array[0..15] of Integer;
const
RGBA_R = 1;
RGBA_G = 2;
RGBA_B = 4;
RGBA_A = 8;
function GetCounts(const Strings: array of string): TCounts;
var
i, j, k: Integer;
s: string;
begin
Fillchar(Result, Sizeof(Result), 0);
for i := 0 to Length(Strings) - 1 do
begin
k := 0;
s := Strings[i];
for j := 1 to Length(s) do
case s[i] of
'R': k := k or RGBA_R;
'G': k := k or RGBA_G;
'B': k := k or RGBA_B;
'A': k := k or RGBA_A;
'"', ' ', ',': ; // do nothing
else
// handle error here
end;
Inc(Result[k]);
end;
end;
The total number of all combinations of R, G, B is Result[RGBA_R or RGBA_G + RGBA_B].
I have written this function that converts a double to a fraction returning a string:
function getFraction(x: double):string;
var h1, h2, k1, k2, y, a, aux : double;
begin
//Setup the values
h1 := 1;
h2 := 0;
k1 := 0;
k2 := 1;
y := x;
//Generates the fraction
repeat
begin
a := floor(y);
aux := h1;
h1 := a*h1+h2;
h2 := aux;
aux := k1;
k1 := a*k1+k2;
k2 := aux;
y := 1/(y-a) ;
end;
until ( abs(x-h1/k1) > x*0.000001);
//Output
Result := FloatToStr(h1) + '/' + FloatToStr(k1);
end;
And then I call it in this way: Edit7.Text := getFraction(x); where the x is a double. I am using lazarus and I always have this error:
I am sure that the code above has not logic hassles because it becomes from a Java class that I have implemented last week in a project (code).
What am I missing? The full code of my Delphi project can be found here.
The error will surely occur here:
y := 1/(y-a);
When y-a evaluates to 0 then this will result in a divide by zero error. That happens when you pass 0 to the function.
Or perhaps when you evaluate h1/k1 the value of k1 is zero. Again, that's a floating point exception.
Even when you trap those conditions, I cannot make the function return anything that seems remotely sensible to me. So, once you fix the exception condition then you'll have further work.
I'm sure that you could have worked this out in the debugger, even if you could not do so by reading the code. The debugger will tell you which line produced the error and then it is merely a matter of inspecting the value of the operands in the expression.
For what it's worth, your repeat loop is the wrong way around. You're replacing a java do/while with repeat/until - the condition has to invert for this to work.
To avoid divide by zero, just check and break out of the loop. That will save the crash, but I haven't verified that it will always produce the right answer, although it does for previously deadly inputs like 0.25 or 0.5.
repeat
begin
a := floor(y);
aux := h1;
h1 := a * h1 + h2;
h2 := aux;
aux := k1;
k1 := a * k1 + k2;
k2 := aux;
if (y - a = 0) or (k1 = 0) then break; //!!
y := 1 / (y - a) ;
end;
until (Abs(x - h1 / k1) <= x * 0.000001); // Here <= instead of >
I am trying to port an existing random generator based on 128 bit XorShift from C. But I have trouble with generating the seed which is just generating the same number again and again.
static uint64_t s[ 2 ];
static uint64_t __inline next(void) {
uint64_t s1 = s[ 0 ];
const uint64_t s0 = s[ 1 ];
s[ 0 ] = s0;
s1 ^= s1 << 23;
return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0;
}
uint64_t getusertime() {
struct rusage rusage;
getrusage( 0, &rusage );
return rusage.ru_utime.tv_sec * 1000000ULL + ( rusage.ru_utime.tv_usec / 1000 ) * 1000;
}
int main( int argc, char* argv[] ) {
const long long int n = strtoll( argv[1], NULL, 0 );
uint64_t t = 0;
for( int i = 0; i < 2; i++ ) s[ i ] = -1ULL / 3;
const int64_t start = getusertime();
for( long long int i = n; i-- != 0; ) t ^= next();
const int64_t elapsed = getusertime() - start;
const double secs = elapsed / 1E6;
printf( "%f s, %.02f queries/s, %.02f ns/query\n", secs, n / secs, 1E9 * secs / n );
if ( t == 0 ) putchar( 0 );
return 0;
}
program Project1;
var
S: Array [0..1] of UInt64;
function XorShift128: UInt64;
var
s0, s1: UInt64;
begin
s1 := s[0];
s0 := s[1];
s[0] := s0;
s1 := s1 xor (s1 shl 23);
s[1] := (s1 xor s0 xor (s1 shr 17) xor (s0 shr 26));
Result := s[1] + s0;
end;
procedure GenerateSeed;
var
I: Integer;
begin
for I := 0 to High(S) do
S[I] := MaxLongInt div 3;
end;
var
I: UInt64;
begin
GenerateSeed;
I := XorShift128;
end.
The reason you get the same value every time you run the program in the question is that you use the same seed every time. If I am understanding your comments correctly. The other difference between the C and the Pascal is the seed – see below.
However, your code is fine and is an accurate translation of the C code. The output of this C program:
#include <stdio.h>
#include <stdint.h>
static uint64_t s[ 2 ];
static uint64_t __inline next(void) {
uint64_t s1 = s[ 0 ];
const uint64_t s0 = s[ 1 ];
s[ 0 ] = s0;
s1 ^= s1 << 23;
return ( s[ 1 ] = ( s1 ^ s0 ^ ( s1 >> 17 ) ^ ( s0 >> 26 ) ) ) + s0;
}
int main(void)
{
s[ 0 ] = s[ 1 ] = 715827882; // the value of MaxLongInt div 3
printf("%llu\n", next());
printf("%llu\n", next());
printf("%llu\n", next());
return 0;
}
is
6004846026386057
6004846115863870
12676181551404632061
The output of this Delphi program:
program Project1;
{$APPTYPE CONSOLE}
var
S: Array [0..1] of UInt64;
function XorShift128: UInt64;
var
s0, s1: UInt64;
begin
s1 := s[0];
s0 := s[1];
s[0] := s0;
s1 := s1 xor (s1 shl 23);
s[1] := (s1 xor s0 xor (s1 shr 17) xor (s0 shr 26));
Result := s[1] + s0;
end;
procedure GenerateSeed;
var
I: Integer;
begin
for I := 0 to High(S) do
S[I] := MaxLongInt div 3;
end;
begin
GenerateSeed;
Writeln(XorShift128);
Writeln(XorShift128);
Writeln(XorShift128);
end.
is
6004846026386057
6004846115863870
12676181551404632061
I note that the C code in the question uses a different seed from your translation. It seeds the state with -1ULL / 3 and that leads to this output:
46820872945684
46912499612351
13066320939010318272
To match that in the Delphi code you would use high(UInt64) div 3. Do that and you get the output above.
An important note here is that your Delphi code only supplies 64 bits of seed, but your C code supplies 128. I expect that you should supply 128 bits of seed.
I'm trying to find out if String is "mnemonic type"...
My mnemonic type consists of letters from 'a' to 'z' and from 'A' to 'Z', digits from '0' to '9', and additionaly '_'.
I build code like below. It should result with True if given string match my mnemonic pattern otherwise False:
TRes := True;
for I := 0 to (AString.Length - 1) do
begin
if not ((('0' <= AString[I]) and (AString[I] <= '9'))
or (('a' <= AString[I]) and (AString[I] <= 'z'))
or (('A' <= AString[I]) and (AString[I] <= 'Z'))
or (AString[I] = '_')) then
TRes := False;
end;
This code always results with False.
I'm assuming that since you tagged the question XE5, and used zero-based indexing, that your strings are zero-based. But perhaps that assumptions was mistaken.
Your logic is fine, although it is rather hard to read. The code in the question is already doing what you intend. At least the if statement does indeed perform the test that you intend.
Let's just re-write your code to make it easier to understand. I'm going to lay it our differently, and use a local loop variable to represent each character:
for C in AString do
begin
if not (
(('0' <= C) and (C <= '9')) // C is in range 0..9
or (('a' <= C) and (C <= 'z')) // C is in range a..z
or (('A' <= C) and (C <= 'Z')) // C is in range A..Z
or (C = '_') // C is _
) then
TRes := False;
end;
When written like that I'm sure that you will agree that it performs the test that you intend.
To make the code easier to understand however, I would write an IsValidIdentifierChar function:
function IsValidIdentifierChar(C: Char): Boolean;
begin
Result := ((C >= '0') and (C <= '9'))
or ((C >= 'A') and (C <= 'Z'))
or ((C >= 'a') and (C <= 'z'))
or (C = '_');
end;
As #TLama says, you can write IsValidIdentifierChar more concisely using CharInSet:
function IsValidIdentifierChar(C: Char): Boolean;
begin
Result := CharInSet(C, ['0'..'9', 'a'..'z', 'A'..'Z', '_']);
end;
Then you can build your loop on top of this function:
TRes := True;
for C in AString do
if not IsValidIdentifierChar(C) do
begin
TRes := False;
break;
end;
String type is 1-based. dynamic Arrays are 0-based. Better use for ... in so you are safe for future Delphi's.
Testing for ranges of possible character values can be done more efficiently (and more conciece) is CharInSet.
function IsMnemonic( AString: string ): Boolean;
var
Ch: Char;
begin
for Ch in AString do
if not CharInSet( Ch, [ '_', '0'..'9', 'A'..'Z', 'a'..'z' ] ) then
Exit( False );
Result := True;
end;
I'm trying to migrate some xml code from the default delphi XML routines to NativeXML, hopefully to improve the speed (a lot).
The XML files are of the form:
<Datafile>
<Header>
<Name>'My Name'</Name>
<Address>'My Address'</Address>
</Header>
<Body>
<ValuesSets>
<ValuesSet>
<v>1</v>
<v>2</v>
<v>3</v>
<v>4</v>
</ValuesSet>
<ValuesSet>
<v>5</v>
<v>6</v>
<v>7</v>
<v>8</v>
</ValuesSet>
</ValuesSets>
</Body>
</Datafile>
My problem is how to iterate through each of the sets of values. A more or less direct translation of the old code didn't work:
procedure TForm1.Button1Click(Sender: TObject);
var
AXMLDoc : TNativeXML ;
FileID : TFilename ;
I : Integer ;
J : Integer ;
HeaderNode : TXMLNode ;
BodyNode : TXMLNode ;
ValuesSetsNode : TXMLNode ;
ValuesSetNode : TXMLNode ;
Values : array of array of integer ;
begin
try
Memo1.Lines.Clear ;
FileID := 'Sample.XML' ;
Memo1.Lines.LoadFromFile (FileID) ;
AXMLDoc := TNativeXml.Create (nil) ;
AXMLDoc.LoadFromFile (FileID) ;
if Assigned(AXMLDoc.Root) then
begin
HeaderNode := AXMLDoc.Root.NodeByName ('Header') ;
if Assigned (HeaderNode) then
begin
// < process header items >
BodyNode := AXMLDoc .Root.NodeByName ('Body') ;
if Assigned (BodyNode) then
begin
ValuesSetsNode := BodyNode.NodeByName ('ValuesSets') ;
if Assigned (ValuesSetsNode) then
begin
SetLength (Values, ValuesSetsNode.NodeCount) ;
for i := 0 to ValuesSetsNode.NodeCount - 1 do
begin
ValuesSetNode := ValuesSetsNode [i] ;
if Assigned (ValuesSetNode) then
begin
SetLength (Values [i], ValuesSetNode.NodeCount) ;
for j := 0 to ValuesSetNode.NodeCount - 1 do
begin
Values [i, j] := StrToIntDef (ValuesSetNode [j].Value, 0) ;
end ;
end ;
end ;
end ;
end ;
end ;
end ;
for i := 0 to Length (Values) - 1 do
begin
for j := 0 to Length (Values [i]) - 1 do
begin
Memo1.Lines.Add (Format ('Values [%d, %d] = %d', [i, j, Values [i, j]])) ;
end ;
end ;
finally
FreeAndNil (AXMLDoc) ;
end ;
end ;
The output I get is:
Values [1, 0] = 0
Values [1, 1] = 1
Values [1, 2] = 0
Values [1, 3] = 2
Values [1, 4] = 0
Values [1, 5] = 3
Values [1, 6] = 0
Values [1, 7] = 4
Values [1, 8] = 0
Values [3, 0] = 0
Values [3, 1] = 5
Values [3, 2] = 0
Values [3, 3] = 6
Values [3, 4] = 0
Values [3, 5] = 7
Values [3, 6] = 0
Values [3, 7] = 8
Values [3, 8] = 0
and I was expecting:
Values [0, 0] = 1
Values [0, 1] = 2
Values [0, 2] = 3
Values [0, 3] = 4
Values [1, 0] = 5
Values [1, 1] = 6
Values [1, 2] = 7
Values [1, 3] = 8
so it seems as if the Nodes property of TNativeXML is not exactly the same as IXMLNode's ChildNodes property.
How do I iterate all the child nodes within a parent node? I don't want to give each one a unique name (<v1001>1234</v1001>, <v1002>4321</v1002>... etc), as I only ever need to access them sequentially, and don't want the speed penalty (or increased file size) of having to do a NodeByName for every value (there can be many of these values).
UPDATE **
NativeXML does have an equivalent to ChildNodes - it's called Containers (not ChildContainers as the online documentation would have you believe). The following worked:
var
AXMLDoc : TNativeXML ;
FileID : TFilename ;
I : Integer ;
J : Integer ;
HeaderNode : TXMLNode ;
BodyNode : TXMLNode ;
ValuesSetsNode : TXMLNode ;
ValuesSetNode : TXMLNode ;
Values : array of array of integer ;
begin
try
Memo1.Lines.Clear ;
FileID := 'Sample.XML' ;
Memo1.Lines.LoadFromFile (FileID) ;
AXMLDoc := TNativeXml.Create (nil) ;
AXMLDoc.LoadFromFile (FileID) ;
if Assigned(AXMLDoc.Root) then
begin
HeaderNode := AXMLDoc.Root.NodeByName ('Header') ;
if Assigned (HeaderNode) then
begin
// < process header items >
BodyNode := AXMLDoc .Root.NodeByName ('Body') ;
if Assigned (BodyNode) then
begin
ValuesSetsNode := BodyNode.NodeByName ('ValuesSets') ;
if Assigned (ValuesSetsNode) then
begin
SetLength (Values, ValuesSetsNode.ContainerCount) ;
for i := 0 to ValuesSetsNode.ContainerCount - 1 do
begin
ValuesSetNode := ValuesSetsNode.Containers [i] ;
if Assigned (ValuesSetNode) then
begin
SetLength (Values [i], ValuesSetNode.ContainerCount) ;
for j := 0 to ValuesSetNode.ContainerCount - 1 do
begin
Values [i, j] := StrToIntDef (ValuesSetNode.Containers [j].Value, 0) ;
end ;
end ;
end ;
end ;
end ;
end ;
end ;
for i := 0 to Length (Values) - 1 do
begin
for j := 0 to Length (Values [i]) - 1 do
begin
Memo1.Lines.Add (Format ('Values [%d, %d] = %d', [i, j, Values [i, j]])) ;
end ;
end ;
finally
FreeAndNil (AXMLDoc) ;
end ;
end ;
It's actually pretty slow - to read 32k float values takes many 10's of seconds.
OP :
so it seems as if the Nodes property of TNativeXML is not exactly the
same as IXMLNode's ChildNodes property.
You are right . There must be something more to be done to achieve this result.
procedure TForm1.Button1Click(Sender: TObject);
var
[...]
i , i2 : Integer ;
j , j2 : Integer ;
[...]
begin
try
Memo1.Lines.Clear ;
[...]
BodyNode := AXMLDoc .Root.NodeByName ('Body') ;
if Assigned (BodyNode) then
begin
ValuesSetsNode := BodyNode.NodeByName ('ValuesSets') ;
if Assigned (ValuesSetsNode) then
begin
SetLength (Values, ValuesSetsNode.NodeCount) ;
ValuesSetNode := ValuesSetsNode.NodeByName('ValuesSet') ;
if Assigned (ValuesSetNode) then
begin
i2:=0;
for i := 0 to ValuesSetSNode.NodeCount - 1 do begin
if i > 0 then ValuesSetNode := ValuesSetsNode.NextSibling(ValuesSetNode) ;
if ValuesSetNode=nil then break;
if ValuesSetNode.NodeCount > 0 then begin
SetLength(Values[i2], ValuesSetNode.NodeCount) ;
j2:=0;
for j := 0 to ValuesSetNode.NodeCount - 1 do begin
if pos(#13,ValuesSetNode[j].Value) > 0 then continue;
Values [i2, j2] := StrToIntDef (ValuesSetNode[j].Value, 0) ;
inc(j2);
end ; // for j
SetLength(Values[i2],j2);
inc(i2);
end;
end ; // for i
end; // ValuesSetNode
end; // ValuesSetsNode
end; // BodyNode
end; // HeaderNode
end; // AXMLDoc.Root
[...]
finally
FreeAndNil (AXMLDoc) ;
end ;
end ;
Delphi 5 / Delphi XE2 NativeXml 4.07