How do I do if-statements like this in Erlang? I have searched but found nothing...
if((1 == 1 || 2 == 2 || 3 == 3) && (4 == 4 || 5 == 5 )) {}
Highly recommended position for Erlang in general (free to read online) and answering your problem here: http://learnyousomeerlang.com/syntax-in-functions#what-the-if
In short, alternative in if (||):
if 1 =:= 2; 1 =:= 1 ->
works
end,
Conjunction in if (&&):
if 1 =:= 2, 1 =:= 1 ->
notWorks
end,
See also: http://learnyousomeerlang.com/syntax-in-functions
Related
I want to write the function residue l n which calculates the residue of n by l by making an iterative calculation starting with n and using the items in the list in order. The calculation is as follows:
-initially the residue is the value of n
-each element e of l (taken in the order of the list) changes the residue in the following way:
if e and the residue are of the same parity (both even or both odd) then the new residue is the sum of r and e, otherwise it is the difference between r and e (r-e).
-the last residue is the result of the game.
Example: residu [1;3] 7 returns 5 as a result of the following calculations:
7 + 1 (same parity +) = 8
8 - 3 (parité différente -) = 5
This is my code but it doesn't seem to be working:
let rec residue l n =
if l = [] then 0 else
if (((List.hd l) mod 2 <> 0) && (n mod 2 <> 0 )) || (((List.hd l) mod 2 == 0) && (n mod 2 == 0 ))
then
(List.hd l) + residue (List.tl l) ((List.hd l)+ n) else
n - (List.hd l) - residue (List.tl l) (n - (List.hd l));;
residu [1;3] 7;;
- : int = 6 (The correct result should be 5)
Thank you for your help.
Here is my stab at it.
let rec residue l n =
let parity a b =
if ((a mod 2 <> 0) && (b mod 2 <> 0)) ||
((a mod 2 == 0) && (b mod 2 == 0)) then true else false in
match l, n with
| [], n -> n
| (x::xs), n -> if parity x n then residue xs (n+x) else residue xs (n-x)
Hope it helps for figuring out the problem.
I want to prove a property parameterized over a finite number of cases. I would like to divide the problem to one instance per case and solve each instance separately. Here is an example to clear up things:
module Minimal
open FStar.List
open FStar.Tactics
open FStar.Reflection.Data
unfold let lst = [0;1]
unfold let prop i =
match i with
| 0 -> i == 0
| 1 -> i == 1
| _ -> False
val propHolds (i:int) : Lemma (requires (List.mem i lst)) (ensures (prop i))
In this case the cases are defined by the list lst.
I can easily prove propHolds:
let propHolds i =
assert_by_tactic (prop 0) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized"; trivial ());
assert_by_tactic (prop 1) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized"; trivial ())
but I obviously don't want to write a separate assert_by_tactic for each case (not when there may be thousands..).
I somehow want to generate the proof above automatically for all elements in lst.
I tried various things, here is one of them:
assert_by_tactic (let rec props i =
if i = 0 then prop 0
else (prop i) /\ (props (i-1))
in
props 1) (fun () -> norm[delta;primops;iota;zeta]; dump "normalized")
Unfortunately, this doesn't quite achieve what I would like, the assert_by_tactic fails (and is not reduced in the way I would expect). I think I am missing something obvious about normalization, but what is the canonical way to do this in F*? Bonus points if the solution points to the "case"/assertion that failed if there exists one.
F*'s type system only ensures weak normalization of terms. Well-typed open terms can diverge, e.g., when reduced in an inconsistent context. To guard against this, the F* normalizer employs various heuristics and, by default, conservatively refuses to reduce recursive calls in the bodies of unreduced matches. This is what prevents List.mem from reducing fully to a cascade of unreduced if/then/else's (if/then/else is just sugar for a match on a Boolean).
List.memP, a related function from F*'s standard library is more reduction friendly in this case, since it does not block on unreduced matches internally. Note, List.memP need not always be more reduction friendly than List.mem---the latter is Boolean, so it can in some cases compute more (e.g., List.mem 3 [1;2;3] will reduce just fine to true);
Try this program:
module Minimal
open FStar.Tactics
let lst = [0;1;2;3;4;5;6;7;8;9;10]
let prop i =
match i with
| 0 -> i == 0
| 1 -> i == 1
| 2 -> i == 2
| 3 -> i == 3
| 4 -> i == 4
| 5 -> i == 5
| 6 -> i == 6
| 7 -> i == 7
| 8 -> i == 8
| 9 -> i == 9
| 10 -> i == 10
| _ -> False
let propHolds (i:int) =
assert (List.memP i lst ==> prop i)
by (dump "A";
norm [delta_only [`%List.memP; `%lst]; iota; zeta; simplify];
dump "B")
At dump B, you'll see the hypothesis reduced to a nested disjunction. Z3 can prove the goal easily from there.
Here's another way to do it, this time without tactics.
let trigger_norm (a:Type)
: Lemma
(requires a)
(ensures (Pervasives.norm [delta_only [`%List.memP; `%lst]; iota; zeta; simplify] a))
= ()
let propHolds (i:int)
: Lemma
(requires List.memP i lst)
(ensures prop i)
= trigger_norm (List.memP i lst)
Now, in response to jebus' comment below, you can go further and prove the postcondition using a tactic, although, the SMT solver is really pretty fast at doing this … so I wouldn't use a tactic for this unless you had some specific strong reason for doing so.
Here's one more solution:
module SO
open FStar.Tactics
let lst = [0;1;2;3;4;5;6;7;8;9;10]
let pred i =
match i with
| 0 -> i == 0
| 1 -> i == 1
| 2 -> i == 2
| 3 -> i == 3
| 4 -> i == 4
| 5 -> i == 5
| 6 -> i == 6
| 7 -> i == 7
| 8 -> i == 8
| 9 -> i == 9
| 10 -> i == 10
| _ -> False
let case_impl (a b c:Type)
: Lemma
(requires (a ==> c) /\ (b ==> c))
(ensures (a \/ b) ==> c)
= ()
let solve_pred_impl () : Tac unit =
let eq = implies_intro () in
rewrite eq;
norm [delta_only [`%pred]; iota];
trivial()
let test i =
assert (List.memP i lst ==> pred i)
by (norm [delta_only [`%List.memP; `%lst]; iota; zeta; simplify];
let _ = repeat
(fun () ->
mapply (`case_impl);
split();
solve_pred_impl()) in
solve_pred_impl())
new to Ocaml. I've no clue what is happening here and I've been trying to solve this for maybe 2 hours.
Here is the code:
let hailstorm n =
match n with
| (mod n 2 == 0) -> (n/2)
| (mod n 2 == 1) -> (3*n+1);;
When I try to compile it says:
File "./x.ml", line 3, characters 11-12:Error: Syntax error: ')' expected
File "./x.ml", line 3, characters 6-7:
Error: This '(' might be unmatched
The keyword mod is a binary operator (like lsl, lsr, asr, land, lor, lxor and or) . For instance,
let zero = 2 mod 2
Binary operator can be transformed into standard function by wrapping them around parentheses,
let zero = (mod) 2 2
this is why the parser is expecting a closing parenthesis after (mod .
Then, you pattern matching is wrong because n mod 2 == 0 is an expression, not a pattern (and you should use structural equality = rather than physical equality ==):
let f n = match n mod 2 with
| 0 -> ...
| _ -> ...
or
let f n = match n mod 2 = 0 with
| true -> ...
| false -> ...
which is probably simpler with an if ... then ... else ... .
function name = mycount
here is output example:
(mycount 20) -> error(must standard error)
(mycount `()) -> 0
(mycount `(1 2 3)) - > 6
(mycount `((1 2) ((3)) (4 (5)))) -> 15
function count-numbers takes a list:
define a counter
is it a number?
ERROR
is it a list?
for each element of list:
cond
- is it a number? -> increase the counter
- is it a list? -> apply (count-numbers) to it and add the result to counter
- do nothing
Something like that? We are not going to make your homework :)
This is my code:
import Data.Bits
main = print . sum . takeWhile( < 200000) $ multSum 999
multSum m = 3 : multiples [6..m] where
multiples (p:xs)
| ((p `mod` 3 == 0) || (p `mod` 5 == 0)) = p : multiples([p..m])
| otherwise = p : xs
Error: out of memory (requested 1048576 bytes)
Where am I going wrong?
multSum isn't doing what you think it is. Try debugging it directly:
*Main> take 20 $ multSum 999
[3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]
multSum returns the infinite list [3,6,6,6,6...] for all arguments, thus it never exceeds 200000 and so the sum you request can't be printed.
try
mults35 m = multiples [3..m] .....
............
....| ...... = p : multiples xs
... | otherwise = multiples xs
there will be one more thing for you to add there. Try this, and you'll see.