Infinite loop scala code - scala

object Prop {
def simplify(prop : Prop) : Prop = {
prop match {
case Not(Or(a,b)) => simplify(And(Not(a),Not(b)))
case Not(And(a,b)) => simplify(Or(Not(a),Not(b)))
case Not(Not(a)) => simplify(a)
case _ => {
if (simplify(prop) == prop) prop
else prop
}
}
}
}
I'm pretty sure I've an infinite loop caused by my 'default' case. I'm using recursion in all cases. Which is meant to be, but, only if the Prop can be simplified. As soon as the Prop can't be simplified, it should return the whole thing.
I don't see how I can test for any further simplification. (I'm not allowed to use other libraries, as suggested in freenodes #scala channel).
Can someone explain whether it IS the 'case _' causing the loop, and how to solve it? How can I test for possible simplification without making a loop?
Thanks in advance!

It is pretty obvious what happens and you are right with the default case. If your input prop does not match any of the cases you are invoking:
simplify(prop)
with the same argument. Because previously it caused recursive call to simplify() and you are calling your function with the same input, it enters simplify() again. So this is not an infinite loop but rather never terminated recursive call:
...simplify(simplify(simplify(simplify(simplify(simplify(simplify(prop)))))))
However the fix (based on your code) is simple:
if (simplify(prop) == prop) prop
else prop
just replace it with...
case _ => prop
Both branches return the same value. This is actually correct if you think about if for a while. You have a set of optimizations. If none of them matched your expressions it means it can no longer be simplified. Hence you are returning it as-is.
BTW looks like you are doing boolean expressions simplification using case classes. You might by interested in my article where I do the same but with arithmetic expressions.

The problem is that you're trying to do two things in one step that need to happen in sequence—applying De Morgan's law (and removing double negation) and recursively simplifying any children. This is why just dropping a case And(a, b) => And(simplify(a), simplify(b)) into your match won't work.
Try the following:
val deMorganAndDoubleNegation: Prop => Prop = {
case Not(Or(a, b)) => And(Not(a), Not(b))
case Not(And(a, b)) => Or(Not(a), Not(b))
case Not(Not(a)) => a
case a => a
}
val simplify: Prop => Prop = deMorganAndDoubleNegation andThen {
case And(a, b) => And(simplify(a), simplify(b))
case Or(a, b) => Or(simplify(a), simplify(b))
case Not(a) => Not(simplify(a))
case a => a
}

Yes, default case is causing the loop.
if (simplify(prop) == prop) prop is problematic line.
You don't need to test if it can be simplified further because when you are in the default case all possible simplifications are tried.

Related

How do you tell Dafny to use a lemma when validating termination

