How to clear multidimensional array of Word in Delphi? - delphi

I am using Delphi 7 and I try to clear (i.e fill with zeros) the array of declaration:
const CONST_MAX_INDEX_AllColumnsSeparators = 3658;
type TAllColumnsSeparators = array[0..CONST_MAX_INDEX_AllColumnsSeparators] of Word;
type ColSeparators = Array[0..11] of TAllColumnsSeparators; // count of columns
var All_separators: ColSeparators;
Acoording this page, there should be function System.Array.Clear - but seems like this could be for newer IDE than Delphi v. 7.
System.Array.Clear(All_separators, 0, CONST_MAX_INDEX_AllColumnsSeparators+1);
I got error undefined identifier Array.
I thought, I could to do this in a loop reseting manually, but I guess that would be slow performance job.
Notice: I have 63 files processed in a loop which needs to reset this array in every cycle, so this command will be nested in a loop. So I guess there should be some smart way to do it fast and easy without another control loop.

Notice that, given your
const
CONST_MAX_INDEX_AllColumnsSeparators = 3658;
type
TAllColumnsSeparators = array[0..CONST_MAX_INDEX_AllColumnsSeparators] of Word;
TColSeparators = array[0..11] of TAllColumnsSeparators;
both types are static arrays which are value types. Hence, the outermost array type is also a value type containing nothing but a sequence of Words. Hence, to fill such a variable with zeros (zero Words), you only need to fill its memory with zeros (zero Bytes):
var
AllSeparators: TColSeparators;
begin
FillChar(AllSeparators, SizeOf(AllSeparators), 0);

Related

Converting a slice to an array

