Suppose racket's datalog code:
#lang datalog
price(a, 1).
a1(A) :- price(A, Price), Price > 0.
a1(A)?
I would expect result:
a1(a)
I receive an error:
prices_datalog.rkt:4:32: datalog: Unexpected token IDENTIFIER in: ">"
How can I solve this problem?
it looks like it is not directly supported. But you can define your own operator.
#lang datalog/sexp
(! (:- (gt X Y)
(> X Y :- #t)))
(! (price a 1))
(! (price b 2))
(! (price c 3))
(! (price d 4))
(! (:- (a2 X)
(price X Y)
(gt Y 2)))
(? (a2 X))
;; outputs
a2(c).
a2(d).
Related
I am doing Exercise 1.3 from SICP.
My code is the following:
#lang racket
(require sicp)
(define (square a)
(* a a)
)
(define (sum-of-squares a b)
(+ (square a) (square b) )
)
(define (max a b)
(cond ((>= a b) a)
(else b)
)
)
(define (sum-of-biggest-squares a b c )
(cond ((>= a b)
(sum-of-squares a (max b c) )
(sum-of-squares b (max a c) )
)
)
)
(sum-of-biggest-squares 5 7 10)
Surprisingly, the Racket interpreter does
not print any result for the above. The interpreter
works fine for other values. But for
this set of three values its not
working.
When I try to add an else statement
like the following:
(else (sum-of-squares b (max a c) ) )
The interpreter says:
exercise_1-3.rkt:23:10: else: not allowed as an expression
in: (else (sum-of-squares b (max a c)))
You have a couple of syntax errors in function sum-of-biggest-squares: a parenthesis should be added to close the first cond clause, and else should be added to the second one:
(define (sum-of-biggest-squares a b c)
(cond ((>= a b) (sum-of-squares a (max b c)))
(else (sum-of-squares b (max a c)))))
Note that the way in which you format the code, so different from the current common conventions, makes very difficult to read it and easy to introduce syntax errors.
Does racket's datalog (https://docs.racket-lang.org/datalog) support 'datalog with negation' ?
This is the best I was able to come up with:
#lang racket
(require datalog)
(define prices (make-theory))
(datalog prices
(! (price a 1))
(! (price b 2))
(! (price c 3))
(! (price d -5))
(! (price e 5))
)
(define (notgt x y)
(not (> x y)
))
(datalog prices
(! (:- (notgt X Y)
(notgt X Y :- #t))
))
(datalog prices
(! (:- (al2 X)
(price X Y)
(notgt Y 2)
)))
(datalog prices (? (al2 X)))
Problem is that predicates must all return true and cannot be complex, so you cannto write there something like (not (= Y 2)). And it looks like negation is not in racket's datalog, but I am not expert on this matter. There is also another datalog implementation in racket: https://github.com/rntz/datafun But I have no idea if that is any better.
How to write a macro "MAXF" : find max value in a parameter list , then call a specific function? e.g.
(defun func (x y z) (format t "~A ~A ~A~%" x y z))
(let ((a 1) (b 1))
(maxf ((+ a b 1) (func a b 1)) ((+ a b 2) (func a b 2))... ((+ a b 100)
(func a b 100)) )
The result should be: "1 1 100"
I am learning Common Lisp using clisp and have entered following code:
(defun ordered (x y)
(if (< x y)
(list x y)
(list y x)))
(setq l (ordered 28 49))
(print l)
(setq l (ordered 49 28))
(print l)
Expected these answers:
(28 49)
(49 28)
Got these answers:
(28 49)
(28 49)
In the solutions of this book I have found the same function definition.
What could be wrong?
Your code
(defun
defines a function,
ordered
named "ordered",
(x y)
that expects two arguments which will be known as "x" and "y" in its body, whereupon on receiving the arguments (i.e. having been called with two values, e.g. (ordered 49 28))
(if (< x y)
it will compare them, and in case the first was smaller than the second, it will produce
(list x y)
the same two values repackaged in a list (i.e. '(49 28)); or otherwise, if the first value was not smaller than the second,
(list y x)))
it will produce the list containing the second value first, and then the first argument value (i.e. '(28 49)).
So, which was the case here, of comparing the 49 and 28?
Reading this code generally, we can say that if it receives the smaller number as its first argument, it will produce the smaller number first and the bigger number second, in the result list;
and in case it receives the smaller number as its second argument, it will produce the smaller number first and the bigger number second, in the result list.
Reading this back, we can see that this description can be simplified further into one simple statement: it will always produce ______ number first, and ______ second, in the resulting list.
Another way to attack this, is to write down the function created by that definition,
( lambda (x y) (if (< x y) (list x y) (list y x) ) )
Then follow its application symbolically:
( ( lambda (x y) (if (< x y) (list x y) (list y x) ) )
49
28 )
==
(let ( (x 49)
(y 28)
)
(if (< x y) (list x y) (list y x) ) )
==
(let ( (x 49)
(y 28)
)
(if (< 49 28) (list x y) (list y x) ) )
==
(let ( (x 49)
(y 28)
)
(if FALSE (list x y) (list y x) ) )
==
(let ( (x 49)
(y 28)
)
(list y x) )
==
(let ( (x 49)
(y 28)
)
(list 28 49) )
==
(list 28 49)
I'm trying to return (values str ((+ x 3) y)) from the function it resides in.
code snippet:
(if (<my condition>)
(values str ((+ x 3) y))
(values str ((+ x 2) y)))
gives error:
(+ X 3) SHOULD BE A LAMBDA EXPRESSION
but (values str (y (+ x 3))) works fine.
why?
The S-expression ((+ x 3) y) cannot be evaluated because the first list element is not funcallable (it should name a function or be a lambda expression).
So, to avoid evaluation, you need to quote it:
(if (<my condition>)
(values str '((+ x 3) y))
(values str '((+ x 2) y)))
Then you will return a list of length 2 (containing a list of length 3 and a symbol y) as your second value. If, however, you want to return the values of (+ x 2) and y in the list, you will want to do something like
(values str (list (+ x (if <condition> 3 2)) y))
or maybe return 3 values instead of 2:
(values str
(+ x (if <condition> 3 2))
y)
On the other hand, y is a symbol, which, apparently, names a function in your image, so (y (+ x 3)) evaluates fine (it calls function y on the result of adding 3 to x).