Mathematica If-then vs. Implies - if-statement

I am new to Mathematica(v8) and am using it to program propositional logic.
I'm wondering what the difference is between the If and the Implies operators. For example,
both If[p,q] and Implies[p,q] return q for p=True (as expected).
But when I try to obtain SatisfiabilityInstances, I get the following:
SatisfiabilityInstances[If[p, q], {p, q}]
(*
{{True, True}}
*)
unless I ask it for more instances:
SatisfiabilityInstances[If[p, q], {p, q}, All]
SatisfiabilityInstances::boolv: "If[p,q] is not Boolean valued at {False,True}.
However:
SatisfiabilityInstances[Implies[p, q], {p, q}, All]
returns the expected out of:
(* {{True, True}, {False, True}, {False, False}} *)
What is causing this difference in the outputs?

It is what it said -- If is not Boolean, i.e. it returns not only true or false. Try If[False,True] and you'll see no result. If[a,b,c,d] can return any b, c and d, not only Boolean, for example If[True,2] returns 2. So, If is for branching (even being functional) while Implies is a normal Boolean function.
P.S. Ah, Implies also can return 2. So the difference is that If[False,True] returns nothing, so SatisfiabilityInstances function can't find true area.
P.P.S. More precisely, if the first argument of If[] is False then it returns it's third argument. When it is absent, it returns nothing.

You may try:
SatisfiabilityInstances[If[p, q, Not[q]], {p, q}, All]

Related

OCaml return value in if statement nested in loop

I am trying to return a value if something occurs when iterating through a list. Is it possible to return a string if X happens when iterating through the list, otherwise return another string if it never happens?
let f elem =
if not String.contains str elem then "false" in
List.iter f alphlist;
"true";
This is not working in my implemented method sadly.
OCaml is a functional language, so you pretty much need to concentrate on the values returned by functions. There are ways to return different values in exceptional cases, but (IMHO) the best way to learn is to start just with ordinary old nested function calls.
List.iter always returns the same value: (), which is known as unit.
For this reason, the expression List.iter f alphlist will also always return () no matter what f does.
There is another kind of list-handling function that works by maintaining a value across all the calls and returning that value at the end. It's called a fold.
So, if you want to compute some value that's a kind of summary of what it saw in all of the string lists in alphlist, you should probably be using a fold, say List.fold_left.
Here is a function any_has_7 that determines whether any one of the specified lists contains the integer 7:
let any_has_7 lists =
let has_7 sofar list =
sofar || List.mem 7 list
in
List.fold_left has_7 false lists
Here's how it looks when you run it:
# any_has_7 [[1;2]; [3;4]];;
- : bool = false
# any_has_7 [[1;2]; [5;7]; [8;9]];;
- : bool = true
In other words, this function does something a lot like what you're asking for. It returns true when one or more of the lists contains a certain value, and false when none of them contains the value.
I hope this helps.

if statement checking multiple conditions in SML

I am new to SML and I have written a program that takes 3 integer numbers (n,z,k) and wants to compare them with a value given in the program, if the statement is correct it will return true, else false. conditions and values should be equal simultaneously, I mean program will return true if all these numbers are equal to the value given in the program, so my if statement should check 3conditions at the same time.
my problem is that I don't know how I can write all these 3conditions in one if clause, because SML don't recognize for example & or ^ as and!
for example i want to check whether if(n==8 && k==5 && z==9). what should I use instead of &
here is the code:
fun EvalR (n: int , k: int , z:int) =
if (n=8 ???) then true
else false;
Since Ashkan Parsa referred to the CS317 SML Style Guide, I thought I would point out what you might derive from it.
Let function names start with a lower case, e.g. evalR.
Don't write if ... then true else false; simply write ....
Some disagree; type annotations certainly are helpful, but so is type inference.
As nazila says, the and operator in Standard ML is called andalso.
So,
fun evalR (n, k, z) =
n = 42 andalso k = 43 andalso z = 0
It might seem comfusing that the function body contains =s at the same time as the function being defined with a = to separate the function arguments from the function body. Just think of the latter =s as value operators and the first = as a part of declaring things (like types, values, functions, etc.)
I found it. we can use andalso in SML.

Acceptable parameter combinations for flatten method

