I've been working through "Prolog and Natural Language Analysis" in 
miniKanren recently https://github.com/tca/PANL/ (link to book in README).
It covers all the things you need to make a program like this, and it 
chapter 5 it has you make one.

The key thing you are missing is building the logical forms of the 
sentences so you can pull out the parts you want.

I wrote up very simple dialogue program that works based on extracting 
relation tuples from the logical forms. A statement will add the tuple to 
the database; a question will put variables in the tuple and query the 
database with it. There is obviously a lot more to do but it's a start!


(use-modules (minikanren language)
             (minikanren dcg))
(use-modules (ice-9 readline))




(--> (question s)
     (fresh (np vp s1)
       (conde ((wh-question np) (verb-phrase `(lambda (,np) ,s)) '(?)))))


(--> (statement s)
     (fresh (np vp s1)
       (conde ((noun-phrase np) (verb-phrase `(lambda (,np) ,s))))))


(--> (verb-phrase vp)
     (fresh (tv np)
       (conde ((transitive-verb `(lambda (,np) ,vp)) (noun-phrase np))
              ((intransitive-verb vp)))))


(--> (transitive-verb logical-form)
     (fresh (tv)
       (conde (`(,tv) (escape (transitive-verbo tv logical-form))))))


(define (transitive-verbo tv logical-form)
  (fresh (x y)
    (conde ((== tv 'wrote))
           ((== tv 'played)))
    (== logical-form `(lambda (,x) (lambda (,y) (,tv ,x ,y))))))


(--> (intransitive-verb exp)
     (fresh (x)
       (conde ((== exp `(lambda (,x) (halts ,x)))
               '(halts)))))


(--> (noun-phrase x)
     (fresh (d x^)
       (conde ((proper-noun x))
              ((== x `(,d ,x^)) (determiner d) (noun x^)))))


(--> (determiner x)
     (conde ((== x 'the) '(the))))


(--> (proper-noun logical-form)
     (fresh (pn)
       (conde (`(,pn) (escape (proper-nouno pn logical-form))))))


(define (proper-nouno pn logical-form)
  (fresh ()
    (== pn logical-form)
    (conde
     ((== pn 'will))
     ((== pn 'jason))
     ((== pn 'dan))
     ((== pn 'oleg))
     ((== pn 'kanren))
     ((== pn 'minikanren))
     ((== pn 'microkanren)))))


(--> (noun n)
     (conde ((== n 'cat) '(cat))
            ((== n 'guitar) '(guitar))))


(--> (wh-question x)
     (fresh (x)
       (conde ((== x 'who) `(,x)))))


(define (membero x l)
 (fresh (head tail)
  (== l `(,head . ,tail))
  (conde
   ((== x head))
   ((membero x tail)))))


(define (query in db db^ out)
  (fresh (logical-form)
    (conde
     ((statement logical-form in '())
      (== db^ (cons logical-form db))
      (== out 'ok!))
     ((question logical-form in '())
        (== db db^)
        (membero logical-form db)
        (statement logical-form out '())))))


(define db '())
(define (run-query in)
  (let ((answer (run^ 1 (lambda (state)
                          (fresh (db^ out)
                            (== state (cons db^ out))
                            (query in db db^ out))))))
    (if (null? answer)
        (display "I don't know.")
        (let ((state (caar answer)))
          (let ((db^ (car state))
                (out (cdr state)))
            (set! db db^)
            (display out)))))
  (newline))


(define (dialogue)
  (call-with-input-string (string-append "(" (readline "> ") ")")
    (lambda (in) (run-query (read in))))
  (dialogue))




(dialogue)


;; > will wrote minikanren
;; ok!
;; > jason wrote microkanren
;; ok!
;; > oleg wrote kanren
;; ok!
;; > the cat played the guitar
;; ok!
;; > dan played will
;; ok!
;; > who played the guitar ?
;; (the cat played the guitar)
;; > who played will ?
;; (dan played will)
;; > who wrote kanren ?
;; (oleg wrote kanren)
;; > who wrote minikanren ?
;; (will wrote minikanren)
;; > who wrote microkanren ?
;; (jason wrote microkanren)
;; > who halts ?
;; (minikanren halts)


-- 
You received this message because you are subscribed to the Google Groups 
"minikanren" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/minikanren.
For more options, visit https://groups.google.com/d/optout.

Reply via email to