Check for divisibility by a three digit number in F# - f#

I want a function isDiv to return true if a number x is divisible by some number i between 100 and 999, and x/i is between 100 and 999; I attempted to write the method below;
let isDiv x =
for i in 101..999 do
if x%i == 0 && x/i > 100 && x/i < 999
0
the F# Interactive panel tells me that this is incomplete - Where have I gone wrong?

Your if has no corresponding then and equality comparison is = not ==.
But if you use a for-loop you will have to use somewhere a mutable, you can use a while-loop but I would use instead Seq.exists:
let isDiv x = Seq.exists (fun i -> x%i = 0 && x/i > 100 && x/i < 999) {101..999}

Related

dafny matrix expressions and functions

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?
Functions (even ghost functions) are not allowed to allocate memory or call methods, so calls to new cannot appear in function bodies.
This is because functions must be deterministic (return the same thing when called with the same arguments). As written, your function would return a different (fresh) object every time (reference types like arrays have reference equality, which means that they are the same if they live at the same address, not just if they have the same contents).
The passage you quoted is relevant for ghost methods, but does not apply to functions.
So the answer is 1. Don't use array which is heap based as Clément said. 2. Use datatypes. The following verifies...
datatype Matrix = Matrice(vals: seq<seq<real>>, rows: nat, columns: nat)
predicate isMatrix(mat: Matrix) {
mat.rows >= 1 && mat.columns >= 1 && |mat.vals| == mat.rows && forall i :: 0 <= i < mat.rows ==> |mat.vals[i]| == mat.columns
}
function method seqTranspose(mat: Matrix): Matrix
requires isMatrix(mat)
ensures isMatrix(seqTranspose(mat))
ensures seqTranspose(mat).columns == mat.rows
ensures seqTranspose(mat).rows == mat.columns
// ensures seqTranpose(matrix).Length0 == matrix.Length1 && ftranspose(matrix).Length1 == matrix.Length0
ensures forall i, j :: 0 <= i < mat.columns && 0 <= j < mat.rows ==> seqTranspose(mat).vals[i][j] == mat.vals[j][i]
{
Matrice(seq(mat.columns, i requires 0 <= i < mat.columns => seq(mat.rows, j requires 0 <= j < mat.rows => mat.vals[j][i])), mat.columns, mat.rows)
}
lemma matTranspose(mat: Matrix)
requires isMatrix(mat)
ensures seqTranspose(seqTranspose(mat)) == mat
{
assert forall i :: 0 <= i < |mat.vals| ==> mat.vals[i] == seqTranspose(seqTranspose(mat)).vals[i];
}

While loop with double conditional and || logical operator in Swift

I have a While Loop with a condition that limits it to repeat only 10 times, every time a cycle is repeated a constant D generates a random number in a range from 0 to 24, if D is 0, I change a variable dIsZero to true and prints the cycle where D is 0 for the first time.
var S = 0
var dIsZero = false
while S < 10 || dIsZero == false {
S += 1
let D = Int.random(in: 0...24)
if dIsZero == false && D == 0 {
dIsZero = true
print("D = 0 in a cycle \(S)/10")
}
}
My problem is that I want the While Loop can also end when D is 0 before the 10 cycles are completed. I already tried to put the logical operator || but it doesn't work and I get the following results:
10 cycles are exceeded until D is 0. For example: 84 cycles.
If D is 0 before 10 cycles, the loop does not stop until that 10 cycles
are reached.
I read about the logical operators and found the following:
The Swift logical operators && and || are left-associative, meaning
that compound expressions with multiple logical operators evaluate the
leftmost subexpression first.
What solution do you recommend?
You just need to break loop
while S < 10 {
S += 1
let D = Int.random(in: 0...24)
if D == 0 {
print("D = 0 in a cycle \(S)/10")
break
}
}

F# Function where x is divisible by 2 or 3 but not 5

I have a function that determines whether a value is divisible by 2 or 3, but **NOT** 5:
let ttnf x =
if (x % 2 = 0) || (x % 3 = 0) && not(x % 5 = 0) then true
else
false
I'm getting a weird response from Visual Studio 2015 in the interactive panel.
I execute the above code in the F# interactive panel then enter say...
ttnf 15
Hit enter, nothing...
hit alt + enter then it returns it on the second time.
Any idea why it isn't returning true/false from entering:
ttnf 15
The first time?
Thanks.
#ildjarn commented about the error in your code, but about F# interactive's behavior: when you type code directly into fsi, you need to terminate each declaration with ;; to tell fsi to interpret it, otherwise it will just wait for you to continue your input (as you experienced). So:
> let ttnf x =
if (x % 2 = 0 || x % 3 = 0) && not(x % 5 = 0) then true
else
false;;
val ttnf : x:int -> bool
> ttnf 15;;
val it : bool = false
>

String concatenation?

I am trying to understand string concatenation.
Why doesn't the fourth line give the same result as the second one?
counter = 0
"#{counter+1}. test" gives "1. test"
counter = 0
"#{++counter}. test" gives "0. test"
++ just looks like the increment operator. It's actually two unary + operators, so it's just the same as plain old counter
There is no ++ operator in Ruby. What ++counter says is "give me the positive result of the positive result of 0" which is 0.
++ is not an operator in Ruby. If you want to use a pre-increment operator then use:
counter += 1
Because, ++ is not an operator for Ruby like C or Java.
In Ruby, ++x or --x will do nothing! In fact, they behave as multiple unary prefix operators: -x == ---x == -----x == ...... or +x == +++x == +++++x == ......
To increment a number, simply write x += 1.
To decrement a number, simply write x -= 1.
Proof :
x = 1
+x == ++++++x # => true
-x == -----x # => true
x # => 1 # value of x doesn't change.
In C
++counter //Pre Increment
counter++// Post Incremet
But In Ruby ++ has no existence ,
So if you want to increment a variable then you have to simply write
counter = counter + 1
In your case you have to write just
"#{counter = counter + 1}. test" gives "1. test"
And will increment the value counter by 1

Bound checks for array and string slices

I can't seem to get my head around the rules that govern these two cases:
1. The end index may be one less than the start index, producing an empty array/string.
2. It's apparently legal to position the start index just behind the last element, if the end index is one less, as before.
[|0..2|].[3..2];; // [||]
"bar".[3..2];; // ""
A naive implementation of bound checks with consideration of case 1 wouldn't allow case 2:
let trySlice i j (a : string) =
let lastIdx = a.Length - 1
if i < 0 || i > lastIdx || j < i - 1 || j > lastIdx then None
else Some a.[i..j]
trySlice 3 2 "bar" // None
What's the rationale behind this behavior? How to proceed?
Edit
This is what I have now thanks to Tarmil's input
let trySlice i j (a : string) =
if i >= 0 && j >= i - 1 && j < a.Length then Some a.[i..j]
else None
which should be equivalent to
let trySlice' i j (s : string) =
try s.Substring(i, j - i + 1) |> Some
with _ -> None
I suppose the rationale is that a.[i..j] is a sequence of length (j - i + 1), so in a way it makes sense to allow i = j + 1 as a way to extract an empty sequence.
As for "how to proceed", if you want your trySlice to accept all cases that the built-in slicing accepts, then just remove the i > lastIdx clause. When i = lastIdx + 1, the only way for the other conditions to pass is if j = lastIdx, and when i > lastIdx + 1, there is no way for j to pass both its constraints.
As a side-note, the way you write:
if (failCondition || failCondition || ...) then None else Some x
feels counter-intuitive to me for some reason, I would have written it as:
if (successCondition && successCondition && ...) then Some x else None

Resources