I am having difficulties in defining matching rules.
(defrule set-current
?desAct <- (Actuator (name 0) (StrokeLength ?sl) (Force ?f)
(nominalCurrent ?c3))
(test (eq ?c3 0)) ; I have defined this to change only if value is not
; set yet
?act <- (Actuator (inputVoltage ?v1) ; actuator that has matching slots
(StrokeLength ?sl1)
(nominalCurrent ?c1))
(test (eq ?sl1 ?sl)) ; for same stroke length I want to modify
; nominalCurrent of ?desAct
=>
(modify ?desAct (nominalCurrent ?c1))
)
?desAct represent the fact which slots values I want to change according to other existing facts based on some criteria.
I am not sure why this rule doesn't fire for following facts:
f-4 (MAIN::Actuator (name 4) (inputVoltage 12) (Force 17) (StrokeLength 10) (length 62) (width 18) (height 15.1) (motorType DC) (speedAtNomLoad 25) (weight 28) (nominalCurrent 0.46) (highTemp 50) (lowTemp -10) (price 90) (dutyCycle 20))
f-9 (MAIN::Actuator (name 0) (inputVoltage 12) (Force 17) (StrokeLength 10) (length 10) (width 10) (height 10) (motorType DC) (speedAtNomLoad 0) (weight 0) (nominalCurrent 0) (highTemp 0) (lowTemp 0) (price 0) (dutyCycle 0))
I am expecting that Actuator with name 0 with this rule has nominalCurrent same as f-4, but rule doesn't fire.
The rule does fire but more than once. If you have facts of the same template, make sure to avoid multiple matches of 1 or 2 facts.
(defrule set-current
?act1 <- (Actuator (name ?n1)
(inputVoltage ?v1)
(StrokeLength ?sl1)
(nominalCurrent ?c1&0))
?act2 <- (Actuator (name ?n2&~?n1) ; avoid redundant matches
(inputVoltage ?v1) ; same input voltage
(StrokeLength ?sl1) ; same stroke length
(nominalCurrent ?c2)) ; bind current
=>
(printout t "modify actuator " ?n1 " current=" ?c2 crlf)
(modify ?act1 (nominalCurrent ?c2))
)
The constraint (name ?n2&~?n1) forces matches to occur between Actuators with different name values. Reusing a bound variable forces a match with a slot of that value.
Don't use test. Be more consistent with the names for binding variables.
Related
I have my string in clsp format : "(a (q 2 (i (= (sha256 11) 5) (q 4 (c 2 (c 23 (c 47 ()))) ()) (q 8 (q . 'Bad password'))) 1) (c (q . 51) 1))"
When I entered it on this website conversion,(https://pawket.app/#/) in clvm section.
Result (Translated): ff02ffff01ff02ffff03ffff09ffff0bff0b80ff0580ffff01ff04ffff04ff02ffff04ff17ffff04ff2fff80808080ff8080ffff01ff08ffff018c4261642070617373776f72648080ff0180ffff04ffff0133ff018080
Could you help me to find the conversion algorithm? I have tried to get the byte format, but it didn't succed.
I have to make a rule who choose the best phone line rate between 3 of them. The rates have different packs, such to have TV or a better Internet Connection.
When a clients want to upgrade it, it starts a petition with the internet connection it wants and if it wants TV.
The system has to choose the minimum rate there is avalible for the petition, namely, it couldn't choose a higher rate if there is a lower one who satisfies the conditions.
Is it possible to do it using only one rule? What I have right now choose always the highest rate, because for some reason it always have a higher preference.
(defrule cambio-tarifa
?dirPeticion <- ( peticion ( id_cliente ?id_cliente ) ( fibra ?fibra_minima ) ( TV ?TV_Peticion ) )
?dirCliente <- ( cliente ( id ?id_cliente ) ( plan ?plan_actual ) )
( plan ( nombre ?plan_nuevo ) ( precio ?precio_plan ) ( fibra ?fibra ) ( TV ?TV_Plan ) )
( plan ( nombre ?plan_actual ) ( precio ?precio_actual ) )
( test ( > ?precio_plan ?precio_actual ) )
( test ( >= ?fibra ?fibra_minima ) )
=>
( modify ?dirCliente ( plan ?plan_nuevo ) )
( retract ?dirPeticion )
)
This is the general pattern for a rule which selects the lowest/highest value:
CLIPS>
(deftemplate plan
(slot id)
(slot price))
CLIPS>
(deffacts plans
(plan (id A) (price 100))
(plan (id B) (price 90))
(plan (id C) (price 200))
(plan (id D) (price 150)))
CLIPS>
(defrule lowest
(plan (id ?id) (price ?price))
(not (plan (price ?price2&:(< ?price2 ?price))))
=>
(printout t "Plan " ?id " has the lowest price: " ?price crlf))
CLIPS> (reset)
CLIPS> (run)
Plan B has the lowest price: 90
CLIPS>
In elisp to replace an occurrence of a string in a buffer I would do
(search-forward "aaa" nil 't)
(replace-match "bbb")
If between the search and the replace I modify the buffer, the following seems to happen:
(match-end 1) <- (min (point-max) (match-end 1))
(match-beginning 1) <- (min (match-beginning 1) (match-end 1))
Moreover if (match-end 1)==(match-beginning 1) replace-match calls insert at (match-end 1) (both of which gets updated to point to the end of the inserted string) whereas if (match-end 1)>(match-beginning 1) replace-match updates the string between (match-beginning 1) and (match-end 1) (and they get updated to point to the beginning and end of the inserted string)
So the second question is why the different behaviours?
I am learning how to use structures with MIT-scheme and am trying to "translate" the following function from C to scheme:
static inline void
body_integrate(struct body *body, double dt)
{
body->vx += dt * body->fx / body->mass;
body->vy += dt * body->fy / body->mass;
body->rx += dt * body->vx;
body->ry += dt * body->vy;
}
With the following definitions
(define-structure body rx ry vx vy fx fy mass)
(define integrate (lambda (body dt) (
(set-body-vx! body (+ (body-vx body) (* dt (/ (body-fx body) (body-mass body)))))
(set-body-vy! body (+ (body-vy body) (* dt (/ (body-fy body) (body-mass body)))))
(set-body-rx! body (+ (body-rx body) (* dt (body-vx body))))
(set-body-ry! body (+ (body-ry body) (* dt (body-vy body))))
)))
I get:
MIT/GNU Scheme running under GNU/Linux
Type `^C' (control-C) followed by `H' to obtain information about interrupts.
Copyright (C) 2011 Massachusetts Institute of Technology
This is free software; see the source for copying conditions. There is NO warranty; not even for
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Image saved on Thursday November 5, 2015 at 8:44:48 PM
Release 9.1.1 || Microcode 15.3 || Runtime 15.7 || SF 4.41 || LIAR/x86-64 4.118 || Edwin 3.116
;Loading "body.ss"... done
1 ]=> (define b (make-body 1.0 1.0 2.0 2.0 10.0 10.0 0.1))
;Value: b
1 ]=> (integrate b 5.0)
;The object #!unspecific is not applicable.
;To continue, call RESTART with an option number:
; (RESTART 2) => Specify a procedure to use in its place.
; (RESTART 1) => Return to read-eval-print level 1.
2 error>
I have the feeling I can't do multiple (set-body-X! ...) inside integrate. But then how should I proceed to do this?
The opening parentheses right at the end of the first line is incorrect, in Scheme when you surround an expression with () it's treated as a function application, and that's not what you want here.
Anyway, it'd be more idiomatic to create a new structure with the new values, instead of modifying a parameter - remember, Scheme encourages a functional programming style, and you should avoid mutating values; besides modifying a parameter is considered bad style in most programming languages (that's ok in C, though). Try this:
(define (integrate body dt)
(make-body (+ (body-rx body) (* dt (body-vx body)))
(+ (body-ry body) (* dt (body-vy body)))
(+ (body-vx body) (* dt (/ (body-fx body) (body-mass body))))
(+ (body-vy body) (* dt (/ (body-fy body) (body-mass body))))
(body-fx body)
(body-fy body)
(body-mass body)))
**UPDATED with a better example
Let's have two statements
(value > 15)
(value > 25)
And a list of items with the following values
10
20
30
This is what a truth table would give
Item Value (value > 15) (value > 25)
---- ----- ------------ ------------
1 10 FALSE FALSE
2 20 TRUE FALSE
3 30 TRUE TRUE
Example 1
Where ALL of the following are TRUE
value > 15
value > 25
This one is easy and we get the following
Where (value > 15) AND (value > 25)
The result is then a single value of 30
Example 2
Where NONE of the following are TRUE
value > 15
value > 25
This is where I am not sure of what to generate.
This would be "simple" as it is only a NOT of the whole expression
Where NOT ((value > 15) AND (value > 25))
However, the result is then two values (10 and 20)
From what someone would think of NONE of the two statements would be something like:
Where NOT ((value > 15) OR (value > 25))
And the result would be that 10 is returned.
What is the correct meaning of NONE here?
None in this instance means NOT on both of the instances, AND'd together.
Where NOT(value > 15) AND NOT (value > 25)
Using Demorgan's Law, we can extract the NOT to mean:
Where NOT ((value > 15) OR (value > 25))
Which is the second statement in your Example 2.
You can represent "none of (a, b, etc) is true" by either
(NOT a) AND (NOT b) AND (NOT etc)
or
NOT (a OR b OR etc)
Either will work.
In your case, you could say NOT ((value > 15) OR (value > 25)). Only 10 matches.