Simple State Machine in Alloy - state

i'm new to alloy and its function as well. Recently, i have an assignment about a simple state machine : begin_state->normal_state->end_state. There is only one begin_state, but some normal_state and some end_state. Then I can't make the instance view go right with these below alloy code:
abstract sig state
{
prev : some state,
next : some state
}
one sig begin extends state{}
some sig end extends state{}
sig mid extends state{}
//There is no state after end state, and there is no state before begin state
pred dosomething
{
no s : state | s in begin.prev and s in end.next
}
run{dosomething}
So basically i just want no state before begin state, no state after the end state and the instance examples can something like this :
begin->normal->end
or
begin-> normal ->end
|
normal->normal->end
|
normal---normal
| |
end <--------
... something like that. Thank you

Consider the following propositions:
Every state points to a preceding state.
The begin-state is a state.
The begin-state does not point to a preceding state.
If (as I hope) you believe that these three propositions contradict each other, then ask yourself (a) do these propositions resemble the rules given in your Alloy model? (b) how might you rephrase them to make sense and not contradict each other? (c) how might your rephrasing of them be translated into Alloy?
I hope this helps.

Watch your quantifiers! The formula
no s : state | s in begin.prev and s in end.next
says there is no state s that is BOTH a predecessor of begin AND a successor of end.

Related

Camunda: query processes that do not have a specific variable

In Camunda (7.12) I can query processes by variable value:
runtimeService.createProcessInstanceQuery()
.variableValueEquals("someVar", "someValue")
.list();
I can even query processes for null-value variables:
runtimeService.createProcessInstanceQuery()
.variableValueEquals("someVar", null)
.list();
But how can I query processes that do not have variable someVar?
I am not sure why you wouldn't have figured that out, but if i am correct what i think you are looking for , then looks like its pretty simple . The ProcessInstanceQuery class has also a method called variableValueNotEquals(String name, Object value) , that allows you select the processes that do not match a variable . In the Camunda Java API Docs it is stated as :
variableValueNotEquals(String name, Object value)
Only select process instances which have a global variable with the given name, but with a different value than the passed value.
Documentation page for your reference:
https://docs.camunda.org/javadoc/camunda-bpm-platform/7.12/?org/camunda/bpm/engine/RuntimeService.html
So i believe you can simply do :
runtimeService.createProcessInstanceQuery()
.variableValueNotEquals("someVar", null)
.list();
Let me know if that helps you .
First, get list of ids of all process instances which have "someVar"
Second, get list of all process ids in camunda
Get ids, from second list, which are not contained in first list.
Here is Kotlin sample as it's shorter than Java code, but concept is the same:
val idsOfProcessesWithVar = runtimeService.createVariableInstanceQuery().variableName("someVar").list().map {
it.processInstanceId
}
val allProcessesIds = runtimeService.createProcessInstanceQuery().list().map { it.id }
allProcessesIds.minus(idsOfProcessesWithVar)

Eiffel: classical typecasting switch structure with attached and inspect

What is the best practice to do something such as
local
l_pet: ANIMAL
do
l_pet := catch_it_from_the_sky
inspect l_pet
when attached {DOG} l_pet as l_dog
l_dog.eat (meat)
when attached {FISH} l_pet as l_fish
l_fish.eat (plants)
else
io.put_string ("Strange animal how do I feed him???")
end
do
the compiler is complaining with the attached after when...
Update: why such a need?
because it just happened me to mess up with repeated copy-paste which is what a language tries to help avoiding. In the above case, the l_pet is written one time, with a N times if/else I'd have to write it as much times as ifs...
An inspect statement allows for checking if an expression has a specific value, and can be applied to expressions of integral types (such as INTEGER_64, CHARACTER_32 or NATURAL_8):
inspect age
when 6 .. 16 then ...
when 18 then ...
when 80, 90 then ...
...
end
For discriminating over object types, conditional instructions are used:
if attached {DOG} pet as dog then
dog.eat (meat)
elseif attached {FISH} pet as fish then
fish.eat (plants)
else
io.put_string ("Strange animal how do I feed him???")
end
In a multi-branch instruction
inspect exp when ... then ... else ... end
The exp expression needs to be a character or an integer expression.
In your given example I don't see the need to do that Object-Test,
but if you need to do something like that you need to use the conditional instruction.
if ... then
...
elseif ... then
...
else
...
end

using member/2 predicate to create a list of events in prolog

