racket datalog - datalog with negation? - racket

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.

Related

Exercise 1.3 SICP Error: Cannot evaluate expression in Racket

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.

racket datalog - is '>' supported?

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).

Racket - arguments for procedure how to get all

I need to write procedure for calculation of weighted sum in follow functionality:
((weighted-sum 1) 5)
5
((weighted-sum 1/2 1/2) 3 1)
2
etc..
So far I did only how to get parameters for procedure:
(define (weighted-sum x . xn) (cons x xs))
(weighted-sum 2 3)
> '(2 3)
How to get ((weighted-sum 2 3) X X) parameters?
Thank you.
Your question doesn't have one easy answer. It sounds like you're supposed to write a function that accepts a sequence of weights, and returns a function that accepts a sequence of weights, and sums the products of the weights and the sums (by the way, stating this yourself would have been really helpful...).
1) Is this your design, or someone else's? I would not design this function this way.
2) You can write functions that return functions in a bunch of different ways. E.g.:
;; these all do the same thing.
;; they all have the type (number -> (number -> number))
(define a (lambda (x) (lambda (y) (+ x y))))
(define ((a x) y) (+ x y))
(define (a x)
(define (b y) (+ x y))
b)
So weighted-sum takes a variable number of values as parameters (let's call them ws) , and returns a new procedures that, in its turn, takes a variable number of parameters (vs) and does the calculation.
In racket, the for/fold construct comes in handy:
(define (weighted-sum . ws)
(lambda vs
(for/fold ((res 0)) ((i (in-list ws))
(j (in-list vs)))
(+ res (* i j)))))
or even
(define ((weighted-sum . ws) . vs)
(for/fold ((res 0)) ((i (in-list ws))
(j (in-list vs)))
(+ res (* i j))))
Alternatively, using a more classic foldl returning a named inner procedure:
(define (weighted-sum . ws)
(define (sub . vs)
(foldl
(lambda (i j res) (+ res (* i j)))
0
ws
vs))
sub)
For any of those:
> ((weighted-sum 1) 5)
5
> ((weighted-sum 1/2 1/2) 3 1)
2

Common Lisp - Gentle introduction to symbolic computation: Excercise 4.4

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)

Deconstructing a recursive process - SICP

Consider the following definition:
(define foo
(lambda (x y)
(if (= x y)
0
(+ x (foo (+ x 1) y)))))
What is the test expression? (write the actual expression, not its value)
I would think it is just (if (= x y) but the MIT 6.001 On Line Tutor is not accepting that answer.
The test would be:
(= x y)
That's the expression that actually returns a boolean value, and the behaviour of the if conditional expression depends on it - if it's #t (or in general: any non-false value) the consequent part will be executed: 0. Only if it's #f the alternative part will be executed: (+ x (foo (+ x 1) y)).