The maze book for programmers!
mazesforprogrammers.com

Algorithms, circle mazes, hex grids, masking, weaving, braiding, 3D and 4D grids, spheres, and more!

DRM-Free Ebook

The Buckblog

assorted ramblings by Jamis Buck

A Rubyish DSL for Logic Programming

6 November 2006 — 1-minute read

Alright, I had a rather productive weekend. After mentioning in my post about Prolog in Ruby that it would be nice to have a more Rubyish implementation, I started hammering away on an implementation of my own.

The result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
db = KBase::Database.new do
  + X.is_sibling_of(Y).if { Z.is_parent_of(X) & Z.is_parent_of(Y) & X.is_not(Y) }
  + X.is_parent_of(Y).if { X.is_father_of(Y) }
  + X.is_parent_of(Y).if { X.is_mother_of(Y) }

  + jamis.is_father_of(kaitrin)
  + jamis.is_father_of(nathaniel)
end

result = db.query { nathaniel.is_sibling_of(X) }
puts "querying #{result.goal}..."
result.each do |solution|
  puts "solution:"
  solution.bindings.each do |variable, value|
    puts " - #{variable}: #{value}"
  end
end
puts "no solutions!" if result.empty?

The output from the above program:

1
2
3
4
5
$ ruby resolver.rb
querying nathaniel.is_sibling_of(X)...
solution:
 - X: kaitrin
$

I’ll be cleaning it up next, and will write about the implementation of the DSL. It was a fun project! Honestly, though, the DSL was the easy part…the hard part was getting the prolog-like matching and backtracking working. It’s still not perfect, but it works for queries like the above.

Reader Comments

Nice work! Would be interesting to hook this up to ActiveRDF and implement some RDFS and OWL rules.