0

Here is the question.

I have this type Set:

type Set = Int => Boolean

Which i can use like this:

val belowNegFive: Set = (i) => i < -5
belowNegFive(10)

I mean to return a bool depending if the elem 10 pertains to the set of numbers below -5.

  1. I have this code, which returns the subset of s for which p holds.
def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)

Q1: How do I know p(e) tells me that the int e satisfies the predicate p?

  1. I have this fc, which returns whether all bounded integers within s satisfy p.
def contains(s: Set, elem: Int): Boolean = s(elem)

val bound = 1000    
def forall(s: Set, p: Int => Boolean): Boolean = {
def iter(a: Int): Boolean = {
  if (a > bound) true
  else if (contains(s, a) && !p(a)) false
  else iter(a+1)
  }
iter(-bound)
}

Q2: Why do all a > bound simply satisfy the condition of the predicate by default? Or true is just a stop condition? I am not sure why this fc does not return an infinite loop. Just an infinite list of Booleans, and the last Booleans are "true, true, true ..." for all a > bound.

Q3: And i do not see in which point it uses && between resulting Booleans in order to say yes, all bounded integers within s satisfy p.

thank you

kaileena
  • 121
  • 9
  • Didn't quite get first part. can you expand more on what you want to ask in Q1? – kiddorails Mar 17 '18 at 19:55
  • 1
    `p` is `Int=>Boolean` and `e` is `Int` therefore `p(e)` is `Boolean`. So `e` satisfies `p` if `p(e)` returns `true`. – jwvh Mar 17 '18 at 20:04
  • I potentially answered y own question. I noticed that the predicate p: Int => Boolean is treated in the same way as type Set = Int => Boolean. If we define s as a Set, the method s(e: Int) indicates if e belong to the Set s. So p(e: Int) should have the same result. – kaileena Mar 17 '18 at 20:10
  • If `a > bound` then you've run through all possible values of `a` (within the boundary). If you haven't found a `false` by now then there is none. If there is no `false` then it must be `true` for all. – jwvh Mar 17 '18 at 20:25
  • If `s` does **not** contain `a` then we don't care whether the predicate `p(a)` holds true or not. So the predicate test is skipped if `a` is **not** a member of `s`. Only if `a` **is** a member of `s` do we then test for the predicate `p(a)`. – jwvh Mar 17 '18 at 20:29

1 Answers1

1

For Q1: p is a function which takes an integer and returns a boolean. My predicate can be something like, the number should be less than -10. My set can be, it should be less than -5. filter will return that custom set for which both hold.

  type Set = Int => Boolean
  val belowNegFive: Set = (i) => i < -5

  def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)
  val predicate: Int => Boolean = (num) => num < -10    

  val myset = filter(belowNegFive, predicate)
  myset(0) #=> false
  myset(-1) #=> false
  myset(-10) #=> false
  myset(-11) #=> true

For Q2:

def contains(s: Set, elem: Int): Boolean = s(elem)

val bound = 1000    
def forall(s: Set, p: Int => Boolean): Boolean = {
def iter(a: Int): Boolean = {
  if (a > bound) true
  else if (contains(s, a) && !p(a)) false
  else iter(a+1)
  }
iter(-bound)
}

It's a stop condition. forall dictates that if for all integers b/w -1000 to 1000 (bound), if set contains the integer and predicate holds, it is true. AS you can see, in last line, the check is started from -1000 (iter(-bound)).

Q3: what will truth table for set and predicate look like?

set  | predicate | should continue checking?  
____________________________________________
true | true      | yes
false| true      | yes 
true | false     | no 
false| false     | yes

As you can see, only condition it should return false is the third one, which is the else if condition. For all others, it continues to check with the next integer for presence in set and predicate.

kiddorails
  • 12,961
  • 2
  • 32
  • 41
  • hello. for Q1: I understand. One more question about it. I have the code: type Set = Int => Boolean def fc(s: Set) = (i: Int) => s(i) How the compiler knows who s(i) is? I have not defined it. I only have these 2 code lines. – kaileena Mar 19 '18 at 22:41
  • for Q2,Q3: I am still not sure about the stop condition. I understand the truth table. But the fc "iter" receives as input all numbers between -100 and 100 (-bound and bound). So a list of integers. But it returns only one boolean. For me, I think it return the last boolean resulting from the if conditions. ("Iter" is a recursive fc. But it was much easier with other recursive fc such as factorial. It was obvious from the code that all previous results were multiplied between each other, until you reached the stop condition n == 1. Here, it is not obvious that the stop condition is a > bound.) – kaileena Mar 19 '18 at 23:29
  • I see that the number a can continue to increase to 101, 102... (why not?). In this case, " a > bound" would give infinite true booleans (Maybe I am missing a general principle behind these recursive fc) – kaileena Mar 19 '18 at 23:30
  • 1
    `a > bound` is just a stop condition in this function, like in factorial function you stop at n == 1. Instead of `a > bound`, you can also replace that with `a == bound + 1`, I think that will clear some confusion with infinite set. I agree that it's not a best iterating function there. The code of other recursive function had different objective, and they carried the last result to new value, they followed tail recursion. This is just an iteration without for/while loop. – kiddorails Mar 20 '18 at 04:10
  • for `def fc(s: Set) = (i: Int) => s(i)`. `s` _is a_ `Set`, who is defined here as a function which takes an integer and returns a boolean. s(i) naturally knows it's return type as boolean in that scenario. – kiddorails Mar 20 '18 at 04:14
  • Thank you. That is a very good explanation about the recursive fc here. For the Q1, the code "type Set = Int => Boolean val t = Set(3) t(3) t(2)". I see when typing t(3) the compiler returns true, and while typing t(2) it returns false. So when you create a variable of type Set, the compiler will automatically give true as a boolean output , for any input of type Int used in the creation of the variable of type Set. Just an observation. Correct? – kaileena Mar 20 '18 at 21:13
  • @kaileena you are confusing `Set` with the standard library's Set. When you did `Set(3)`, you are not working on the type `Set` created by you, but rather using the standard library's collection Set. For instance, try naming `type MySet = Int => Boolean` and do `val t = MySet(3)`; it will give the error. In your query, t(3) returns `true`, because that's how we can check in a std library's Set if an element is present. `val sset = Set(3,4); t(3) # true, t(4) # true` – kiddorails Mar 23 '18 at 04:09