Generating truth table in CLIPS - clips

The problem is how to obtain alike binary truth table in CLIPS.
Suppose an ordered initial fact like:
(vector -1 -1 -1)
The expected result will be something like:
(vector 0 0 0 0)
(vector 0 0 0 1)
(vector 0 0 1 0)
(vector 0 0 1 1)
(vector 0 1 0 0)
(vector 0 1 0 1)
(vector 0 1 1 0)
(vector 0 1 1 1)
(vector 1 0 0 0)
The question is: how do I proceed to obtain this result ?

It's not clear what you're trying to do (e.g. what's the purpose of the vector fact containing three negative ones), but if you're just trying to generate permutations you can do something like this:
CLIPS (6.31 6/12/19)
CLIPS>
(defrule generate
(values $? ?v1 $?)
(values $? ?v2 $?)
(values $? ?v3 $?)
(values $? ?v4 $?)
=>
(assert (vector ?v1 ?v2 ?v3 ?v4)))
CLIPS> (assert (values 0 1))
<Fact-1>
CLIPS> (run)
CLIPS> (facts)
f-0 (initial-fact)
f-1 (values 0 1)
f-2 (vector 0 0 0 0)
f-3 (vector 0 0 0 1)
f-4 (vector 0 0 1 0)
f-5 (vector 0 0 1 1)
f-6 (vector 0 1 0 0)
f-7 (vector 0 1 0 1)
f-8 (vector 0 1 1 0)
f-9 (vector 0 1 1 1)
f-10 (vector 1 0 0 0)
f-11 (vector 1 0 0 1)
f-12 (vector 1 0 1 0)
f-13 (vector 1 0 1 1)
f-14 (vector 1 1 0 0)
f-15 (vector 1 1 0 1)
f-16 (vector 1 1 1 0)
f-17 (vector 1 1 1 1)
For a total of 18 facts.
CLIPS>

Thank you Mr. Riley.
If I may, here is a summary explanation of what the program do. The purpose of the problem is to obtain a combination of the states of certain protective devices in an electrical power system network. In fact, the -1 in ordred vector fact correspond to the unknown status of some switching devices after a blackout, and the objective is to combine in a binary decision tree all the possible states for the switches (0: open state, 1 closed state) in order to obtain a sequence satisfying certain conditions, such as a non-radial network structure.
Therefore, not every combination of the vector fact is a solution to the problem, and an optimal solution has yet to be identified.
God bless you, Mr. Riley, for helping others.

Related

Why does this not generate a matrix in racket?

I would like to generate a matrix (perhaps with numbers from a process, used 0 for simplification as below) in racket. I tried
(array (for/vector ((x (range 4)))
(for/vector ((y (range 4)))
0)))
which gives
(array '#(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0) #(0 0 0 0)))
Silly enough though,
(matrix? (array (for/vector ((x (range 4)))
(for/vector ((y (range 4)))
0))))
gives #f, and so does (array '#(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0) #(0 0 0 0))). Yet
> (matrix? (array #(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0) #(0 0 0 0))))
#t
So what's going wrong with it?
EDIT: the matrix module is imported from math/array and math/matrix.
The array special form defines a new syntax, according to the docs it expects "nested rows of expressions" as its argument, which is not the same as a vector. For example:
(require math/array)
(require math/matrix)
(array #[#[1]])
=> (array #[#[1]])
(matrix? (array #[#[1]]))
=> #t
(array (vector (vector 1)))
; notice the difference, there's a quote and the brackets are not square
=> (array '#(#(1)))
(matrix? (array (vector (vector 1))))
=> #f
To summarize: you can't use a vector of vectors as a substitute for the special syntax that array requires as its argument. And it's not just a matter of removing the quote and using square brackets, they're objects of different types even though they look similar when printed.
array is some special magic thing which I don't understand but its body is not a general-purpose expression at all. If you want to make an array programmatically you want something like build-array or vector*->array:
(define nvs (for/vector ((x (range 4)))
(for/vector ((y (range 4)))
0)))
(define a (vector*->array nvs number?))

Matching two vectors with same elements but not ordered the same

I'm trying to write a general rule that will activate when two facts like these two are present:
(Vector v1 3 4 5)
(Vector v2 1 3 10 15 5 2 4)
(Elements 4 5 3)
So, my problem is that I don't know how to match ALL the unordered elements in the vector, in order to fire the rule.
I want the rule to activate only when ALL the elements from Elements are present, not taking in consideration if they follow the same order.
I haven't been able to achieve it, so I ask for help.
Examples of rules not doing what I want:
(defrule Equal
(Elements $?x)
(Vector ?name $?y)
(test (member$ $?x $?y))
=>
(printout t ?name crlf)
)
*The problem of this one is that it fires when both are blank, and mainly when a single member of ?x is contained in ?y, but I want the rule to fire when ALL elements in ?x are in ?y.
I tried using this simplier one too:
(defrule Equal
(Elements $? $?x $?)
(Vector ?name $? $?y $?)
=>
(printout t ?name crlf)
)
But in this case the rule only activates when the elements are exactly the same and ordered in the same way, but I want to have the flexibility of elements not having to be ordered exactly as they appear in the vector.
Use the subsetp function rather than member$:
CLIPS (6.31 4/1/19)
CLIPS>
(defrule equal
(elements $?elements)
(test (> (length$ ?elements) 0))
(vector ?name $?values)
(test (subsetp ?elements ?values))
=>
(printout t ?name crlf))
CLIPS>
(assert (vector v1 3 4 5)
(vector v2 1 3 10 15 5 2 4)
(vector v3 4 5 7 2)
(elements 4 5 3))
<Fact-4>
CLIPS>
(agenda)
0 equal: f-4,f-2
0 equal: f-4,f-1
For a total of 2 activations.
CLIPS> (run)
v2
v1
CLIPS>
You can also do it this way without a function call:
CLIPS> (clear)
CLIPS>
(defrule equal
(elements ? $?)
(vector ?name $?list)
(forall (elements $? ?v $?)
(vector ?name $? ?v $?))
=>
(printout t ?name crlf))
CLIPS>
(assert (vector v1 3 4 5)
(vector v2 1 3 10 15 5 2 4)
(vector v3 4 5 7 2)
(elements 4 5 3))
<Fact-4>
CLIPS> (agenda)
0 equal: f-4,f-2,*
0 equal: f-4,f-1,*
For a total of 2 activations.
CLIPS> (run)
v2
v1
CLIPS>

Set Individual Elements of Multidimensional Vectors in Racket

For a university project i have to make a game based in a matrix in the pretty big language, the matrix is being defined as a multidimensional vector.
I need to set a single element of the matrix, my code is:
(require racket/vector)
(define test (make-vector 4 (make-vector 4 0)))
(define (matrix-set matrix row column value)
(vector-set! (vector-ref matrix row) column value)
)
(display test)(newline)
(matrix-set test 0 0 1)
(display test)
And outputs this:
#(#(0 0 0 0) #(0 0 0 0) #(0 0 0 0) #(0 0 0 0))
#(#(1 0 0 0) #(1 0 0 0) #(1 0 0 0) #(1 0 0 0))
I have searched the racket documentation and only found functions that set an element by making a new matrix, this and this questions too.
Why is the function setting the whole column instead of only the element?
What can be done to resolve it?
(make-vector 4 (make-vector 4 0)) is the same as:
(let ((x (make-vector 4 0)))
(vector x x x x))
That is, (make-vector 4 0) is called only once, and its value is used for all 4 slots of the outer vector.
What you need is something like (for/vector ((i 4)) (make-vector 4 0)), which will call (make-vector 4 0) (and create a distinct vector) for each element of the outer vector.
An alternative approach is to use the vector generating iterator for/vector. I'm not sure the syntax is any cleaner than using thunks, but conceptually, I feel it is more familiar and perhaps simpler.
(define test (for/vector ([i (range 4)])(make-vector 4 0)))
(matrix-set test 0 0 1) ; '#(#(1 0 0 0) #(0 0 0 0) #(0 0 0 0) #(0 0 0 0))
A third alternative, that isn't as Racket like, would be using do.
(define test
(do ((vec (make-vector 4))
(i 0 (+ i 1)))
((= i 4) vec)
(vector-set! vec i (make-vector 4 0))))
On the other hand, sometimes it's worth knowing a bit about do because do don't require memorizing a different command for each type since do does what it does on vectors, lists, and hashes.

Define a Scheme procedure (bitAdder x a b) to simulate the logic design

Define a Scheme procedure (bitAdder x a b) to simulate the logic design given in following the diagram in Figure 2. The procedure must call the gate procedures that you defined in Question 1 and must return a pair with two elements '(s . c), where s is the binary sum of a, b, and x, while c is the carry-out. You will implement the procedure in three steps using three procedures, as listed below.
Write a procedure (sum-bit x a b) to generate the result bit s.
Write a procedure (carry-out x a b) to generate the carry-out bit c.
Write a procedure (bitAdder x a b) to generate the pair out put (s . c).
So far I have defined my logic gates for "and", "or" , and "xor". I tried to do the first two procedures but they seem incorrect.
(define AND-gate (lambda (a b)
(if (= a b 1)
1
0)))
(define OR-gate (lambda (a b)
(if (= a 1)
1
(if (= b 1)
1
0))))
(define XOR-gate (lambda (a b)
(if (= a b)
0
1)))
(define sum-bit (lambda (x a b)
(XOR-gate a b)
(XOR-gate x (XOR-gate a b))))
(define carry-out (lambda (x a b)
(OR-gate a b)
(AND-gate (OR-gate a b) x)
(AND-gate a b)
(OR-gate (AND-gate a b) (AND-gate (OR-gate a b) x))))
Define the Gates
#lang racket
(define (AND-gate A B)
(if (= A B 1)
1
0))
(define (XOR-gate A B)
(if (not (= A B))
1
0))
(define (OR-gate A B)
(if (not (= 0 (+ A B)))
1
0))
Test the Gates
(module+ test
(require rackunit
rackunit/text-ui)
(define-test-suite
gate-tests
(test-equal? "AND-gate" (AND-gate 1 1) 1)
(test-equal? "XOR-gate" (XOR-gate 0 1) 1)
(test-equal? "XOR-gate" (XOR-gate 1 0) 1)
(test-equal? "XOR-gate" (XOR-gate 0 0) 0)
(test-equal? "XOR-gate" (XOR-gate 1 1) 0)
(test-equal? "AND-gate" (AND-gate 0 0) 0)
(test-equal? "AND-gate" (AND-gate 0 1) 0)
(test-equal? "AND-gate" (AND-gate 1 0) 0)
(test-equal? "OR-gate" (OR-gate 0 0) 0)
(test-equal? "OR-gate" (OR-gate 1 0) 1)
(test-equal? "OR-gate" (OR-gate 0 1) 1)
(test-equal? "OR-gate" (OR-gate 1 1) 1))
(run-tests gate-tests))
Define Sum-Bit
(define (sum-bit X A B)
(XOR-gate X (XOR-gate A B)))
Test Sum-Bit
(module+ test
(define-test-suite
sum-bit-tests
(test-equal? "Sum-bit" (sum-bit 0 0 0) 0)
(test-equal? "Sum-bit" (sum-bit 1 0 0) 1)
(test-equal? "Sum-bit" (sum-bit 0 1 0) 1)
(test-equal? "Sum-bit" (sum-bit 0 0 1) 1)
(test-equal? "Sum-bit" (sum-bit 1 1 0) 0)
(test-equal? "Sum-bit" (sum-bit 1 0 1) 0)
(test-equal? "Sum-bit" (sum-bit 0 1 1) 0)
(test-equal? "Sum-bit" (sum-bit 1 1 1) 1))
(run-tests sum-bit-tests))
Define Carry-Bit
(define (carry-bit X A B)
(OR-gate (AND-gate A B)
(OR-gate (AND-gate X A)
(AND-gate X B))))
Test Carry-Bit
(module+ test
(define-test-suite
carry-bit-tests
(test-equal? "Carry-bit" (carry-bit 0 0 0) 0)
(test-equal? "Carry-bit" (carry-bit 1 0 0) 0)
(test-equal? "Carry-bit" (carry-bit 0 1 0) 0)
(test-equal? "Carry-bit" (carry-bit 0 0 1) 0)
(test-equal? "Carry-bit" (carry-bit 1 1 0) 1)
(test-equal? "Carry-bit" (carry-bit 1 0 1) 1)
(test-equal? "Carry-bit" (carry-bit 0 1 1) 1)
(test-equal? "Carry-bit" (carry-bit 1 1 1) 1))
(run-tests carry-bit-tests))
Define Bit-Adder
(define (bit-adder X A B)
(cons (sum-bit X A B)
(carry-bit X A B)))
Test Bit-Adder
(module+ test
(define-test-suite
bit-adder-tests
(test-equal? "Bit-adder" (bit-adder 0 0 0) '(0 . 0))
(test-equal? "Bit-adder" (bit-adder 1 0 0) '(1 . 0))
(test-equal? "Bit-adder" (bit-adder 0 1 0) '(1 . 0))
(test-equal? "Bit-adder" (bit-adder 0 0 1) '(1 . 0))
(test-equal? "Bit-adder" (bit-adder 1 1 0) '(0 . 1))
(test-equal? "Bit-adder" (bit-adder 1 0 1) '(0 . 1))
(test-equal? "Bit-adder" (bit-adder 0 1 1) '(0 . 1))
(test-equal? "Bit-adder" (bit-adder 1 1 1) '(1 . 1)))
(run-tests bit-adder-tests))
Run the Tests
racket#297774346.rkt> ,enter "/home/ben/StackOverflow/297774346.rkt"
12 success(es) 0 failure(s) 0 error(s) 12 test(s) run
0
8 success(es) 0 failure(s) 0 error(s) 8 test(s) run
0
8 success(es) 0 failure(s) 0 error(s) 8 test(s) run
0
8 success(es) 0 failure(s) 0 error(s) 8 test(s) run
0
Turn in Homework
Subject to academic policies regarding the work of others.

SICP exercise 1.10: Scheme evaluation of Ackermann's function

I'm working through Structure and Interpretation of Computer Programs and have a question concerning exercise 1.10, which, using Ackermann's function defined as
(define (A x y)
(cond ((= y 0) 0)
((= x 0) (* 2 y))
((= y 1) 2)
(else (A (- x 1)
(A x (- y 1))))))
determine the value of the expression (A 1 10).
Now, I know the answer should be (A 1 10) = 2^10 = 1024, but when working through the computation, I get the following:
(A 1 10)
(A (- 1 1) (A 1 (- 10 1)))
(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
...
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0(A 0 (A 0 (A 0(A 0 (A 0 (A 0 ( A 0 0)))))))))))))
Now, the way I understood it, Scheme will start by evaluating the deepest expressions first, i.e. the (A 0 0) on the far right. This has the value 0, as the first condition of the function is met with (= y 0). The same happens for the next step and we end up reducing all brackets until we end up with the last (A 0 0) which will also have the value 0 for analogous reasons. Now, I get that the last line should be something like
(*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (*2 (A 0 0)))))))))))))
So, if all of this is correct, why does the last (A 0 0) yield 2 instead of 0? Or, more generally, can you spot where the error in my reasoning is? I'm pretty sure it either has something do to with the evaluation procedure of recursive calls OR with how conditional statements are evaluated.
Solved: As noted by leppie the (= y 1) gets evaluated first, getting 2 as value for (A 0 1) before getting to (A 0 0)
You never get all the way to
(A 0 0)
The expansion proceeds
(A 0 (A 1 9))
(A 0 (A 0 (A 1 8)))
(A 0 (A 0 (A 0 (A 1 7))))
...
(A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 0 (A 1 1))))))))))
and now the (A 1 1) is evaluated to 2.

Resources