Skip to content

Commit

Permalink
Merge pull request #851 from null-a/dp-cache
Browse files Browse the repository at this point in the history
Make `cache` callable as `dp.cache`
  • Loading branch information
stuhlmueller committed May 26, 2017
2 parents adf99ae + e2cfc7f commit a997d0f
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 6 deletions.
19 changes: 19 additions & 0 deletions docs/functions/other.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ Other
var y = { b: 3, c: 4 };
extend(x, y); // => { a: 1, b: 3, c: 4 }

.. js:function:: cache(fn, maxSize)

Returns a memoized version of ``fn``. The memoized function is
backed by a cache that is shared across all executions/possible
worlds.

``cache`` is provided as a means of avoiding the repeated
computation of a *deterministic* function. The use of ``cache``
with a *stochastic* function is unlikely to be appropriate. For
stochastic memoization see :js:func:`mem`.

When ``maxSize`` is specified the memoized function is backed by a
LRU cache of size ``maxSize``. The cache has unbounded size when
``maxSize`` is omitted.

``cache`` can be used to memoize mutually recursive functions,
though for technical reasons it must currently be called as
``dp.cache`` for this to work.

.. js:function:: mem(fn)

Returns a memoized version of ``fn``. The memoized function is
Expand Down
16 changes: 13 additions & 3 deletions src/headerUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ module.exports = function(env) {
return k(s, console.log(ad.valueRec(x)));
}

var dp = {};

// Caching for a wppl function f.
//
// Caution: if f isn't deterministic weird stuff can happen, since
// caching is across all uses of f, even in different execuation
// caching is across all uses of f, even in different execution
// paths.
function cache(s, k, a, f, maxSize) {
dp.cache = function(f, maxSize) {
var c = LRU(maxSize);
var cf = function(s, k, a) {
var args = Array.prototype.slice.call(arguments, 3);
Expand Down Expand Up @@ -47,7 +49,14 @@ module.exports = function(env) {
return f.apply(this, [s, newk, a].concat(args));
}
};
return k(s, cf);
// Make the cache publicly available to facilitate checking the
// complexity of algorithms.
cf.cache = c;
return cf;
};

function cache(s, k, a, f, maxSize) {
return k(s, dp.cache(f, maxSize));
}

function apply(s, k, a, wpplFn, args) {
Expand Down Expand Up @@ -207,6 +216,7 @@ module.exports = function(env) {
return {
display: display,
cache: cache,
dp: dp,
apply: apply,
applyd: applyd,
_Fn: _Fn,
Expand Down
2 changes: 1 addition & 1 deletion tests/test-data/deterministic/expected/cache.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"result": true
"result": [true, true, true, true, true]
}
19 changes: 17 additions & 2 deletions tests/test-data/deterministic/models/cache.wppl
Original file line number Diff line number Diff line change
@@ -1,2 +1,17 @@
var id = cache(function(x) { return x; });
id(Infinity) === Infinity && id(-Infinity) === -Infinity;
var id = cache(function(x) { globalStore.x += 1; return x; });
// Test mutual recursion between cached functions.
var odd = dp.cache(function(n) { return n <= 0 ? false : even(n - 1); });
var even = dp.cache(function(n) { return n <= 0 ? true : odd(n - 1); });

[
(function() {
globalStore.x = 0;
id(0);
id(0);
return globalStore.x === 1;
})(),
id(Infinity) === Infinity,
id(-Infinity) === -Infinity,
odd(3),
even(4)
];

0 comments on commit a997d0f

Please sign in to comment.