I defined a class with a restricted options for a slot:
(defclass TARGET (is-a USER)
(slot uuid
(type STRING))
(slot function
(type SYMBOL)
(allowed-symbols a1 a2 b c d e f g))
)
(make-instance target of TARGET
(uuid "a123")
(function zzz)
)
I expected CLIPS to complain for the "zzz" (not allowed), but it didn't. Why?
Best regards.
Nicola
Constraint checking is done statically (during parsing) and dynamically (during execution). By default, only static constraint checking is enabled. Slot assignments for instances are done dynamically when messages passing is invoked because it's possible for an illegal value to be replaced with a legal value during execution of a message handler.
In the following case, the definstances does not generate an error when it is defined because the invalid value could be replaced at run time, but the defrule does generate an error because object patterns directly grab the value of a slot without using message passing.
CLIPS> (clear)
CLIPS>
(defclass TARGET (is-a USER)
(slot uuid
(type STRING))
(slot function
(type SYMBOL)
(allowed-symbols a1 a2 b c d e f g)))
CLIPS>
(definstances static
(target1 of TARGET (uuid "a123") (function zzz)))
CLIPS>
(defrule static
(object (is-a TARGET) (function zzz))
=>)
[CSTRNCHK1] A literal restriction value found in CE #1
does not match the allowed values for slot function.
ERROR:
(defrule MAIN::static
(object (is-a TARGET)
(function zzz))
=>)
CLIPS> (reset)
CLIPS>
(make-instance target2 of TARGET
(uuid "b456")
(function zzz))
[target2]
CLIPS>
If you enable dynamic constraint checking, you'll see errors during execution when the instances are actually created:
CLIPS> (set-dynamic-constraint-checking TRUE)
FALSE
CLIPS>
(make-instance target3 of TARGET
(uuid "c789")
(function zzz))
[CSTRNCHK1] zzz for slot function of instance [target3] found in put-function primary in class TARGET
does not match the allowed values.
[PRCCODE4] Execution halted during the actions of message-handler put-function primary in class TARGET
FALSE
CLIPS> (reset)
[CSTRNCHK1] zzz for slot function of instance [target1] found in put-function primary in class TARGET
does not match the allowed values.
[PRCCODE4] Execution halted during the actions of message-handler put-function primary in class TARGET
CLIPS>
Related
I have two int values in Dart, test them equals or not with == previously, it was fine. Now I have to test if first one is greater or equals to the second one, so I changed == to >= instinctively, but it seems Dart was not happy with me doing that
I double checked documentation of Dart, >= should work to test greater or equals operation
IMO, in the end, if >= has something wrong, then the same should come to ==
You are comparing two different operators which comes from different part of the Dart language. The == operator is defined on Object:
https://api.dart.dev/stable/2.15.1/dart-core/Object/operator_equals.html
Which needs to be able to compare every type of object including null. The reason why the == operator does not have Object? as input parameter is because of the following detail in the Dart Language Specification (page 167) under the section "Equality":
Evaluation of an equality expression ee of the form e1 == e2 proceeds as follows:
The expression e1 is evaluated to an object o1.
The expression e2 is evaluated to an object o2.
If either o1 or o2 is the null object (17.4), then ee evaluates to true if both o1 and o2 are the null object and to false otherwise. Otherwise,
evaluation of ee is equivalent to the method invocation o1.==(o2)
...
https://dart.dev/guides/language/specifications/DartLangSpec-v2.10.pdf
So based on third rule, the language itself will make sure that null values are compared correctly and therefore the Object.== method will never see a null object as its input.
The other operator is >= and comes (in your case) from num which int extends from:
https://api.dart.dev/stable/2.15.1/dart-core/num/operator_greater_equal.html
And is specified to accept only num (so int or double) which are a non-nullable type (null is therefore not allowed).
You are then trying to call the num.>= operator with the result from values?.length. This is a problem since values is nullable and can therefore potentially be null. And when you use the ?. operator, you are saying that if values are null, don't care calling .lenght but instead just return null.
So the type of values?.length ends up being int? which is not compatible with num.
The following code used to work in Dart 2.6 (very simplified example!):
T plus<T extends num>(T a, T b) => a + b;
Now it fails with: A value of type 'num' can't be returned from method 'plus' because it has a return type of 'T'.
Is there a way to abstract over double/int like intended in the example?
I'm assuming you are passing the --no-implicit-casts flag to the analyzer in order to get this error. The code is correct in the current Dart language, but it contains an implicit cast, so if you choose to disable those, the code will not be accepted.
The reason the code does not work is that the static type of a + b is num (both have type T which is only known to extend num, so they are treated as num, and num.operator+ returns num), and the return type is T which may extend num.
So, the code does an implicit cast from num to T if you allow it.
To make the code compile even without implicit casts, you have to turn it into an explicit cast:
T plus<T extends num>(T a, T b) => (a + b) as T;
The lua doc's comment on label scope:
A goto may jump to any visible label as long as it does not enter into the scope of a local variable
So in my understanding, the following code is problematic:
-- codelist 1
goto a
local x = 42
::a::
But it works well in the lua web shell. The doc continues to say:
Note that you can think of
do
<...>
--::a::
goto a -- invalid (forward jump into scope of local definition)
goto b -- valid (jump out of block)
<...>
local x
<...>
::a::
<...>
--goto a
::b::
end
as equivalent to
do
<...>
--::a::
goto a -- invalid (jump into nested block prohibited because nested label not even visible here)
goto b -- valid (jump out of block)
<...>
do
local x
<...>
::a::
<...>
--goto a
end
::b::
end
Why is ::a:: included in the auto-introduced do...end block and why isn't ::b::? Please help me understand, thanks.
Edit: I also found this old post, and it seems that there indeed was a time when codelist 1 was prohibited.
goto a
local x = 42
::a::
will not cause an error. Not even in 5.2
goto a
local x = 42
::a::
print("oh no")
on the other hand will.
Lua's pre-compilation will only complain if you jump into the scope of a local and acutally do something after the label while still within the local's scope.
So you may jump there but you may not do something in this invalid situation.
Same with your second example. ::b:: is the end of the block. Nothing happens within the scope of x after it so it's ok to jump there.
goto b
local x = 42
::a::
print("oh no")
::b::
would be ok.
I have the following code. I am checking 3 conditions. You can see for the first condition I stored the output of xml:get_tag_attr_s(...) in a variable and then used the variable within the if block. My problem is I get error illegal guard expression, if I try to do the above process in one line like I did for the other two conditions.
Also, I am getting variable '_' is unbound from the default condition. It supposed to be the same thing.
Can somebody please explain the issue?
validate_xmpp(Packet) ->
Type = xml:get_tag_attr_s(list_to_binary("type"), Packet),
if
(Type /= <<"chat">> ->
{error, "Message type is not chat"};
xml:get_path_s(Packet, [{elem, list_to_binary("body")}, cdata]) /= <<"">> ->
{error, "No or empty body"};
exml_query:path(Packet, [{element,<<"received">>},{attr,<<"xmlns">>}]) == <<"urn:xmpp:receipts">> ->
{error, "delivery-receipts should be ignored"};
_->
{ok, xml:get_tag_attr_s(list_to_binary("from"), Packet)}
end.
Erlang allows only these to be guards:
The atom true
Other constants (terms and bound variables), all regarded as false
Calls to the BIFs (built-in functions) specified in table Type Test BIFs
Term comparisons
Arithmetic expressions
Boolean expressions
Short-circuit expressions (andalso and orelse)
For more info take a look http://www.erlang.org/doc/reference_manual/expressions.html#id83606
Instead of _ use true. You cannot use _ in if, only in case statements, and also take a look at the docs.
isPrime(A,B) when B>math:sqrt(A) -> true;
That results in an illegal guard error.
On a first reading, it looks like the guard contains a "term comparison":
>
and an "arithmetic expression":
math:sqrt(A)
Futhermore, if you play around with the code, you will see that the guard:
B > A+2
is legal. So what's the difference between the "arithmetic expression" math:sqrt(A) and A+2?
The Erlang docs define an "arithmetic expression" as: `
+
-
*
/
div
rem
bnot
band
bor
bxor
bsl
bsr
Notably, math:sqrt() is not in the list of "arithmetic expressions". Therefore, math:sqrt(A) is a "function call" rather than an "arithmetic expression", and you can only call a certain limited number of functions in a guard, namely the "type test BIF's" listed here, such as:
is_integer/1
is_float/1
is_binary/1
is_list/1
is_map/1
is_function/1
etc.
Every time I use my keybindings I get an error
/usr/share/awesome/lib/awful/key.lua:42: attempt to call upvalue 'press' (a string value)
Line 42:
ret[#ret]:connect_signal("press", function(kobj, ...) press(...) end)
Here's all the lines around it
--- Create a new key to use as binding.
-- This function is useful to create several keys from one, because it will use
-- the ignore_modifier variable to create more key with or without the ignored
-- modifiers activated.
-- For example if you want to ignore CapsLock in your keybinding (which is
-- ignored by default by this function), creating key binding with this function
-- will return 2 key objects: one with CapsLock on, and the other one with
-- CapsLock off.
-- #see key
-- #return A table with one or several key objects.
function key.new(mod, _key, press, release)
local ret = {}
local subsets = util.subsets(ignore_modifiers)
for _, set in ipairs(subsets) do
ret[#ret + 1] = capi.key({ modifiers = util.table.join(mod, set),
key = _key })
if press then
ret[#ret]:connect_signal("press", function(kobj, ...) press(...) end)
end
if release then
ret[#ret]:connect_signal("release", function(kobj, ...) release(...) end)
end
end
return ret
end