I'm trying to define a matrix transpose method and functions in Dafny. I'm having difficulty defining the function version.
/** verifies **/
method transpose(matrix: array2<real>) returns (result: array2<real>)
ensures result.Length0 == matrix.Length1 && result.Length1 == matrix.Length0
ensures forall i, j :: 0 <= i < matrix.Length1 && 0 <= j < matrix.Length0 ==> result[i,j] == matrix[j,i]
{
result := new real[matrix.Length1, matrix.Length0]((i,j) reads matrix => if 0 <= i < matrix.Length1 && 0 <= j < matrix.Length0 then matrix[j,i] else 0.0);
assert result.Length0 == matrix.Length1;
assert result.Length1 == matrix.Length0;
}
/** says it is an invalid LogicalExpresion**/
function ftranspose(matrix: array2<real>): array2<real>
reads matrix
ensures ftranspose(matrix).Length0 == matrix.Length1 && ftranspose(matrix).Length1 == matrix.Length0
ensures forall i, j :: 0 <= i < matrix.Length1 && 0 <= j < matrix.Length0 ==> ftranspose(matrix)[i,j] == matrix[j,i]
{
new real[matrix.Length1, matrix.Length0]((i,j) reads matrix => if 0 <= i < matrix.Length1 && 0 <= j < matrix.Length0 then matrix[j,i] else 0.0)
}
I'm not quite sure why it says it is an invalid logical expression since in the method I am able to assign it to a variable, which makes me assume that it is an expression.
I can see here in the docs that
Array allocation is permitted in ghost contexts. If any expression used to specify a dimension or initialization value is ghost, then the new allocation can only be used in ghost contexts. Because the elements of an array are non-ghost, an array allocated in a ghost context in effect cannot be changed after initialization.
So it seems like I should be able to define a new array in a function. What is the correct syntax here?