I have a slice that I have guaranteed (in runtime) that its length is at least 8. I want to convert that slice to an array because I need to use std.mem.bytesAsValue() in order to create an f64 from raw bytes (for context, I'm implementing a binary serialization format).
I solved it like this, but I'd like to know if there is a better syntax for achieving the same goal:
var array: [8]u8 = undefined;
array[0] = slice[0];
array[1] = slice[1];
array[2] = slice[2];
array[3] = slice[3];
array[4] = slice[4];
array[5] = slice[5];
array[6] = slice[6];
array[7] = slice[7];
Given your goal, if alignment works out, you could just cast the slice pointer to a pointer to a f64: #ptrCast(*f64, slice.ptr). This saves you from even having to copy anything, in case you don't need to do that at all.
Note that bytesAsValues is a stdlib function that uses compiler builtins, if the signature doesn't match your needs, you can just skip it and use directly the builtins, like I mentioned above. Don't be afraid to read the stdlib source code.
Here's a godbolt link with some examples on how to do the conversion in-place (by casting the pointer) and by copying everything immediately as a float: https://zig.godbolt.org/z/3Y9o5zvfe
you can do this by std.mem.copy
var array = slice[0..8].*;
or using std.mem.copy
std.mem.copy(u8, &array, slice[0..2]);
while i think you can just need to put slice[0..8] as argument instead creating a variable

Dafny: types with contraints

I am trying some things in Dafny. I want to code a simple datastructure that holds an uncompressed image in memory:
datatype image' = image(width: int, height: int, data: array<byte>)
newtype byte = b: int | 0 <= b <= 255
Actually using it:
method Main() {
var dat := [1,2,3];
var im := image(1, 3, dat);
}
datatype image' = image(width: int, height: int, data: array<byte>)
newtype byte = b: int | 0 <= b <= 255
leads Dafny to complain:
stdin.dfy(3,24): Error: incorrect type of datatype constructor argument (found seq, expected array)
1 resolution/type errors detected in stdin.dfy
I might also want to demand that the byte array is not null, and the size of the byte array is equal to width * height * 3 (to store three bytes representing the RGB value of that pixel).
What way should I enforce this? I looked into newtype, which lets you put some constraints on variables with a certain type, but this works only for numeric types.
Dafny supports both immutable sequences (which are like mathematical sequences of elements) and mutable arrays (which are, like in C and Java, pointers to elements). The error you're getting is telling you that you're calling the image constructor with a seq<byte> value where an array<byte> value is expected.
You can fix the problem by replacing your definition of dat with:
var dat := new byte[3];
dat[0], dat[1], dat[2] := 1, 2, 3;
However, the more typical thing, if you're using a datatype (which is immutable), would be to use a sequence. So, you probably want to instead change your definition of image to:
datatype image = image(width: int, height: int, data: seq<byte>)
Btw, note that Dafny allows you to name a type and one of its constructors the same, so there's no reason to name one of them with a prime (unless you want to, of course).
Another matter of style is to use a half-open interval in your definition of byte:
newtype byte = b: int | 0 <= b < 256
Since half-open intervals are prevalent in computer science, Dafny's syntax favors them. For example, for a sequence s, the expression s[52..57] denotes a subsequence of s of length 5 (that is, 57 minus 52) starting in s at index 52. One more thing, you can also leave out the type int of b if you want, since Dafny will infer it:
newtype byte = b | 0 <= b < 256
You also asked about the possibility of adding a type constraint, so that the sequence in your datatype will always be of length 3. As you discovered, you cannot do this with a newtype, because newtype (at least for now) only works with numeric types. You can (almost) use a subset type, however. This would be done as follows:
type triple = s: seq<byte> | |s| == 3
(In this example, the first vertical bar is like the one in the newtype declaration and says "such that", whereas the next two denote the length operator on sequences.) The trouble with this declaration is that types must be nonempty and Dafny isn't convinced that there are any values that satisfy the constraint of triple. Well, Dafny is not trying very hard. The plan is to add a witness clause to the type (and newtype) declaration, so that a programmer can show Dafny a value that belongs to the triple type. However, this support is waiting for some implementation changes that will allow customized initial values, so you cannot use this constraint at this time.
Not that you want it here, but Dafny would let you give a weaker constraint that admits the empty sequence:
type triple = s: seq<byte> | |s| <= 3
So, instead, if you want to talk about that an image value has a data component of length 3, then introduce a predicate:
predicate GoodImage(img: image)
{
|img.data| == 3
}
and use this predicate in specifications like pre- and postconditions.
Program safely,
Rustan

set of WideChar: Sets may have at most 256 elements

I have this line:
const
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')];
The above does not compile, with error:
[Error] Sets may have at most 256 elements
But this line does compile ok:
var WS: WideString;
if WS[1] in [WideChar('A')..WideChar('Z')] then...
And this also compiles ok:
const
MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];
...
if WS[1] in MY_SET then...
Why is that?
EDIT: My question is why if WS[1] in [WideChar('A')..WideChar('Z')] compiles? and why MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')]; compiles? aren't they also need to apply to the set rules?
A valid set has to obey two rules:
Each element in a set must have an ordinal value less than 256.
The set must not have more than 256 elements.
MY_SET: set of WideChar = [WideChar('A')..WideChar('Z')];
Here you declare a set type (Set of WideChar) which has more than 256 elements -> Compiler error.
if WS[1] in [WideChar('A')..WideChar('Z')]
Here, the compiler sees WideChar('A') as an ordinal value. This value and all other values in the set are below 256. This is ok with rule 1.
The number of unique elements are also within limits (Ord('Z')-Ord('A')+1), so the 2nd rules passes.
MY_SET = [WideChar('A')..WideChar('Z'), WideChar('a')..WideChar('z')];
Here you declare a set that also fulfills the requirements as above. Note that the compiler sees this as a set of ordinal values, not as a set of WideChar.
A set can have no more than 256 elements.
Even with so few elements the set already uses 32 bytes.
From the documentation:
A set is a bit array where each bit indicates whether an element is in the set or not. The maximum number of elements in a set is 256, so a set never occupies more than 32 bytes. The number of bytes occupied by a particular set is equal to
(Max div 8) - (Min div 8) + 1
For this reason only sets of byte, (ansi)char, boolean and enumerations with fewer than 257 elements are possible.
Because widechar uses 2 bytes it can have 65536 possible values.
A set of widechar would take up 8Kb, too large to be practical.
type
Capitals = 'A'..'Z';
const
MY_SET: set of Capitals = [WideChar('A')..WideChar('Z')];
Will compile and work the same.
It does seem a bit silly to use widechar if your code ignores unicode.
As written only the English capitals are recognized, you do not take into account different locales.
In this case it would be better to use code like
if (AWideChar >= 'A') and (AWideChar <= 'Z') ....
That will work no matter how many chars fall in between.
Obviously you can encapsulate this in a function to save on typing.
If you insist on having large sets, see this answer: https://stackoverflow.com/a/2281327/650492

