The proposed forms for BKO set-builder were:

KET in SUPERPOSITION such that TRUTH-STATEMENT OP-SEQUENCE KET for KET in SUPERPOSITION such that TRUTH-STATEMENTand 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.

Python:

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 oneSo, 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> |Jefferson> 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:

KET in SUPERPOSITION

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!