; (q X) -> q(X) ; (q :x) -> q(x) ; (q #(+ 1 2)) -> q(3) (fn clause [c] (match c (where [:hashfn expr] (list? c)) `[:const ,expr] (where [name & params] (list? c)) `[:literal ,(tostring name) ,(icollect [_ param (ipairs params)] (clause param))] (where v (sym? c)) `[:var ,(tostring v)] _ `[:const ,c])) (fn clauses [...] (icollect [_ c (ipairs [...]) :into `(values)] (clause c))) (fn defrule [s ...] `(: ,s :defrule ,(clauses ...))) (fn defrules [s ...] (icollect [_ rule (ipairs [...]) :into `(do)] (defrule s (table.unpack rule)))) (fn query [s ...] `(: ,s :query ,(clauses ...))) {: clause : clauses :$ clauses : defrule : defrules : query}