Combinators for logic programming
09 June 2011
Digging in my hard drive found this piece of code from my functional programming studies that implements
the logic unification algorithm described in the article ‘Combinators for logic programming’ by Michael Spivey and Silvija Seres.
Here are some samples of what kind of problems it can solve.
Sample #1 – append
let X = var "x" let Y = var "y"let problem1 = append X Y (list [1;2;3;4;5])run problem1 |> printSolutions
returns:
{x=Nil,y=[1, 2, 3, 4, 5]}
{x=1,y=[2, 3, 4, 5]}
{x=[1, 2],y=[3, 4, 5]}
{x=[1, 2, 3],y=[4, 5]}
{x=[1, 2, 3, 4],y=5}
{x=[1, 2, 3, 4, 5],y=Nil}
Sample #2 – good sequence
let rec good s = step( (s == cons (Int 0) Nil) ||| exists (fun t -> exists(fun q -> exists(fun r -> (s == cons (Int 1) t) &&& append q r t &&& (good q) &&& (good r)))) )let problem2 = good (var "s")run problem2 |> printSolutions
returns:
{s=0}
{s=[1, 0, 0]}
{s=[1, 0, 1, 0, 0]}
{s=[1, 1, 0, 0, 0]}
{s=[1, 0, 1, 0, 1, 0, 0]}
{s=[1, 1, 0, 0, 1, 0, 0]}
{s=[1, 1, 0, 1, 0, 0, 0]}
{s=[1, 0, 1, 1, 0, 0, 0]}
{s=[1, 1, 0, 0, 1, 0, 1, 0, 0]}
{s=[1, 1, 0, 1, 0, 0, 1, 0, 0]}
… ad infinitum
Sample #3 – Difference lists & Grammars
let append' (a1,a2) (b1,b2) (c1,c2) = (a1 == c1) &&& (a2 == b1) &&& (b2 == c2) // -- difference list axiomlet list3 xs ys = List.foldBack (cons) xs yslet (++) f1 f2 = fun (list1,r) -> exists( fun x -> append' (list1,x) (x,r) (list1,r) &&& f1(list1,x) &&& f2(x,r))let final s (list,rest) = exists(fun x -> ((list == list3 ([String(s)]) x)) &&& (x == rest)) let or' f g (list,rest) = f (list,rest) ||| g (list,rest)let noun = final "cat" |> or' <| final "mouse" let determiner = final "the" |> or' <| final "a" let verb = final "scares" |> or' <| final "hates"let noun_phrase = determiner ++ noun let verb_phrase = verb ++ noun_phraselet sentence = noun_phrase ++ verb_phraserun ( sentence (var "q", Nil)) |> printSolutions
returns:
{q=[the, cat, scares, the, cat]}
{q=[the, cat, scares, the, mouse]}
{q=[the, mouse, scares, the, cat]}
{q=[the, cat, hates, the, cat]}
{q=[the, mouse, scares, the, mouse]}
{q=[a, cat, scares, the, cat]}
{q=[the, cat, scares, a, cat]}
{q=[the, mouse, hates, the, cat]}
{q=[a, cat, scares, the, mouse]}
{q=[a, mouse, scares, the, cat]}
{q=[the, cat, hates, the, mouse]}
{q=[the, mouse, scares, a, cat]}
{q=[a, cat, hates, the, cat]}
{q=[a, mouse, scares, the, mouse]}
{q=[the, cat, scares, a, mouse]}
{q=[the, mouse, hates, the, mouse]}
{q=[a, cat, scares, a, cat]}
{q=[a, mouse, hates, the, cat]}
{q=[the, cat, hates, a, cat]}
{q=[the, mouse, scares, a, mouse]}
{q=[a, cat, hates, the, mouse]}
{q=[a, mouse, scares, a, cat]}
{q=[the, cat, hates, a, mouse]}
{q=[the, mouse, hates, a, cat]}
{q=[a, cat, scares, a, mouse]}
{q=[a, mouse, hates, the, mouse]}
{q=[the, mouse, hates, a, mouse]}
{q=[a, cat, hates, a, cat]}
{q=[a, mouse, scares, a, mouse]}
{q=[a, cat, hates, a, mouse]}
{q=[a, mouse, hates, a, cat]}
{q=[a, mouse, hates, a, mouse]}
The code is here
blog comments powered by Disqus