Dafny makes use of a decreases clause to verify that a recursive function terminates. When verification fails can Dafny be given a hint, in this case in the form of a lemma. How to I tell Dafny to use the lemma when checking that the decreases clause actually decreases?
datatype List<T> = Nil | Cons(head:T, tail:List<T>)
datatype Twee = Node(value : int, left : Twee, right : Twee) | Leaf
function rotateLeft(t:Twee) :Twee
{
match t
case Leaf => t
case Node(v,Node(vl,ll,rl),r) => Node(vl,ll,Node(v,rl,r))
case Node(v,Leaf,r) => Node(v,Leaf,r)
}
function Leftheight(t:Twee) :(h:nat) decreases t
{
match t
case Leaf => 0
case Node(_,l,_) => 1+Leftheight(l)
}
lemma {:induction ll, rl, r} decreasesHint(v:int, vl:int, ll:Twee,rl:Twee,r:Twee)
ensures Leftheight(Node(v,Node(vl,ll,rl),r)) ==
1+ Leftheight(Node(vl,ll, Node(v,rl,r))) {}
function rotateAllLeft(t:Twee) :Twee
decreases t, Leftheight(t)
{
match t
case Leaf => Leaf
case Node(v,Leaf,r) => Node(v,Leaf,rotateAllLeft(r)) //decrases t
case Node(v,Node(vl,ll,rl),r) => //{ decreasesHint(v,vl,ll,rl,r);}
rotateAllLeft(rotateLeft(Node(v,Node(vl,ll,rl),r)))
}
Sorry for such a long example but this is the first time I have wanted to give hints for checking termination. The error failure to decrease termination measure occurs on the last line rotateAllLeft(rotateLeft(Node(v,Node(vl,ll,rl),r).
You can call a lemma from inside an expression. Just use a semicolon to separate the lemma call from the rest of the expression.
case Node(v,Node(vl,ll,rl),r) =>
decreasesHint(v,vl,ll,rl,r);
rotateAllLeft(rotateLeft(Node(v,Node(vl,ll,rl),r)))
Note that this does not completely solve your termination problems, because your decreases annotation is t, Leftheight(t), which means that recursive calls must either make t smaller, or leave t the same and make the left height smaller. But this recursive call does not leave t the same. I tried changing your annotation to just decreases Leftheight(t), which accepted this case, but gave an error on the previous case. Maybe you can find a way around that.

Yielding with For-loop and pass to match-case Expression

I was experimenting with the following code;
(for (f <- (new File(".")).listFiles() if !f.isDirectory) yield f) match {
case x:File => println(x.getAbsoluteFile)
case _ => println(_)
}
Obviously I am wrong somehow, as I am getting the following Error
scrutinee is incompatible with pattern type;
found : java.io.File
required: Array[java.io.File]
case x:File => println(x.getAbsoluteFile)
^
What I was trying to do is pretty obvious; I tried to get each yielded value from the for-loop and pass it to a match-case "filter". I am not interesting in writing a better File tree filter rather than knowing the reason of the Error that I am getting and if it is possible to fix it (or rewrite somehow else).
Cheers!
Just a few symbols away:
for (f <- (new File(".")).listFiles() if !f.isDirectory) f match {
case x:File => println(x.getAbsoluteFile)
case _ => println(_)
}
The diff is
yield f)
{ f
In your case you're first processing (listing|filtering|yielding one-by-one) whole collection and only then match whole result.

Use same variable multiple times within one pattern

I'd like to be able to use a single variable multiple times within one pattern, so that it will only match if the same value is present in all places, such as
list match {
case x :: x :: xs => // recurse
}
which would match List(1,1,2) but would not match List(1,2,1). But this does not compile with error: x is already defined as value x.
In researching this question, I found out that I can also include a guard in the case clause, so I can do
list match {
case x1 :: x2 :: xs if x1==x2 => // recurse
}
which seems to work the same way (it does, right?). This is good, but it wouldn't look as clean if I wanted the same value in many places, like
list match {
case x1::x2::x3::x4::xs if x1==x2 && x2==x3 && x3==x4 => // recurse
}
Is there any more elegant way I can do this?
A few notes: Yes, I am just learning scala, if that wasn't clear, so I'm not sure this is something I'd ever really want to do, but I'm just interested in what's possible. In that regard, I'm not really looking for a completely different solution, like takeWhile or filter or something, but more so am specifically interested in pattern matching.
Scala doesn't provide quite that much flexibility with its matches (which may be a good thing, as one has to be aware of errors arising from unintentional variable re-use).
If you have a large number of identical items, you might want to consider a nested match (but note that you won't fail out of the inner match to be completed later down the outer match, so you have to handle everything locally):
list match {
case x :: rest => rest match {
case `x` :: `x` :: `x` :: xs => println("Four of the same")
case _ => println("Well, nonempty at least")
}
case _ => println("Boring, there's nothing here!")
}
Note the backticks which mean "we've already got this variable, check against it, don't set it!".
Alternatively, if you have specialized functionality that you use repeatedly, you can create a custom matcher:
object FourOf {
def unapplySeq(xs: List[Int]): Option[(Int, List[Int])] = xs match {
case x :: y :: z :: a :: rest if x==y && y==z && z==a => Some((x,rest))
case _ => None
}
}
and then use it whenever you need that complicated pattern:
list match {
case FourOf(x,rest) => println("four of the same")
case x :: more => println("Nonempty")
case _ => println("Yawn")
}
Neither of these are quite as tidy and flexible as what you were apparently hoping for, but then again, I'm not sure flipping between assigning and testing the same variable in a match statement is a good way to write clear code anyway.
For many repeats you might use stable identifiers to do a comparison (instead of catching a value):
val x = list.head
list match {
case `x`::`x`::`x`::`x`::xs => ....
}
But note that this won't work on empty list (you just cannot get head of it).
I think Rex's answer rocks. I am a fan of unapplySeq. But here's a not-so-clever-and-maybe-wasteful alternative, if your main bother is just with the sequence of =='s in each guard.
So in the TMTOWTDI spirit:
def same[A](xs: A*) = xs forall (xs.head==)
// Then in your pattern match,
list match {
// case x1::x2::x3::x4::xs if x1==x2 && x2==x3 && x3==x4 => // recurse
case x1::x2::x3::x4::xs if same(x1,x2,x3,x4) => // recurse
}
I like Om's answer as well, so here's an adaptation:
list.headOption map (x => list match {
case `x`::`x`::`x`::`x`::xs => //...;
case _ => // ...
}) getOrElse {
// do what you'd have done for an empty list...
}

Processing Scala Option[T]

I have a Scala Option[T]. If the value is Some(x) I want to process it with a a process that does not return a value (Unit), but if it is None, I want to print an error.
I can use the following code to do this, but I understand that the more idiomatic way is to treat the Option[T] as a sequence and use map, foreach, etc. How do I do this?
opt match {
case Some(x) => // process x with no return value, e.g. write x to a file
case None => // print error message
}
I think explicit pattern matching suits your use case best.
Scala's Option is, sadly, missing a method to do exactly this. I add one:
class OptionWrapper[A](o: Option[A]) {
def fold[Z](default: => Z)(action: A => Z) = o.map(action).getOrElse(default)
}
implicit def option_has_utility[A](o: Option[A]) = new OptionWrapper(o)
which has the slightly nicer (in my view) usage
op.fold{ println("Empty!") }{ x => doStuffWith(x) }
You can see from how it's defined that map/getOrElse can be used instead of pattern matching.
Alternatively, Either already has a fold method. So you can
op.toRight(()).fold{ _ => println("Empty!") }{ x => doStuffWith(x) }
but this is a little clumsy given that you have to provide the left value (here (), i.e. Unit) and then define a function on that, rather than just stating what you want to happen on None.
The pattern match isn't bad either, especially for longer blocks of code. For short ones, the overhead of the match starts getting in the way of the point. For example:
op.fold{ printError }{ saveUserInput }
has a lot less syntactic overhead than
op match {
case Some(x) => saveUserInput(x)
case None => printError
}
and therefore, once you expect it, is a lot easier to comprehend.
I'd recommend to simply and safely use opt.get which itself throws a NoSuchElementException exception if opt is None. Or if you want to throw your own exception, you can do this:
val x = opt.getOrElse(throw new Exception("Your error message"))
// x is of type T
as #missingfaktor says, you are in the exact scenario where pattern matching is giving the most readable results.
If Option has a value you want to do something, if not you want to do something else.
While there are various ways to use map and other functional constructs on Option types, they are generally useful when:
you want to use the Some case and ignore the None case e.g. in your case
opt.map(writeToFile(_)) //(...if None just do nothing)
or you want to chain the operations on more than one option and give a result only when all of them are Some. For instance, one way of doing this is:
val concatThreeOptions =
for {
n1 <- opt1
n2 <- opt2
n3 <- opt3
} yield n1 + n2 + n3 // this will be None if any of the three is None
// we will either write them all to a file or none of them
but none of these seem to be your case
Pattern matching is the best choice here.
However, if you want to treat Option as a sequence and to map over it, you can do it, because Unit is a value:
opt map { v =>
println(v) // process v (result type is Unit)
} getOrElse {
println("error")
}
By the way, printing an error is some kind of "anti-pattern", so it's better to throw an exception anyway:
opt.getOrElse(throw new SomeException)

Issues with maps and their entries in Scala

I have a recursive function that takes a Map as single parameter. It then adds new entries to that Map and calls itself with this larger Map. Please ignore the return values for now. The function isn't finished yet. Here's the code:
def breadthFirstHelper( found: Map[AIS_State,(Option[AIS_State], Int)] ): List[AIS_State] = {
val extension =
for(
(s, v) <- found;
next <- this.expand(s) if (! (found contains next) )
) yield (next -> (Some(s), 0))
if ( extension.exists( (s -> (p,c)) => this.isGoal( s ) ) )
List(this.getStart)
else
breadthFirstHelper( found ++ extension )
}
In extension are the new entries that shall get added to the map. Note that the for-statement generates an iterable, not a map. But those entries shall later get added to the original map for the recursive call. In the break condition, I need to test whether a certain value has been generated inside extension. I try to do this by using the exists method on extension. But the syntax for extracting values from the map entries (the stuff following the yield) doesn't work.
Questions:
How do I get my break condition (the boolean statement to the if) to work?
Is it a good idea to do recursive work on a immutable Map like this? Is this good functional style?
When using a pattern-match (e.g. against a Tuple2) in a function, you need to use braces {} and the case statement.
if (extension.exists { case (s,_) => isGoal(s) } )
The above also uses the fact that it is more clear when matching to use the wildcard _ for any allowable value (which you subsequently do not care about). The case xyz gets compiled into a PartialFunction which in turn extends from Function1 and hence can be used as an argument to the exists method.
As for the style, I am not functional programming expert but this seems like it will be compiled into a iterative form (i.e. it's tail-recursive) by scalac. There's nothing which says "recursion with Maps is bad" so why not?
Note that -> is a method on Any (via implicit conversion) which creates a Tuple2 - it is not a case class like :: or ! and hence cannot be used in a case pattern match statement. This is because:
val l: List[String] = Nil
l match {
case x :: xs =>
}
Is really shorthand/sugar for
case ::(x, xs) =>
Similarly a ! b is equivalent to !(a, b). Of course, you may have written your own case class ->...
Note2: as Daniel says below, you cannot in any case use a pattern-match in a function definition; so while the above partial function is valid, the following function is not:
(x :: xs) =>
This is a bit convoluted for me to follow, whatever Oxbow Lakes might think.
I'd like first to clarify one point: there is no break condition in for-comprehensions. They are not loops like C's (or Java's) for.
What an if in a for-comprehension means is a guard. For instance, let's say I do this:
for {i <- 1 to 10
j <- 1 to 10
if i != j
} yield (i, j)
The loop isn't "stopped" when the condition is false. It simply skips the iterations for which that condition is false, and proceed with the true ones. Here is another example:
for {i <- 1 to 10
j <- 1 to 10
if i % 2 != 0
} yield (i, j)
You said you don't have side-effects, so I can skip a whole chapter about side effects and guards on for-comprehensions. On the other hand, reading a blog post I made recently on Strict Ranges is not a bad idea.
So... give up on break conditions. They can be made to work, but they are not functional. Try to rephrase the problem in a more functional way, and the need for a break condition will be replaced by something else.
Next, Oxbow is correct in that (s -> (p,c) => isn't allowed because there is no extractor defined on an object called ->, but, alas, even (a :: b) => would not be allowed, because there is no pattern matching going on in functional literal parameter declaration. You must simply state the parameters on the left side of =>, without doing any kind of decomposition. You may, however, do this:
if ( extension.exists( t => val (s, (p,c)) = t; this.isGoal( s ) ) )
Note that I replaced -> with ,. This works because a -> b is a syntactic sugar for (a, b), which is, itself, a syntactic sugar for Tuple2(a, b). As you don't use neither p nor c, this works too:
if ( extension.exists( t => val (s, _) = t; this.isGoal( s ) ) )
Finally, your recursive code is perfectly fine, though probably not optimized for tail-recursion. For that, you either make your method final, or you make the recursive function private to the method. Like this:
final def breadthFirstHelper
or
def breadthFirstHelper(...) {
def myRecursiveBreadthFirstHelper(...) { ... }
myRecursiveBreadthFirstHelper(...)
}
On Scala 2.8 there is an annotation called #TailRec which will tell you if the function can be made tail recursive or not. And, in fact, it seems there will be a flag to display warnings about functions that could be made tail-recursive if slightly changed, such as above.
EDIT
Regarding Oxbow's solution using case, that's a function or partial function literal. It's type will depend on what the inference requires. In that case, because that's that exists takes, a function. However, one must be careful to ensure that there will always be a match, otherwise you get an exception. For example:
scala> List(1, 'c') exists { case _: Int => true }
res0: Boolean = true
scala> List(1, 'c') exists { case _: String => true }
scala.MatchError: 1
at $anonfun$1.apply(<console>:5)
... (stack trace elided)
scala> List(1, 'c') exists { case _: String => true; case _ => false }
res3: Boolean = false
scala> ({ case _: Int => true } : PartialFunction[AnyRef,Boolean])
res5: PartialFunction[AnyRef,Boolean] = <function1>
scala> ({ case _: Int => true } : Function1[Int, Boolean])
res6: (Int) => Boolean = <function1>
EDIT 2
The solution Oxbow proposes does use pattern matching, because it is based on function literals using case statements, which do use pattern matching. When I said it was not possible, I was speaking of the syntax x => s.