Question
Would like to understand the cause of the error and meaning of the error messages. Initially thought it was because of mixing String and Character, but mixing String and Integer was possible.
Problem
Expected below would produce List(tako, saba, ika, h, a, m, a, c, h, i) like List(tako, saba, ika, 1, 2, 3) mixing string and integer. However it caused errors.
println(
List(
List("tako", "saba", "ika"),
"hamachi"
).flatten)
^^^^^^^^
No implicit view available from java.io.Serializable => scala.collection.GenTraversableOnce[B].
not enough arguments for method flatten: (implicit asTraversable: java.io.Serializable => scala.collection.GenTraversableOnce[B])List[B]. Unspecified value parameter asTraversable.
Below worked.
println(
List(
"hamachi"
).flatten)
----
List(h, a, m, a, c, h, i)
println(
List(
List("tako", "saba", "ika")
).flatten)
----
List(tako, saba, ika)
println(
List(
List("tako", "saba", "ika"),
List(1,2,3)
).flatten)
----
List(tako, saba, ika, 1, 2, 3)
The signature of flatten is
def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B]
You can check out more about this in the source. So, about the error you get: when you make List(List("tako", "saba", "ika"), "hamachi"), scala has to infer the generic type of the List you are making. The way it does this is that it takes the least common ancestor of all the types in the list. In this case, it so happens that the closest class/trait that List("tako", "saba", "aka"): List[String] and "hamachi: String" share is java.io.Serializable.
Now, scala has to look for an implicit parameter asTraversable: A => GenTraversableOnce[B], but it doesn't find one. Since it already figured out that A = java.io.Serializable, it gives you as helpful an error message as it can muster: it didn't find any implicit of type java.io.Serializable => scala.collection.GenTraversableOnce[B] to give to asTraversable.
Now, what about the other calls? Where are they getting their implicits? Mostly from the Predef I think. This IMO is one of Scala's weaknesses - noticing, tracing, and debugging implicits. They are absolutely lovely until you try something that requires some complex implicit no one thought of defining. Oh well, no such thing as a free lunch.

Check whether number is Fibonacci or not in Standard ML

I am trying to write a code which checks if number is Fibonacci or not in ML. I am a beginner. Help me find out what is the problem with my code.
fun isfib(n :int): bool=
let
val a1=1;
val a2=1;
val temp=0;
in
while a2<n do (
a1=temp
a2=a1
a2=temp+a2
)
if a2=n then true
else false
end;
a1=temp
a2=a1
a2=temp+a2
= is the equality operator in SML, not an assignment operator. So the above code is just equivalent to this:
false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)
So you have three side-effect-free expressions in your loop, so it just won't do anything.
It's clear that you actually want to change the values of those variables, but you can't do that. Variables in SML are immutable - you can't change them after they're set. So even having a while condition like a2 < n doesn't make sense because a2 and n can't change, so the condition is either always true or always false. If you want to use a while loop like this, you should look into the ref type, which allows you to create mutable values that you can use to simulate mutable variables.
That said using while loops and mutation is not idiomatic SML. There's a reason why variables in SML aren't mutable: the language designers want to encourage you to not rely on mutation (and thus also not on while loops). The idiomatic way to loop in SML is to either use higher order functions (like map, filter, foldl etc.) or recursion. For your problem a recursive function would make the most sense.

Prolog evaluating how two lists compare to eachother

Note: Near complete beginner to logic programming
I need to compare two lists of integers and figure out if one is greater, greater-equal, or they are both equal.
For example:
compare_list([1, 2, 3], [1, 2, 4], C).
C = greater,
C = greater-equal.
compare_list([1, 2, 3], [1, 2, 4], C).
C = equal.
So far the closest I have been able to get has been...
compare_list([],[],_).
compare_list([X|XS],[Y|YS],C):-
X > Y,
compare_list(XS,YS,C),
C = 'greater'.
compare_list([X|XS],[Y|YS],C):-
X >= Y,
compare_list(XS,YS,C),
C = 'greater-equal'.
compare_list([X|XS],[Y|YS],C):-
X == Y,
compare_list(XS,YS,C),
C = 'equal'.
Now that obviously doesn't work as needed because it is always comparing the first element of each list and seeing if the C value holds for all of the values. However I cannot think of a way to make it work as intended.
Edit:
The earlier a value is in a list, the more important it is. So [2,2] > [1,3] > [1,2]
Tips would be appreciated. Thanks.
Edit:
Solved by waiting until the end to assign C to anything.
In your solution you use (>)/2, (>=)/2 and (==)/2. The first two will evaluate their arguments as arithmetic expressions prior to a comparison. And (==)/2 will compare due to term order. You will have to decide for one of them or another term order. But you cannot mix them.
The second remark is that you would also need something as 'less' as a result.
If two elements already compare as (<)/2, there is no need for further comparison.
Also, equality can only be stated in the fact, but not before.
Consider to use the built-in predicate `compare/3`:
?- compare(R, [1, 2, 3], [1, 2, 4]).
R = (<).
?- compare(R, [1, 2, 3], [1, 2, 3]).
R = (=).
Should you write your own comparison predicate, better use the very same argument order and the same terms as result. That is, <, =, and >. It does not make a lot of sense, to expect >= to be a result. After all, two identical lists would then have three different solutions =<, =, >=.
From your description, it is not clear to me what you expect, if both lists are of different length.
According to your definition of "greater" there is no need to continue the recursion after you find that X>Y. If you reach the end of the recursion (as chac said) you'll know that the two lists are equal.
To get "greater-equal" you should instead check that X is not less than Y. You may think of this as "if X is less than Y than fail". Take a look at negation as failure.
You can stop comparing at the first ineguagliance. If you reach the end of (both) lists, that means lists are equals.
The following code will check whether two list are equal or not
is_equal([],[]).
is_equal([H1|T1],[H2|T2]):- H1=:=H2,is_equal(T1,T2).