Fork me on GitHub
#core-logic
<
2023-08-13
>
Patrick00:08:51

Hi, I'm learning core.logic and I think I'm doing something the wrong way. I'm trying to express a very simple language with true, false, if arg1 then arg2 else arg3 as the valid terms and I'm trying to write an evalbooltermo constraint Right now I have this

(defn evalbooltermo [t e]
  (l/conde 
    [(l/== t 'true)
     (l/== e 'true)]
    [(l/== t 'false)
     (l/== e 'false)]
    [(l/fresh [?if ?ifstatement ?predicate ?thenclauses ?thenpath ?then ?true ?elseclauses ?elsepath ?else ?false] ;if P then T else E
              (l/resto t ?ifstatement) ; P then T else E
              (l/firsto ?ifstatement ?predicate) ; P
              (l/resto ?ifstatement ?thenclauses) ; then T else E
              (l/resto ?thenclauses ?thenpath) ; T else E
              (l/firsto ?thenpath ?true) ; T
              (l/resto ?thenpath ?elseclauses) ; else E
              (l/resto ?elseclauses ?elsepath) ; (E)
              (l/firsto ?elsepath ?false) ; E
              (l/fresh [?predval]
                       (evalbooltermo ?predicate ?predval)
                       (l/conde
                         [(l/== ?predval 'true)
                          (evalbooltermo ?then e)]
                         [(l/== ?predval 'false)
                          (evalbooltermo ?else e)])))]))
This code does work, but I just get the feeling that there's got to be a better way to do this. Can you destructure lists? I also have a booltermo constraint if it would be useful anywhere.

Patrick20:08:32

Figured it out. For future readers

(defn evalbooltermo [t e]
  (l/conde 
    [(l/== t 'true)
     (l/== e 'true)]
    [(l/== t 'false)
     (l/== e 'false)]
    [(l/fresh [?predicate ?predval ?thenpath ?elsepath]
              (l/== t `(~'if ~?predicate ~'then ~?thenpath ~'else ~?elsepath))
              (l/conde 
                [(l/== ?predval 'true)
                 (evalbooltermo ?thenpath e)]
                [(l/== ?predval 'false)
                 (evalbooltermo ?elsepath e)])
              (evalbooltermo ?predicate ?predval))]))
Is not exactly equivalent, but does the job!