Prolog to Racklog - Trouble using %rel and %which

This problem has really stumped me. I don't understand the correct method to build a simple Prolog rule in Racklog, for example, pairing two people up by company:

% Prolog (runs in SWISH)
company(art ,apple).
company(bob ,apple).
company(cy  ,ibm).
company(deb ,ibm).
company(ed  ,microsoft).
company(fay ,ibm).

company_pair(X, Y) :- % make sure the two people aren't the same person, but from the same company
    company(X, Z), company(Y, W), (Z = W, \+(X = Y)).

company_pair(art, N). %returns ben
company_pair(M, N). %returns art/ben ben/art cy/deb cy/fay ...etc.

So far, this is what I have gotten in Racket:

#lang racket/base

(require racklog)

(define %company
  (%rel ()
        [('art 'apple)]
        [('bob 'apple)]
        [('cy 'ibm)]
        [('deb 'ibm)]
        [('ed 'microsoft)]
        [('fay 'ibm)]
        ))

(define %company_pair
  (%rel (x y)
        [(x y 
            (%let (comp)
                  (%and (%company x comp)
                        (%company y comp)
                        (%not (%== x y)))))
         ]))

(%which () (%company_pair 'art 'bob))
;returns #f, it should return true as art and bob both work for apple

;some hardcoded trials below

(let ([x 'bob])
  (%which (y)
          (%let (comp)
                (%and (%company x comp)
                      (%company y comp)
                      (%not (%== x y))))))
;returns '((y . art)) correctly

(%which ()
        (%let (comp)
              (%and (%company 'art comp)
                    (%company 'bob comp)
                    (%not (%== 'art 'bob)))))
;returns '() correctly as all conditions are met

(%which (Y)
        (%let (comp)
              (%and (%company 'deb  comp)
                    (%company Y comp))))
;returns '((Y . cy)) correctly

As you can see, I can get it to work, but not as a %rel or predicate or function. Maybe this is just a silly mistake like a () in the wrong place, but I can't see it. I've looked through the Racklog docs and I couldn't find anything about designing %rels similar to this.

Hi, @lannydpittman.

Never used racklog before, so I can't really give a good explanation here, but this seems to do the trick:

(define %company_pair
  (%rel (x y)
        [(x y)
         (%let (comp)
               (%and (%company x comp)
                     (%company y comp)
                     (%not (%== x y))))]))

(%which () (%company_pair 'art 'bob))

I think you were just extending the variables declaration too far; perhaps missing the closing ) in the definition.

I hope that helps!

1 Like