Module: MicroKanren::Lisp

Included in:
Core, MiniKanrenWrappers
Defined in:
lib/micro_kanren/lisp.rb

Instance Method Summary collapse

Instance Method Details

#assp(func, alist) ⇒ Object

Search association list by predicate function. Based on lua implementation by silentbicycle: github.com/silentbicycle/lua-ukanren/blob/master/ukanren.lua#L53:L61

Additional reference for this function is scheme: Ref for assp: www.r6rs.org/final/html/r6rs-lib/r6rs-lib-Z-H-4.html



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/micro_kanren/lisp.rb', line 39

def assp(func, alist)
  if alist
    first_pair  = car(alist)
    first_value = car(first_pair)

    if func.call(first_value)
      first_pair
    else
      assp(func, cdr(alist))
    end
  else
    false
  end
end

#car(z) ⇒ Object



11
# File 'lib/micro_kanren/lisp.rb', line 11

def car(z)     ; z.call(-> (p, q) { p }) ; end

#cdr(z) ⇒ Object



12
# File 'lib/micro_kanren/lisp.rb', line 12

def cdr(z)     ; z.call(-> (p, q) { q }) ; end

#cons(x, y) ⇒ Object

Returns a Cons cell that is also marked as such for later identification.



5
6
7
8
9
# File 'lib/micro_kanren/lisp.rb', line 5

def cons(x, y)
  -> (m) { m.call(x, y) }.tap do |func|
    func.instance_eval{ def ccel? ; true ; end }
  end
end

#cons?(d) ⇒ Boolean Also known as: pair?

Returns:

  • (Boolean)


14
15
16
# File 'lib/micro_kanren/lisp.rb', line 14

def cons?(d)
  d.respond_to?(:ccel?) && d.ccel?
end

#length(list) ⇒ Object



23
24
25
# File 'lib/micro_kanren/lisp.rb', line 23

def length(list)
  list.nil? ? 0 : 1 + length(cdr(list))
end

#lists_equal?(a, b) ⇒ Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
# File 'lib/micro_kanren/lisp.rb', line 73

def lists_equal?(a, b)
  if cons?(a) && cons?(b)
    lists_equal?(car(a), car(b)) && lists_equal?(cdr(a), cdr(b))
  else
    a == b
  end
end

#lprint(node, cons_in_cdr = false) ⇒ Object

Converts Lisp AST to a String. Algorithm is a recursive implementation of www.mat.uc.pt/~pedro/cientificos/funcional/lisp/gcl_22.html#SEC1238.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/micro_kanren/lisp.rb', line 56

def lprint(node, cons_in_cdr = false)
  if cons?(node)
    str = cons_in_cdr ? '' : '('
    str += lprint(car(node))

    if cons?(cdr(node))
      str += ' ' + lprint(cdr(node), true)
    else
      str += ' . ' + lprint(cdr(node)) unless cdr(node).nil?
    end

    cons_in_cdr ? str : str << ')'
  else
    atom_string(node)
  end
end

#map(func, list) ⇒ Object



19
20
21
# File 'lib/micro_kanren/lisp.rb', line 19

def map(func, list)
  cons(func.call(car(list)), map(func, cdr(list))) if list
end

#procedure?(elt) ⇒ Boolean

We implement scheme cons cells as Procs. This function returns a boolean identically to the Scheme procedure? function to avoid false positives.

Returns:

  • (Boolean)


29
30
31
# File 'lib/micro_kanren/lisp.rb', line 29

def procedure?(elt)
  elt.is_a?(Proc) && !cons?(elt)
end