jsonnet-microkanren

microKanren implementation in Jsonnet
git clone https://ccx.te2000.cz/git/jsonnet-microkanren
Log | Files | Refs

microkanren_checks.libsonnet (2904B)


      1 local safeString(value) =
      2   local t = std.type(value);
      3   if t == 'function' then
      4     '<function>'
      5   else if t == 'array' then
      6     '[%s]' % [std.join(', ', std.map(safeString, value))]
      7   else if t == 'object' then
      8     '{%s}' % [std.join(', ', std.map(
      9       function(f) '%s: %s' % [std.escapeStringJson(f.key), safeString(f.value)],
     10       std.objectKeysValues(value)
     11     ))]
     12   else
     13     std.toString(value);
     14 
     15 local checkType(type) = function(value) std.assertEqual(std.type(value), type);
     16 // value checks
     17 {
     18   trace(str, val, rest):
     19     std.trace("%s: %s" % [str, safeString(val)], rest),
     20 
     21   traceValue(str, val):
     22     std.trace("%s: %s" % [str, safeString(val)], val),
     23 
     24   objectFields(obj, checks):
     25     assert std.assertEqual(std.type(obj), 'object');
     26     assert std.assertEqual(std.objectFields(obj), std.objectFields(checks));
     27     std.all(std.map(
     28       function(f) checks[f.key](f.value),
     29       std.objectKeysValues(obj)
     30     )),
     31 
     32   Variable(var):
     33     $.objectFields(var, {
     34       ['µK:var']: function(value)
     35         assert std.assertEqual(std.type(value), 'string');
     36         assert std.parseInt(value) >= 0: "Incorrect variable number: %s" % [value];
     37         true,
     38     }),
     39   checkVariable(var):
     40     assert $.Variable(var);
     41     var,
     42 
     43   VariableCount(vc):
     44     assert vc >= 0: "Incorrect state.variableCount: less than zero";
     45     true,
     46 
     47   Substitution(subst):
     48     assert std.assertEqual(std.type(subst), 'object');
     49     std.all(std.map(
     50       function(f)
     51         assert std.parseInt(f.key) >= 0;
     52         true,
     53       std.objectKeysValues(subst)
     54     )),
     55   checkSubstitution(subst):
     56     assert $.Substitution(subst);
     57     subst,
     58 
     59   State(state):
     60     local checkVariableMaximum = std.all(std.map(
     61       function(f)
     62         assert std.parseInt(f.key) >= 0;
     63         assert std.parseInt(f.key) < state.variableCount;
     64         true,
     65       std.objectKeysValues(state.substitution)
     66     ));
     67     $.objectFields(state, {
     68       variableCount: $.VariableCount,
     69       substitution: $.Substitution,
     70     }) && checkVariableMaximum,
     71   checkState(state):
     72     assert $.State(state);
     73     state,
     74 
     75   Stream(stream):
     76     assert std.assertEqual(std.type(stream), 'object');
     77     local t = stream['µK:stream'];
     78     assert std.type(t) == 'string';
     79     if t == 'empty' then
     80       $.objectFields(stream, {['µK:stream']: checkType('string')})
     81     else if t == 'immature' then
     82       $.objectFields(stream, {
     83         ['µK:stream']: checkType('string'),
     84         call: checkType('function'),
     85       })
     86     else if t == 'mature' then
     87       $.objectFields(stream, {
     88         ['µK:stream']: checkType('string'),
     89         state: $.State,
     90         next: $.Stream,
     91       })
     92     else
     93       error "Incorrect stream type",
     94   checkStream(stream):
     95     assert $.Stream(stream);
     96     stream,
     97 
     98   Goal(goal): $.objectFields(goal, {
     99     ['µK:goal']: checkType('function'),
    100   }),
    101   checkGoal(goal):
    102     assert $.Goal(goal);
    103     goal,
    104 }
    105 // vim: sts=2 ts=2 sw=2 et