how to can get values in facts in clips?
CLIPS> (assert(rule1 (read)))
4
==> f-1 (rule1 1)
I want the fact 1 is stored in a variable and do calculations.
In this example, I want to return a value of ' 4 '.
CLIPS> (watch facts)
CLIPS> (assert (rule1 (read)))
4
==> f-1 (rule1 4)
<Fact-1>
CLIPS>
(defrule double
(rule1 ?v)
=>
(printout t "Twice the value is " (* 2 ?v) crlf))
CLIPS> (agenda)
0 double: f-1
For a total of 1 activation.
CLIPS> (run)
Twice the value is 8
CLIPS>
Related
Write a function that takes two lists of numbers, numerators and denominators, and returns a list of fractions produced by dividing numerators by denominators. If one list is shorter than the other, assume that the corresponding numbers are all 1s. Don't worry about zeros in the denominators (it's ok if your function breaks when dividing by zero).
Input: (list 1 2 3) (list 1 3 5)
Output: (list 1/1 2/3 3/5)
You can solve it by recursion:
(define (r-map func l1 l2 (default-l1 1) (default-l2 1) (acc '()))
(cond ((and (null? l1) (null? l2)) (reverse acc))
((null? l1) (r-map func '() (cdr l2) default-l1 default-l2 (cons (func default-l1 (car l2)) acc)))
((null? l2) (r-map func (cdr l1) '() default-l1 default-l2 (cons (func (car l1) default-l2) acc)))
(else (r-map func (cdr l1) (cdr l2) default-l1 default-l2 (cons (func (car l1) (car l2)) acc)))))
The nice thing with this function is that you can change the default value for each list independently from each other.
Test it:
(define a '(1 2 3))
(define b '(4 5 6))
(define c '(10 20))
(define d '(40 50 60 70))
;; run all combinations of the four:
(let ((lists (list a b c d)))
(for*/list [(x lists)
(y lists)]
(list `(r-map ,x ,y ,default-l1 ,default-l2) '=> (r-map / x y))))
It returns:
Welcome to DrRacket, version 6.11 [3m].
Language: racket, with debugging; memory limit: 128 MB.
'(((r-map (1 2 3) (1 2 3) 1 1) => (1 1 1))
((r-map (1 2 3) (4 5 6) 1 1) => (1/4 2/5 1/2))
((r-map (1 2 3) (10 20) 1 1) => (1/10 1/10 3))
((r-map (1 2 3) (40 50 60 70) 1 1) => (1/40 1/25 1/20 1/70))
((r-map (4 5 6) (1 2 3) 1 1) => (4 2 1/2 2))
((r-map (4 5 6) (4 5 6) 1 1) => (1 1 1))
((r-map (4 5 6) (10 20) 1 1) => (2/5 1/4 6))
((r-map (4 5 6) (40 50 60 70) 1 1) => (1/10 1/10 1/10 1/70))
((r-map (10 20) (1 2 3) 1 1) => (10 10 1/3))
((r-map (10 20) (4 5 6) 1 1) => (2 1/2 4 1/6))
((r-map (10 20) (10 20) 1 1) => (1 1))
((r-map (10 20) (40 50 60 70) 1 1) => (1/4 2/5 1/60 1/70))
((r-map (40 50 60 70) (1 2 3) 1 1) => (40 25 20 70))
((r-map (40 50 60 70) (4 5 6) 1 1) => (10 10 10 70))
((r-map (40 50 60 70) (10 20) 1 1) => (4 2 1/2 60 70))
((r-map (40 50 60 70) (40 50 60 70) 1 1) => (1 1 1 1)))
Let's do this a bit more straightforwardly.
There are two simple cases:
Both lists are empty; the result is '()
Neither list is empty; cons the fraction of the cars onto the result of recursing.
Short-circuiting out the tricky cases:
(define (fractions ns ds)
(cond [(and (null? ns) (null? ds)) '()]
[(null? ns) 'only-denominators]
[(null? ds) 'only-numerators]
[else (cons (/ (car ns) (car ds)) (fractions (cdr ns) (cdr ds)))]))
Test:
> (fractions '() '())
'()
> (fractions '(1 2) '(4 5))
'(1/4 2/5)
> (fractions '(1 2 3) '(4 5))
'(1/4 2/5 . only-numerators)
> (fractions '(1 2) '(4 5 6))
'(1/4 2/5 . only-denominators)
If there are only numerators, the results are the same as those numerators, since x/1 is the same as x:
...
[(null? ds) ns]
...
And if there are only denominators, you divide 1 with each element.
This is easy with map:
...
[(null? ns) (map (lambda (d) (/ 1 d)) ds)]
...
In full:
(define (fractions ns ds)
(cond [(and (null? ns) (null? ds)) '()]
[(null? ns) (map (lambda (d) (/ 1 d)) ds)]
[(null? ds) ns]
[else (cons (/ (car ns) (car ds)) (fractions (cdr ns) (cdr ds)))]))
Test:
> (fractions '() '(4 5 6))
'(1/4 1/5 1/6)
> (fractions '(1 2 3) '())
'(1 2 3)
> (fractions '(1 2 3) '(4 5))
'(1/4 2/5 3)
> (fractions '(1 2) '(4 5 6))
'(1/4 2/5 1/6)
For simplicity, this is a toy version of the actual problem: given a set of integers, find the longest sequence of consecutive numbers from that set.
I looked at CLIPS and other expert systems, and they seem ill-suited to express this kind of problem. Specifically, I don't see a list like data structure, which seems to be necessary to implement a solution. I'm looking for an example of implementation using logic programming.
One way:
CLIPS (6.4 2/9/21)
CLIPS>
(deffacts start
(set 1 9 2 10 4 3 11 13 5 14))
CLIPS>
(defrule combine-1
?f <- (set $?b ?n $?e)
=>
(retract ?f)
(assert (combine ?n))
(assert (set ?b ?e)))
CLIPS>
(defrule combine-2
?f1 <- (combine $?b ?j1)
?f2 <- (combine ?j2&=(+ ?j1 1) $?e)
=>
(retract ?f1 ?f2)
(assert (combine ?b ?j1 ?j2 ?e)))
CLIPS>
(defrule longest
(declare (salience -10))
(combine $?c)
(not (combine $?o&:(> (length$ ?o) (length$ ?c))))
=>
(println "Longest is " ?c))
CLIPS> (reset)
CLIPS> (run)
Longest is (1 2 3 4 5)
CLIPS> (facts)
f-21 (set)
f-22 (combine 13 14)
f-26 (combine 1 2 3 4 5)
f-28 (combine 9 10 11)
For a total of 4 facts.
CLIPS>
Another way:
CLIPS> (clear)
CLIPS>
(deffacts start
(set 1 9 2 10 4 3 11 13 5 14))
CLIPS>
(defrule sort
?f <- (set $?s)
(test (neq ?s (sort > ?s)))
=>
(retract ?f)
(assert (set (sort > ?s))))
CLIPS>
(deffunction consecutive ($?s)
(loop-for-count (?i (- (length$ ?s) 1))
(if (<> (+ (nth$ ?i ?s) 1) (nth$ (+ ?i 1) ?s))
then (return FALSE)))
(return TRUE))
CLIPS>
(defrule longest
(set $? $?s&:(consecutive $?s) $?)
(not (set $? $?s2&~$?s&:(consecutive $?s2)&:(> (length$ ?s2) (length$ ?s)) $?))
=>
(println "Longest is " ?s))
CLIPS> (reset)
CLIPS> (run)
Longest is (1 2 3 4 5)
CLIPS> (facts)
f-2 (set 1 2 3 4 5 9 10 11 13 14)
For a total of 1 fact.
CLIPS>
I am using DrRacket.
How can I write a function for the difference between the maximum and minimum number in the list using accumulators and mutually recursive functions.
For instance, (list 10 2 3 -5 4 1 -6)) 9). The list has at least one element in the list.
Do I need two accumulators?
Version 1: An accumulator based solution that's mutually recursive. Since the input list is assumed to be non-empty, we start of with the first element being max and min. As we go through the list, we pick new max and mins by comparing the current element with the accumulators.
#lang racket
; [NEList-of Number] -> Number
(define (max-min-diff.v1 nelst)
(max-min-diff/t.v1 (rest nelst) (first nelst) (first nelst)))
; [List-of Number] -> Number
(define (max-min-diff/t.v1 l max min)
(cond [(empty? l) (- max min)]
[else (get-new-max-min (rest l) (first l) max min)]))
; [List-of Number] Number Number Number -> Number
(define (get-new-max-min rst fst max min)
(max-min-diff/t.v1 rst
(if (> fst max) fst max)
(if (< fst min) fst min)))
(max-min-diff.v1 '(0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v1'(1 3 9 4 7 2 2 5 11))
; => 10
Version 2: An accumulator based solution that's not mutually recursive. More abstract because we pass the comparators to a generic helper.
; [NEList-of Number] -> Number
(define (max-min-diff.v2 nelst)
(max-min-diff/t.v2 (rest nelst) (first nelst) (first nelst)))
; [List-of Number] -> Number
(define (max-min-diff/t.v2 l max min)
(cond [(empty? l) (- max min)]
[else (max-min-diff/t.v2 (rest l)
(f-if (first l) max >)
(f-if (first l) min <))]))
; X X [X X -> Boolean] -> X
(define (f-if n1 n2 func)
(if (func n1 n2) n1 n2))
(max-min-diff.v2 (list 0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v2 (list 1 3 9 4 7 2 2 5 11))
; => 10
Version 3: Small version. No explicit recursion.
(define (max-min-diff.v3 nelst)
(- (apply max nelst) (apply min nelst)))
(max-min-diff.v3 (list 0 33 2 32 4 8 3 3 5))
; => 33
(max-min-diff.v3 (list 1 3 9 4 7 2 2 5 11))
; => 10
I have two functions in my program. The one that is commented out mods every element in a list by five. And the second function counts how many times an element appears in a list. How do I combine both of these to get my desired result of determining how many elements of a list are divisible by five?
Here is my code:
(defun divide-bye-five (lst)
(loop for x in lst collect (mod x 5)))
(defun counter (a lst)
(cond ((null lst) 0)
((equal a (car lst)) (+ 1 (counter a (cdr lst))))
(t (counter a (cdr lst)))))
(counter '0 '(0 0 0 20 0 0 0 0 0 5 31))
If you need just select all elemets in list, which are dividable by five, you can use remove-if-not.
(defun dividable-by-5 (num)
(zerop (mod num 5))
CL-USER> (remove-if-not #'dividable-by-5 '(1 2 3 10 15 30 31 40))
(10 15 30 40)
But I'm not sure, do you want select this elements, or just count them? Of course you can count them by calling length on resulting list, or of you don't need all elements, but just a number, you can use count-if.
CL-USER> (count-if #'dividable-by-5 '(1 2 3 10 15 30 31 40))
4
If you have two functions where the result of one is what you would like as the input for the second you can combine them like this:
(second-fun (first-fun first-fun-arg ...))
So specifically using your provided functions it should work doing:
(counter 0 (divide-bye-five '(1 2 3 4 5 6 7 8 9 10))) ; ==> 2
If you'd like to abstract it you make it a function:
(defun count-dividable-with-five (lst)
(counter 0 (divide-bye-five lst)))
Is it possible to tell dolist to start at (or even better after) a certain element in the given list? As I may not want to evaluate all the elements before.
If there is no way to do so, is there any other macro which might do the job?
Considering this example:
(defvar *liste* #(1 2 3 4 5 6))
(dolist (x *liste* :start-after: '4)
(FORMAT t "~a~%" x))
resulting in:
5
6
Which Lisp dialect are we talking about?
Assuming Common Lisp.
#(1 2 3 4 5 6) is not a list. It is a vector.
CL-USER > (let ((v #(1 2 3 4 5 6)))
(loop for i from 4 below (length v)
do (print (aref v i))))
5
6
NIL
With a list:
CL-USER 1 > (mapc #'print (nthcdr 4 '(1 2 3 4 5 6)))
5
6
(5 6)
What's wrong with NTHCDR?
http://www.lispworks.com/documentation/HyperSpec/Body/f_nthcdr.htm#nthcdr