new function such that

So, for a long time I thought I needed a "set-builder" notation to complete the maths structure of BKO. But I'm now of the opinion we don't need such a thing, and it would actually weaken our model rather than fit in.

The proposed forms for BKO set-builder were:
and a couple of examples of this:
"Who was the president in 1825?"
|x> in "" |early US Presidents: _list> such that <year: 1825|president-era|x> > 0.5
"What was the party of the third president?"
party |x> for |x> in "" |early US Presidents: _list> such that president-number|x> == |number: 3> 
But now we have:
such-that[op1,op2,...] |x>
returns |x> if op_k |x> is true/yes for all operators op1, op2, ..., |> otherwise.
And it is linear, so if you apply it to a superposition it only keeps the results that are satisfied, and |> as identity element keeps it tidy for those kets that are not satisfied.

def such_that(one,context,ops):
  for op in ops.split(','):
    label = one.apply_op(context,op).the_label().lower()
    if label not in ["true","yes"]:
      return ket("",0)
  return one    
So, now lets do the two examples we mention above:
sa: load early-us-presidents.sw
sa: in-office-in-1825 |*> #=> is-equal[1825] president-era |_self>
sa: such-that[in-office-in-1825] "" |early US Presidents: _list>
|Monroe> + |Q Adams>

sa: is-third-president |*> #=> is-equal[3] president-number |_self>
sa: such-that[is-third-president] "" |early US Presidents: _list>

sa: party such-that[is-third-president] "" |early US Presidents: _list>
|party: Democratic-Republican>
And observe it does the same job as set-builder while preserving the OP-SEQUENCE KET structure.

Now, a quick toy example (randomly select kets from a superposition):
sa: random |*> #=> pick-elt (|yes> + |no>)
sa: such-that[random] split |a b c d e f g h i j k>
|c> + |f> + |g> + |i>

sa: such-that[random] split |a b c d e f g h i j k>
|a> + |b> + |g> + |h>
Now a breakfast menu example:
sa: load breakfast-menu.sw
-- "What can I get for breakfast that is under $6?"
sa: is-under-6-dollars |*> #=> is-less-than[6] price |_self>
sa: table[food,price,calories,description] sort-by[price] such-that[is-under-6-dollars] "" |menu: breakfast>
| food            | price | calories | description                                                         |
| French Toast    | 4.50  | 600      | "Thick slices made from our homemade sourdough bread"               |
| Belgian Waffles | 5.95  | 650      | "Two of our famous Belgian Waffles with plenty of real maple syrup" |

-- "What can I get for breakfast that is under 700 calories?"
sa: is-under-700-calories |*> #=> is-less-than[700] calories |_self>
sa: table[food,calories,price,description] sort-by[calories] such-that[is-under-700-calories] "" |menu: breakfast>
| food            | calories | price | description                                                         |
| French Toast    | 600      | 4.50  | "Thick slices made from our homemade sourdough bread"               |
| Belgian Waffles | 650      | 5.95  | "Two of our famous Belgian Waffles with plenty of real maple syrup" |
And I guess that is about as clear as I can make it. Note we do have to do a little dancing, as in common in the BKO scheme. We have to predefine our truth-statement operators before we can use them in such-that[]. I don't know of a good way to solve that, and maybe it is not an issue. We have to do likewise with tables quite often, it is only 1 line of code to do so, and it is easy enough to load collections of rules from sw files. Indeed, with further thought, this actually encourages modularity, which is a good thing!

Also, I should mention there are still some things we can't do given the current parser. eg:
"I want something with bacon in it!"
In set builder would look like:
|answer> => |x> in |menu: breakfast> such that <food: bacon|read:description|x> > 0.9

Using such-that, would probably look like:
contains-bacon |*> #=> |food: bacon> in read description |_self>
|answer> => such-that[contains-bacon] "" |menu: breakfast>

The bit currently not implemented is:

Anyway, that's it for this post. Heaps more to come!

Update: we can actually do this, and we don't need any new parser code. We can use either the intersection() function, or the new mbr() function.
sa: contains-bacon |*> #=> do-you-know mbr(|word: bacon>,read description |_self>)
sa: such-that[contains-bacon] "" |menu: breakfast>
|food: Homestyle Breakfast>
Very cool!

previous: simple image recognition
next: similar movies and similar actors

updated: 19/12/2016
by Garry Morrison
email: garry -at-