Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.1.1.css">
</head>
<body>
  <div id="qunit"></div>
  <div id="qunit-fixture"></div>
  <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>
  <script src="https://code.jquery.com/qunit/qunit-2.1.1.js"></script>
</body>
</html>
 
/* jshint esnext: true */ 
// miniKanren
function mKanren() {
  function LVar(id) {
    return Symbol.for('LVar' + id)
  }
  function isLVar(a) {
    return typeof a === 'symbol'
        && /Symbol\(LVar[0-9]+\)/.test(a.toString())
  }
  function addSubstitution(subMap, lVar, value) {
    if (subMap instanceof Map) {
      subMap.set(lVar, value)
      return subMap
    }
    else {
      return null
    }
  }
  function walk(u, subMap) {
    if (isLVar(u)) {
      var value = u
      while (subMap.get(value) !== null && subMap.get(value) !== undefined) {
        value = subMap.get(value)
      }
      return value
    }
    else {
      return u
    }
  }
  function unify(_u, _v, subMap) {
    let u = walk(_u, subMap)
      , v = walk(_v, subMap)
    
    if (u === v)
      return subMap
    else if (isLVar(u))
      return addSubstitution(subMap, u, v)
    else if (isLVar(v))
      return addSubstitution(subMap, v, u)
    else
      return null
  }
  function printMap(subMap) {
    if (subMap instanceof Map) {
      var keys = Array.from(subMap.keys())
      return keys.reduce(function(acc, key) {
        acc[key.toString()] = subMap.get(key)
        return acc
      }, {})
    }
    else
      return subMap
  }
  
  function equalsMap(s1, s2) {
    return R.equals(printMap(s1), printMap(s2))
  }
  
  function emptyState() {
    return {subMap: {}, nextId: 0}
  }
  
  function goal(u, v) {
    return function(state) {
      var subMap = unify(u, v, state.subMap)
      if (subMap !== null && subMap !== undefined)
        return R.assoc('subMap', subMap, state)
      else
        return emptyState() 
    }
  }
  
  function callFresh(goalConstructor) {
    return function(state) {
      var goal = goalConstructor(LVar(state.nextId))
      return goal(R.assoc('nextId', state.nextId + 1, state))
    }
  }
  
  function disjunction(goal1, goal2) {
    return function(state) {
      var goal1State = goal1(state)
        , goal2State = goal2(state)
      
      return R.flatten([goal1State, goal2State])
    }
  }
  
  function conjunction(goal1, goal2) {
    return function(state) {
      goal1 = goal1 instanceof Array ? goal1 : [goal1]
      return goal1.map(goal => goal2(state))
    }
  }
  
  this.LVar = LVar
  this.isLVar = isLVar
  this.addSubstitution = addSubstitution
  this.walk = walk
  this.unify = unify
  this.print = printMap
  this.equals = equalsMap
}
var K = new mKanren()
QUnit.test('K.walk', assert => {
  var subMap = new Map([ [K.LVar(0), K.LVar(1)]
                       , [K.LVar(1), 'banana']
                       ])
  assert.ok(K.walk(K.LVar(0), subMap) === 'banana')
  assert.ok(K.walk(K.LVar(1), subMap) === 'banana')
  assert.ok(K.walk('mango', subMap) === 'mango')
})
QUnit.test('K.unify', assert => {
  assert.ok(
    K.equals(
      K.unify('banana', K.LVar(0), new Map()),
      new Map([[K.LVar(0), 'banana']])
    )
  )
  
  assert.ok(
    K.equals(
      K.unify(K.LVar(0), 'banana', new Map()),
      new Map([[K.LVar(0), 'banana']])
    )
  )
  
  assert.ok(
    K.equals(
      K.unify(K.LVar(0), 'banana', new Map([[K.LVar(0), 'banana']])),
      new Map([[K.LVar(0), 'banana']])
    )
  )
   
  assert.ok(
    K.equals(
      K.unify(K.LVar(0), 'mango', new Map([[K.LVar(0), 'banana']])),
      null
    )
  )
   
  assert.ok(
    K.equals(
      K.unify(K.LVar(0), 'banana', new Map([[K.LVar(9), 'squirrels']])),
      new Map([[K.LVar(0), 'banana'], [K.LVar(9), 'squirrels']])
    )
  )
  
  // Transitivity
  var newSubMap = K.unify(K.LVar(1), K.LVar(2), new Map([[K.LVar(0), K.LVar(1)]]))
  assert.ok(
    K.equals(
      K.walk(K.LVar(0), newSubMap),
      K.walk(K.LVar(1), newSubMap)
    )
  )
})
Output

This bin was created anonymously and its free preview time has expired (learn why). — Get a free unrestricted account

Dismiss x
public
Bin info
anonymouspro
0viewers