-
Notifications
You must be signed in to change notification settings - Fork 0
/
sliced_builtins.js
131 lines (107 loc) · 3.84 KB
/
sliced_builtins.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// generates a module with traced versions of the church builtins that also
// perform slicing.
_ = require("underscore");
shred = require("./shred");
retraced = require("./retraced_builtins");
church = require("./webchurch/church_builtins");
// Begin module generation======================================================
// Slicing as state-transforming semantics of re-trace statmenets.
var SLICE_START_VAR = "";
var SLICE_STATE = {
slice_variables : [],
slice : [],
depk : [function (x) { return x; }]
}
function advance_slice_state(lhsv, procname, rhsvs) {
var in_slice = false;
for (var i = 0; i < rhsvs.length; i++) {
if (_.contains(SLICE_STATE.slice_variables, rhsvs[i])) {
in_slice = true;
break;
}
}
if (in_slice) {
SLICE_STATE.slice_variables.unshift(lhsv);
SLICE_STATE.slice.push([lhsv, procname, rhsvs]);
} else {
}
}
// So let's get this straight. You want to execute the trace statements in the
// original order, but produce a BACKWARD SLICE; i.e., all statements on which
// some variable is dependent. That is totally OK and not crazy at all, you
// just need to hook together a truckload (where 1 truckload \propto
// #statements) of continuations to do so.
function retract_slice_state(lhsv, procname, rhsvs) {
function remove_elt(items, item) {
while (items.indexOf(item) !== -1) {
items.splice(items.indexOf(item), 1);
}
return items
}
var call = function(deplist, k) {
if (deplist == []) { return k([]); } else {
if (_.contains(deplist, lhsv)) {
SLICE_STATE.slice.push([lhsv, procname, rhsvs]);
// var next_deplist = _.filter(deplist, function (x) { x != lhsv });
for (var i = 0; i < rhsvs.length; i++) {
if (!(_.contains(deplist, rhsvs[i]))) {
deplist.push(rhsvs[i]);
}
}
return k(deplist);
} else {
return k(deplist);
}
}
}
var curr_idx = SLICE_STATE.depk.length - 1;
var next_step = function (deplist) {
return call(deplist, SLICE_STATE.depk[curr_idx]);
};
SLICE_STATE.depk.push(next_step);
}
function set_slice_from(retv, procname, callvs) {
SLICE_STATE.slice_variables = [retv];
SLICE_STATE.slice = [[retv, procname, callvs]];
}
function bwd_slice_of(vs) {
SLICE_STATE.depk[SLICE_STATE.depk.length - 1](vs);
SLICE_STATE.slice.reverse();
}
function dump_slice() {
return shred.dump_stmt_list(SLICE_STATE.slice, true);
}
function reset_slice_state() {
SLICE_START_VAR = "";
SLICE_STATE.slice_variables = [];
SLICE_STATE.slice = [];
SLICE_STATE.depk =[ function (x) {return x; } ];
}
function sliced(name, trace_proc) {
var call = function () {
var call_vars = [];
for (var i = 0; i < arguments.length; i++) {
call_vars.push(arguments[i]);
}
var retvar = trace_proc.apply(this, arguments);
var stmt = [retvar, name, call_vars];
advance_slice_state(retvar, name, call_vars);
retract_slice_state(retvar, name, call_vars);
return retvar;
}
return call;
}
synth_builtins = bt.synthesize_builtins(retraced, sliced, []);
module.exports = synth_builtins.exports;
module.exports.__annotations__ = synth_builtins.exports.__annotations__;
module.exports._const = function (c) {
var retrace_const_res = retraced._const(c);
retract_slice_state(retrace_const_res, "_const", [c]);
return retrace_const_res;
}
module.exports.dump_trace = shred.dump_trace;
module.exports.set_slice_from = set_slice_from;
module.exports.bwd_slice_of = bwd_slice_of;
module.exports.dump_slice = dump_slice;
module.exports.reset_slice_state = reset_slice_state;
module.exports.state = SLICE_STATE;