Search code examples
schemeracketlogic-programming

Zero of a quadratic function using Racket's logic paradigm


First of all, I want to apologize for the following question. I am a total noob with Racket, but I was quite interested after I have learned about its logic programming feature. Sadly there is only a single tutorial for the embedded racklog-language in the entire internet and it is not all that helpful for my case.

So what I was trying to do... well, I had coded this neat little Prolog exercise to solve a quadratic function by just inserting P and Q:

zero(P, Q) :-
    D is (P/2)*(P/2) - Q,
(   D < 0,
        write('No Zero'), nl;
    D = 0,
        X is -(P/2), write('x= '), write(X), nl;
    D > 0,
        X1 is -(P/2) + sqrt(D), write('x1= '), write(X1), nl,
        X2 is -(P/2) - sqrt(D), write('x1= '), write(X2), n).

Now I tried to rewrite exactly the same program in Racket. I have yet to care about the output, but it would certainly help if it just works at first.

#lang racket
(require racklog)

(define (%zero P Q)
    (define (D ((P/2)*(P/2) - Q))
        (cond
          [(< D 0) (error "No Zero")]
          [(= D 0) (-(P/2))]
          [(> D 0) (-(P/2) + sqrt(D)) (-(P/2) - sqrt(D))]
        )
     )
)

But instead I just get an error pointing at line 5: "define: not an identifier, identifier with default, or key procedure arg" I'm pretty sure that's just the first of many errors, because there must be a gross misunderstanding of mine regarding Racket's syntax. But with what I've got, I'm pretty much at a loss at the moment. I would appreciate some hints to what I did wrong. Sincerely, Dschehuti-Nefer


Solution

  • I don't know racklog, but transposed to Scheme's prefix notation it should be something like this:

    (define (%zero P Q)
      (define D (- (* (/ P 2) (/ P 2)) Q))
      (cond
        [(< D 0) (error "No Zero")]
        [(= D 0) (- (/ P 2))]
        [(> D 0) (values (+ (- (/ P 2)) (sqrt D))
                         (- (- (/ P 2)) (sqrt D)))]))
    

    Not that I would recommend it, but Racket also has a type of infix notation that you could use:

    (define (%zero P Q)
      (define D (((P . / . 2) . * . (P . / . 2)) . - . Q))
      (cond
        [(< D 0) (error "No Zero")]
        [(= D 0) (- (P . / . 2))]
        [(> D 0) (values ((- (P . / . 2)) . + . (sqrt D))
                         ((- (P . / . 2)) . - . (sqrt D)))]))