How do you remove (or 'unstore') an element from a Z3 array?

It is easy to store an element into a Z3 array. For example:
ArrayExpr mem = ctx.MkArrayConst("mem", ctx.MkBitVecSort(nBits), ctx.MkBitVecSort(nBits));
BitVecExpr addr = ctx.MkBV(10, nBits);
BitVecExpr value = ctx.MkBV(20, nBits);
mem = ctx.MkStore(mem, addr, value);
But how do you change or remove an element from such an array?
The method MkSetDel with signature "ArrayExpr MkSetDel(ArrayExpr set, Expr element)" seem to suggest that it can be (mis)used for that purpose; but sadly, it only accepts sets.
If there exists a method to iterate over the asserted elements in the array, I could populate a new array and skip the one I am changing or deleting. But I can not find such a method.
I guess I missing something.
Z3 essentially supports a first-order logic with theory extensions such as array, and consequently only supports values, which are by definition immutable. Arrays are also values, and cannot be changed. Updating an array (at some index) yields a new array (an array value) whose elements are equal to those from the original array except at the index that your change affected.
See the Z3 tutorial on array for more details about arrays and the store and select operations.
By the way, what do you mean with "remove an element from an array"? Would that shorten the array by cutting out an element? That isn't even supported in most programming languages (where arrays are consecutive memory locations). Would it shift all subsequent elements to the front?

Difference between CompareStr and '=' for Strings in Delphi

I just want to know the difference between CompareStr and = for comparing strings in Delphi. Both yield the same result.
if(str2[i] = str1[i]) then
ShowMessage('Palindrome')
if(CompareStr(str2[i], str1[i]) = 0) then
ShowMessage('Palindrome')
Both show message Palindrome.
Use CompareStr not when you just want to see whether two strings are equal, but when you want to know how one string compares relative to another. It will return a value less than 0 if the first argument appears first, asciibetically, and it will return a value greater than zero if the first argument belongs after the second.
Without CompareStr, you might have code like this:
if str1[i] = str2[i] then begin
// They're equal
end else if str1[i] < str2[i] then begin
// str1 comes first
end else begin
// str2 comes first
end;
That compares str1 and str2 twice. With CompareStr, you can cut out one of the string comparisons and replace it with a cheaper integer comparison:
x := CompareStr(str1[i], str2[i]);
if x = 0 then begin
// They're equal
end else if x < 0 then begin
// str1 comes first
end else begin
// str2 comes first
end;
As Gerry's answer explains, the function is particularly useful in sorting functions, especially since it has the same interface as other comparison functions like CompareText and AnsiCompareStr. The sorting function is a template method, and each of the functions serves as a comparison strategy.
If all you want to do is test for equality, use the = operator — it's easier to read. Use CompareStr when you need the extra functionality it provides.
Assuming Str1 and Str2 are strings, rather than arrays (or lists) or string, the first version will be more efficient, as the second version will first copy str1[i] and str2[i] to two new strings, then call a function, with the associated overhead.
The first version will simply compare the single characters referred to by str1[i] and str2[i]
If you are only interested if strings are the same, use =. If you need to know if strings are the same, OR which string is greater, then use CompareStr.
CompareStr is particularly useful when sorting lists, e.g, with TList.Sort(CompareFunc) or TStringList.Sort(CompareFunc)
If you want case-insensitive comparisons, use CompareText.
The result is not the same when compared strings are not equal. The result of CompareStr or AnsiCompareStr is of Integer type showing some more information literally how those strings compare. Take a look at http://www.delphibasics.co.uk/RTL.asp?Name=AnsiCompareStr
Apart from the return value (integer versus boolean), from the code it says that for CompareStr "the compare operation is based on the 8-bit ordinal value of each character and is not affected by the current user locale". So it looks like CompareStr was originally part of the FastCode routines and is in essence an optimised Ansi version developed for performance reasons. I have always tended to go with "=", "<", ">", etc.

Resources