group_events(G,Events) is true if Events is the list of events that
should be scheduled for the group G. My code is as follows:
studying(csen602, group2MET).
event_in_course(csen602, quiz1, quiz).
event_in_course(csen602, quiz2, quiz).
event_in_course(csen602, quiz3, quiz).
group_events(G,[Name|T]):-
studying(Course,G),
event_in_course(Course,Name,_),
\+member(Name,T),
group_events(G,T).
group_events(G,Events):-
member(Name,Events),
studying(Course,G),
event_in_course(Course,Name,Type).
what I get when using the query group_events(group2MET,E) is :
E = [quiz1|_G567]
E = [quiz2|_G502]
E = [quiz3|_G502]
E = [_G501, quiz1|_G505]
E = [_G501, quiz2|_G505]
E = [_G501, quiz3|_G505]
and so on...
I think the problem is with the member/2 predicate so any help how to solve this ?
I think you want
group_events(G,Events):-
setof(Event, Course^Desc^(
studying(Course,G),
event_in_course(Course,Event,Desc)
), Events).
The problem is that you're not 'starting' with an empty list, but with an uninstantiated list, to which you start adding events to be studied and which you are checking for membership.
But that list is still uninstantiated, so the tail of it, and any member you get from it, will be uninstantiated as well.
You want to find all events that need to be studied, so a good approach would be to first define a study_event(G, E) which defines an event E that needs to be studied for by a group G, and then use findall/3 to find all such events.

Boolean Assert in ABAP Unit

How do I write a simple ABAP Unit Assert statement to check if any call, expression or other statement evaluates to true?
I can't see any basic assert() or assert_true() methods in CL_AUNIT_ASSERT while I'd expect those to be very common. I can approximate such an assert as follows, but is there no cleaner way?
cl_aunit_assert=>assert_equals(
act = boolc( lv_value > 100 OR lv_value < 2 )
exp = abap_true ).
cl_aunit_assert=>assert_equals(
act = mo_model->is_active )
exp = abap_true ).
Depending on your SAP NetWeaver stack you can (or should) use the updated ABAP Unit Class CL_ABAP_UNIT_ASSERT. This class is available at a Basis-Release >= 7.02. SAP declared this class as 'FINAL' so it´s impossible to inherit from it, but on the other side they added some ASSERT-Methods like the ASSERT_TRUE Method!
Here is a possible usage of this method:
cl_abap_unit_assert=>assert_true(
exporting
act = m_ref_foo->is_bar( l_some_var )
msg = 'is_bar Method fails with Input { l_some_var }'
).
For the releases I have access to, there's probably no shorter way than the one you outlined. You can create a subclass of CL_AUNIT_ASSERT and add your own static ASSERT_TRUE method. It's not a bad idea to do so and at the same time make your local ABAP Unit test class a subclass of that ZCL_AUNIT_ASSERT - this way, you can omit the cl_aunit_assert=> prefix which will save some keystrokes.
You cannot see such methods because there is no boolean type in ABAP.
While in Java, C++ or C, you are able to assign a result of a condition to a variable, like this
int i = 5;
boolean result = i > 3;
You cannot do the same thing in ABAP as there is no boolean type. Therefore what in other languages is a one liner, in ABAP it will always be more prolix.
DATA: i TYPE i VALUE 5.
DATA: result TYPE abap_bool.
IF i > 3.
result = abap_true.
ELSE.
result = abap_false.
ENDIF.
The thing you used seems to be a new feature, that has been recently added to the language and most of the customers will not be using for a long time. Also the CL_AUNIT_ASSERT class was created way before the new elements came to the language.
So right now, there is a possibility to write the above thing as one liner. However there is still no boolean type in the language.
DATA: i TYPE i VALUE 5.
DATA: result TYPE abap_bool.
result = boolc( i > 3 ).
On the other hand, there is no boolean type, but you could simply use ASSERT_INITIAL or ASSERT_NOT_INITIAL in this case, as boolean is emulated by either X (true) or space (false). The latter is an initial value in ABAP.
The cleanest way is to just fail:
if value > limit.
cl_abap_unit_assert=>fail( ).
endif.
Or a more informative:
cl_abap_unit=>fail( msg = 'Limit exceeded' ).

Identifier idents no member for child class

I do a little project in Pascal and I have a problem.
I have 3 class (1 parent 2 child)
TGroup = class
...
end;
TUser = class(TGroup)
...
public
someVariableForUser: Integer;
...
end;
TAdmin = class(TGroup)
...
public
someVariableForAdmin: Integer;
...
end;
//And main program like this:
var
Person: TGroup;
begin
Person := TGroup.Create();
Person.someVariableForAdmin := 1;
And i get Error: identifier idents no member "someVariableForAdmin"
When I change var Person: TAdmin, so everything works fine.
Please help, Thanks alot.
This is exactly what should be expected. A TGroup instance has no knowledge of types that descend from it, or any fields or methods those descendants might declare. If you want to access something that's contained in TAdmin and it's descendents, you need to create an instance of TAdmin or one of it's descendents.
If you want to access something in a TAdmin, you have to create a TAdmin in the first place:
var
Person: TGroup;
begin
Person := TAdmin.Create;
(Person as TAdmin).someVariableForAdmin := 1;
end.
It's not clear from your question what exactly you're trying to accomplish. You might want to post another question explaining your desired goal, post some base code, and ask for help in changing it to reach that goal. (It's too late to edit this one for that, as that would change the entire meaning of the question after you've received multiple answers to it.)