Sunday 11 October 2015

shopping with process-reaction()

Today an example using process-reaction to go shopping. I guess the idea is that buying stuff is a kind of reaction:
price-of-object -> object
First, learn some prices:
price |apple> => 0.6|dollar>
price |orange> => 0.8|dollar>
price |milk> => 2.3|dollar>
price |coffee> => 5.5|dollar>
price |steak> => 9|dollar>
Now, let's go shopping (we have $30 to spend):
-- buy an orange:
sa: process-reaction(30|dollar>,price |orange>,|orange>)
29.2|dollar> + |orange>

-- buy 4 apples:
sa: process-reaction(29.2|dollar> + |orange>,price 4 |apple>,4 |apple>)
26.8|dollar> + |orange> + 4|apple>

-- buy milk, coffee and steak:
sa: process-reaction(26.8|dollar> + |orange> + 4|apple>,price |milk> + price |coffee> + price |steak>,|milk> + |coffee> + |steak>)
10|dollar> + |orange> + 4|apple> + |milk> + |coffee> + |steak>
Now we have it working, we can compact it! First, define a shopping list:
list-for |shopping> => |orange> + 4|apple> + |milk> + |coffee> + |steak>
Now, let's buy it all at once:
sa: process-reaction(30|dollar>,price list-for |shopping>,list-for |shopping>)
10|dollar> + |orange> + 4|apple> + |milk> + |coffee> + |steak>
I'm impressed how easy that was! Define your prices, define your shopping list, and then you are essentially done. And a key part of why it is so easy is the linearity of the price operator acting on the shopping list.

BTW, there is a quirk that you get stuff for free if it doesn't have a defined price. Whether we want to tweak process-reaction() to prevent this, or just be aware of it, I'm not yet sure. Anyway, here is an example. We add tomato to the shopping list, but we don't have a price:
sa: list-for |shopping> +=> |tomato>
sa: process-reaction(30|dollar>,price list-for |shopping>,list-for |shopping>)
10|dollar> + |orange> + 4|apple> + |milk> + |coffee> + |steak> + |tomato>
And note we still have $10, and a tomato. We got it for free! BTW, here is the price of the tomato:
sa: price |tomato>
|>
Hrmm... I now think it is impossible to tweak process-reaction() to handle undefined prices. Why? Because "price list-for |shopping>" is calculated before it is even sent to process-reaction() and |> being the identity element for superpositions means it is silently dropped.

Finally, we can find the cost of our shopping simply enough:
sa: price list-for |shopping>
20|dollar>
Update: I found one way to solve the free tomato problem. It goes something like this:
price |*> => |undefined price>
ie, if price is not defined for an object, return |undefined price> (making use of label descent). Now if we look at the price of our shopping list:
sa: price list-for |shopping>
20|dollar> + |undefined price>
Then we try to buy our full shopping list:
sa: process-reaction(30|dollar>,price list-for |shopping>,list-for |shopping>)
30|dollar>
And we see our shopping list didn't go through. This is a good thing. Process-reaction didn't know how to handle |undefined price>, and so the reaction was not processed.

Here is another way to handle it. The |undefined price> learn rule gets in the way, so let's drop back to this knowledge:
price |apple> => 0.6|dollar>
price |orange> => 0.8|dollar>
price |milk> => 2.3|dollar>
price |coffee> => 5.5|dollar>
price |steak> => 9|dollar>
list-for |shopping> => |orange> + 4|apple> + |milk> + |coffee> + |steak> + |tomato>
Define a new operator:
price-is-defined |*> #=> do-you-know price |_self>
Now, filter our shopping list to those we know the price of, and then buy the items:
sa: list-of |available items> => such-that[price-is-defined] list-for |shopping>
sa: process-reaction(30|dollar>,price list-of |available items>,list-of |available items>)
10|dollar> + |orange> + 4|apple> + |milk> + |coffee> + |steak>
And noting we didn't get a free tomato this time.

Update: just a quick conversion of operator names to be more like regular English:
the-price-for |apple> => 0.6|dollar>
the-price-for |orange> => 0.8|dollar>
the-price-for |milk> => 2.3|dollar>
the-price-for |coffee> => 5.5|dollar>
the-price-for |steak> => 9|dollar>
the |shopping list> => |orange> + 4|apple> + |milk> + |coffee> + |steak>
Now, ask "what is the price for the shopping list?":
sa: the-price-for the |shopping list>
20|dollar>
Cool, huh?

Eventually the plan is to have code to automatically cast English questions to BKO, and cast BKO answers back to English, but I don't fully know how to do that yet.

No comments:

Post a Comment