daonode: 一个函数式逻辑求解器
发布于 2年前 作者 chaosim 852 次浏览

我发布了daonode,可通过npm安装,版本库在https://github.com/chaosim/daonode 安装daonode: npm install daonode

Dao是一个函数式逻辑求解器, 具有统一代码和数据,语法和程序,逻辑与函数,编译与执行的能力。 Daonode是原python项目daot用coffescript移植、重写后的升级版本。因为coffeescript可编译到javascript,因此daonode同时也直接就是javascript。 当lisp在javascript遇见prolog,世界将会怎样?

一些例子 (摘录的用coffeescript写的daonode测试代码):

"test builtin function": (test) ->
    add = fun(2, (x, y) -> x+y)
    test.equal  solve(add(1, add(1,1)), 3

"test macro": (test) ->
    orpm = macro((x, y) -> orp(x, y))
    test.equal  solve(orpm(fail, print_(2))), null

"test macro tofun": (test) ->
    orpm = macro(2, (x, y) -> orp(x, y))
    test.equal  solve(orpm(print_(1), print_(2))), null
    test.equal  solve(tofun(orpm)(print_(1), print_(2))), null
    test.equal  solve(tofun(orpm)(quote(print_(1)), quote(print_(2)))), null

"test proc,aka online function in dao": (test) ->
    a = proc(0, 'a', () ->
      i = 0
      add(1, 2))
    test.equal solve(a()), 3

"test eval_ quote": (test) ->
    exp = if_(1, 2, 3)
    test.equal  solve(quote(exp)), exp
    test.equal  solve(eval_(quote(exp))), 2

"test lisp style catch/throw ": (test) ->
    test.equal  solve(catch_(1, 2)), 2
    test.equal  solve(catch_(1, throw_(1, 2), 3)), 2
    test.equal(solve(block('foo', protect(break_('foo', 1), print_(2)))), 1)
    test.equal(solve(block('foo', protect(break_('foo', 1),  print_(2), print_(3)))), 1)

"test callcc2": (test) ->
    a = null
    solve(begin(callcc((k) -> a = k), add(1, 2)))
    test.equal a(null), 3

"test callfc": (test) ->
    a = null
    x = vari('x')
    x.binding = 5
    solve(orp(callfc((k) -> a = k), add(x, 2)))
    test.equal a(null), 7

"test quasiquote": (test) ->
    test.equal solve(qq(1)), 1
    a = add(1, 2)
    test.deepEqual solve(qq(a)), a
    test.deepEqual solve(qq(uq(a))), 3
    test.deepEqual solve(qq(uqs([1,2]))), new UnquoteSliceValue([1,2])
    test.deepEqual solve(qq(add(uqs([1,2])))), a

"test block break continue": (test) ->
    test.equal  solve(block('a', 1)), 1
    test.equal  solve(block('a', break_('a', 2), 1)), 2
    test.equal  solve(block('a', block('b', break_('b', 2), 1), 3)), 3
    a = vari('a')
    test.equal  solve(begin(assign(a, 1),  block('a', if_(eq(a, 5), break_('a', a)), inc(a), continue_('a')))), 5

"test logic predicate": (test) ->
    test.equal(solve(andp(unify(a, 1))), true)
    test.equal  (solve(andp(unify(a, 1), unify(a, 2))), false)
    test.equal  solve(orp(andp(unify(a, 1), unify(a, 2)), unify(a, 2))), true
   test.equal  (solve(orp(findall(orp(print_(1), print_(2))),)
                           print_(3))), null
   test.equal  (solve(findall(once(orp(print_(1), (print_(2)))))), null)

"test logic rule": (test) ->
    r = rule(2, (x, y) ->
      [[x,y], 1, null])
    test.equal  solve(r(1,1)), 1

"test parser builtins": (test) ->
    test.deepEqual  (solve(begin(settext('ab'), any(char(_), result, _), eoi, result)), ['a', 'b'])
    test.equal  (solve(parsetext(begin(some(char(_)), char('c'), eoi), 'abc')), true)
    test.deepEqual  (solve(begin(parsetext(seplist(char(_), {sep:char(','), times:n, result:result, template:_}), 'a,b,c'), result)), ['a', 'b','c'])
    test.deepEqual  (solve(begin(parsetext(andp(seplist(char(_), {sep:char(','), times:n, result:result, template:_}), char(','), char('b'), char(','), char('c')), 

‘a,b,c’), result)), [‘a’])

回到顶部