How to crash on internal bug and force totality - ffi

I'm ffi-ing to C and the function I call returns an int to mean gt, eq or lt. I want to crash on anything other than 1, 0 or -1 cos that should never happen. And I'd like Idris to consider 0, 1 and -1 to be exhaustive matches. I tried
prim__compare : Scalar -> Scalar -> Int
Ord Scalar where
compare x y = case prim__compare x y of
-1 => LT
0 => EQ
1 => GT
_ => idris_crash ""
but I get
Error: compare is not covering.
Calls non covering function Builtin.idris_crash

Since the crash can only be due to internal errors, it's reasonable to use assert_total
Ord Scalar where
compare x y = case prim__compare x y of
-1 => LT
0 => EQ
1 => GT
_ => (assert_total idris_crash) ""

Related

Taking two elements from an array and adding them, then adding them back into the array

Im trying to create a calculator in f# using two arrays, one which stores the numbers and the other to store the operator symbols. I need the symbols array to pattern match the symbol and depending on the operator take the first two elements from the array and do the operation and add the new number into the head of the 2nd array.
open System
[<EntryPoint>]
let main argv =
printfn "%A" argv
let Add x y = x + y
let Sub x y = x - y
let Div x y = x * y
let Mul x y = x / y
printfn "1 > Calculator \n2 > Load from txt file"
let chosenIn = Console.ReadLine();
//This is where I need to do the operation and after call the sum function
//again until there's only one element left in the number array
let rec sum num (numArray : int[]) sym (symArray : string[]) () =
let rec calc () =
printfn "Enter Sum"
let input = Console.ReadLine()
let intInput = input.Split()
let numArray = [|for num in intInput do
let v , vp = System.Int32.TryParse(num)
if v then yield vp|]
let symbolArray = [|for symbol in intInput do
match symbol with
| "+" -> yield symbol
| "-" -> yield symbol
| "/" -> yield symbol
| "*" -> yield symbol
| _ -> ignore 0|]
calc()
match chosenIn with
| "1" -> calc()
| "2" -> printfn "File"
| _ -> printfn "Invalid"
0 // return an integer exit code
In response to the answer #Liam Donnelly posted to his own question: I'll leave aside questions like "is that really the best way of solving the problem", just commenting on how to better write the code you currently have.
Array slicing and concatenating the way you are doing it here can be written as
let newNumArray = Array.append [| result |] numArray.[2..]
However, I would use F# lists rather than arrays for your task. With lists, you can do pattern matching to access the first 2 elements. Pattern matching, in my view, wins over direct indexing because you can directly encode corner cases, and get the F# compiler to remind you of corner cases. Do the same thing for the operators. You can do both operators and operands in the same go. It will then look something like this:
let rec sum2 (numArray : int list) (symArray : string list) =
let newNum, newSym =
match numArray with
| [] -> failwith "No numbers left to process"
| arg1 :: [] -> failwith "There's only one number left to process"
| arg1 :: arg2 :: args ->
match symArray with
| op1 :: ops ->
let result =
match op1 with
| "+" -> Add arg1 arg2
| "-" -> Sub arg1 arg2
| "*" -> Mul arg1 arg2
| _ -> failwithf "Operator not recognized: '%s'" op1
// Return the result, concatenate the non-processed
// numbers. Return the non-processed operators
result :: args, ops
| _ -> failwith "I've run out of operators?"
<snip>
Also, returning a "default result" if you don't recognize the operators is something that I consider very risky (even though the practice is rather widespread)
If you use lists (F# lists, that is), you can directly access the elements at indices 1.. via head: let newSymArray = symArray.Head or use List.head
Take a step back each time you see yourself writing a for loop in F#. They are cumbersome to write and error-prone. Most of the typical use-cases for loops are covered by F# library functions, so have a good read through those. Your printing loop can be written way shorter by doing:
newNumArray
|> Seq.iter (printfn "%i")
I've managed to make the function which performs the task I needed for it to do and I'm sure there's a much more code efficient way of taking the first elements of the arrays by using Array.copy with filters but I'm new to f# so I just it the way I was confident with
let rec sum (numArray : int[]) (symArray : string[]) =
let result = match symArray.[0] with
| "+" -> Add numArray.[0] numArray.[1]
| "-" -> Sub numArray.[0] numArray.[1]
| "*" -> Mul numArray.[0] numArray.[1]
| _ -> 0
let newNumArray = [|
for i = 0 to numArray.Length - 1 do
if i = 0 then yield result
if i > 1 then yield numArray.[i]|]
let newSymArray = [|
for i = 0 to symArray.Length - 1 do
if i > 0 then yield symArray.[i]|]
if newNumArray.Length > 1 then
sum newNumArray newSymArray
else
for i = 0 to newNumArray.Length - 1 do
printfn "%i" (newNumArray.[i])

Algorithm to get group index of item in chunked array

So I have an arbitrary array of items:
array = [0,1,2,3,4];
and when it's been chunked it looks like:
array.chunk(2) => [[0,1],[2,3],[4]];
array.chunk(3) => [[0,1,2],[3,4]];
What i'd like is an algorithm to get the index of the group that the index is in, based on the group size.
For instance, running the algorithm on each element in array would yield:
array.chunkIndex( chunkSize = 2, index = n )
0 => 0
1 => 0
2 => 1
3 => 1
4 => 2
array.chunkIndex( chunkSize = 3, index = n )
0 => 0
1 => 0
2 => 0
3 => 1
4 => 1
So running the algorithm on the index with chunkSize = 1 would always yield the original index.
How would I go about doing this? To be clear, I don't want to chunk the array, just determine which group it would be in, without looping and without built-in functions, if possible.
Also in psuedo-code:
chunkIndex = index / chunkSize
It's simple integer division which means the only case you have to be careful of is languages that will return a float/decimal/real. For those cases, you will need a floor function to find just the integer part of the result. You may wish to handle negative values also.
floor(index / chunkSize) should work!

Is it possible to use a conditional statement in an Idiom Bracket in Idris?

An expression like the following is perfectly valid in Idris:
let x = Just 5 in let y = Just 6 in [|x / y|]
Could someone write an expression like the following?
let x = Just 5 in let y = Just 6 in [| if x == 0 then 0 else y|]
I can't seem to get it to compile.
I was able to get this working by taking care of two problems:
if _ then _ else _ doesn't seem to propagate the idiom bracket to its subexpressions
The default definition of if _ then _ else _ is (of course) lazy in its two branches, and Lazy' LazyEval doesn't seem to lift instances.
Once these two were worked around, I was able to get it working in an idiom bracket. Note however that this wouldn't work for an applicative where taking both branches has an observable effect.
strictIf : Bool -> a -> a -> a
strictIf True t e = t
strictIf False t e = e
syntax "if" [b] "then" [t] "else" [e] = strictIf b t e
test : Maybe Float
test = let x = Just 5
y = Just 6
in [| if [| x == pure 0 |] then [|0|] else y |]

Reflexivity on the gt relation in Coq

I want to prove that for any natural number n+1 is greater than 0.
Defining my own greater than function this works fine:
Fixpoint my_gt (n : nat) (m : nat) : bool
:= match n with
| O => false
| S n' => match m with
| O => true
| S m' => my_gt n' m'
end
end.
Lemma GT1: forall n, my_gt (S n) O = true. reflexivity. Qed.
But when I use the default ">"-relation Coq refuses with the message "Tactic failure: The relation gt is not a declared reflexive relation. Maybe you need to require the Setoid library". Because I do require the Setoid library I don't understand why Coq does not seem to find the gt definition?
Require Export Coq.Setoids.Setoid.
Lemma GT2: forall n, S n > O. reflexivity.
If you take a look at Coq's gt definition, you will this that it is just a notation over lt, which is a notation over le:
gt = fun n m : nat => m < n
: nat -> nat -> Prop
lt = fun n m : nat => S n <= m
: nat -> nat -> Prop
Inductive le (n : nat) : nat -> Prop :=
le_n : n <= n | le_S : forall m : nat, n <= m -> n <= S m
Now as you can see, it is not declared as a function, but as an inductive predicate, so you cannot simply "compute" to get the solution. To prove such a goal, you will have to use tactics such as constructor and induction to prove your goal.
Note that your relation is in bool whereas Coq's is in Prop (the general way to compare two elements of some type might no be decidable). For the particular case of natural numbers, you can find leb somewhere in the Arith module, which behaves as you except:
Require Import Arith.
Print leb.
Lemma GT2: forall n, leb O (S n) = true.
reflexivity.
Qed.
Best,
V.

C variable assignment and R equivalent

Hi I am trying to understand the following variable assignment in C, and try re-write it in R. I use R often but have only really glanced at C.
int age,int b_AF,int b_ra,int b_renal,int b_treatedhyp,int b_type2,double bmi,int ethrisk,int fh_cvd,double rati,double sbp,int smoke_cat,int surv,double town
)
{
double survivor[3] = {
0,
0.996994316577911,
0.993941843509674
};
a = /*pre assigned*/
double score = 100.0 * (1 - pow(survivor[surv], exp(a)) );
return(score);
}
how does survivor[surv] work in this context? An explanation would be helpful, and any input on how to do the assignment in R would be a bonus.
Thanks very much!
This is an aggregate initializer:
double survivor[3] = {
0,
0.996994316577911,
0.993941843509674
};
and is equivalent to:
double survivor[3];
survivor[0] = 0;
survivor[1] = 0.996994316577911;
survivor[2] = 0.993941843509674;
and survivor[surv] is the value stored at index of the survivor array. Array indexes run from 0 to N - 1 so if surv was 1 then survivor[surv] has value of 0.996994316577911.
Note, the function as currently written does not check that surv is a valid index for the array survivor (i.e. surv > -1 and surv < 3) and runs the risk of undefined behaviour.
Given the Answer of #hmjd then, the R equivalent would be
survivor <- c(0, 0.996994316577911, 0.993941843509674)
or if survivor already exists and you wish to assign into the first 3 elements:
survivor[1:3] <- c(0, 0.996994316577911, 0.993941843509674)
(Note R's indices are 1-based unlike C's 0-based ones.)
As for the extraction, the general idea is the same as with C, but the details matter:
R> survivor[0] ## 0 index returns an empty vector
numeric(0)
R> survivor[-1] ## negative index **drops** that element
[1] 0.9969943 0.9939418
R> survivor[10] ## positive outside length of vector returns NA
[1] NA
R> surv <- 2
R> survivor[surv] ## same holds for whatever surv contains
[1] 0.9969943

Resources