I'm trying to visualise a spec for a Payment object where it moves from "queued" to "processing" to "complete". I have come up with the following:
enum State {Queued, Processing, Complete}
sig Payment {
var state: State
}
pred processPayment[p: Payment] {
p.state = Queued // guard
p.state' = Processing // action
}
pred completePayment[p: Payment] {
p.state = Processing // guard
p.state' = Complete // action
}
fact init {
Payment.state = Queued
}
fact next {
always (some p : Payment | processPayment[p] or completePayment[p])
}
run {} for 1 Payment
Unfortunately, I get no instances found for this spec. From my understanding, a Payment with state "Queued" initially and a next state where it's in "Processing" should be allowed with the always (some p : Payment | processPayment[p] or completePayment[p])" formula according to the tutorial at https://haslab.github.io/formal-software-design/overview/index.html. Am I missing something?
The issue turned out to be a missing terminating predicate, adding the below(or a stutter) fixes it.
pred afterComplete[p: Payment] {
p.state = Complete // guard
p.state' = Complete // action
}
I am not an expert but I believe that it is impossible for either of your predicates to be true at t0. I think you need a holdPayment predicate like this:
pred holdPayment[p:Payment] {
p.state = p.state'
}
fact next {
always (some p : Payment | processPayment[p] or completePayment[p] or holdPayment[p])
}
run {} for 1 Payment
Related
I'm having a hard time formulating this in a rust-y manner, since my brain is still hardwired in Python. So I have a XML file:
<xml>
<car>
<name>First car</name>
<brand>Volvo</brand>
</car>
<plane>
<name>First plane</name>
<brand>Boeing</brand>
</plane>
<car>
<name>Second car</name>
<brand>Volvo</brand>
</car>
</xml>
In reality it's much more complex and the XML is about 500-1000MB large. I'm reading this using quick-xml which gives me events such as Start (tag start), Text and End (tag end) and I'm doing a state machine to keep track.
Now I want to off-load the parsing of car and plane to different modules (they need to be handled differently) but share a base-implementation/trait.
So far so good.
Now using my state machine I know when I need to offload to the car or the plane:
When I enter the main car tag I want to create a new instance of car
After that, offload everything until the corresponding </car> to it
When we reach the end I'm going to call .save() on the car implementation to store it elsewhere, and can free/destroy the instance.
But this means in my main loop I need to create a new instance of the car and keep track of it (and the same for plane if that's the main element.
let mut current_xml_section: I_DONT_KNOW_THE_TYPE = Some()
loop {
match reader.read_event(&mut buf) {
Ok(Event::Start(ref e)) => {
if state == State::Unknown {
match e.name() {
b"car" => {
state = State::InSection;
current_section = CurrentSection::Car;
state_at_depth = depth;
current_xml_section = CurrentSection::Car::new(e); // this won't work
},
b"plane" => {
state = State::InSection;
current_section = CurrentSection::Plane;
state_at_depth = depth;
current_xml_section = CurrentSection::Plane::new(e); // this won't work
},
_ => (),
};
}else{
current_xml_section.start_tag(e); // this won't work
}
depth += 1;
},
Ok(Event::End(ref e)) => {
depth -= 1;
if state == State::InSection && state_at_depth == depth {
state = State::Unknown;
current_section = CurrentSection::Unknown;
state_at_depth = 0;
current_xml_section.save(); // this won't work
// Free current_xml_section here
}else{
if state == State::InSection {
current_xml_section.end_tag(e) // this won't work
}
}
},
// unescape and decode the text event using the reader encoding
Ok(Event::Text(e)) => (
if state == State::InSection {
current_xml_section.text_data(e) // this won't work
}
),
Ok(Event::Eof) => break, // exits the loop when reaching end of file
Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
_ => (), // There are several other `Event`s we do not consider here
}
// if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
buf.clear();
}
}
So I basically don't know how to keep a reference in the main loop to the "current" object (I'm sorry, Python term), given that:
We may or may not have a current tag we're processing
That section might be a reference to either Car or Plane
I've also considered:
Use Serde, but it's a massive document and frankly I don't know the entire structure of it (I'm black box decoding it) so it would need to be passed to Serde in chunks (and I didn't manage to do that, even though I tried)
Keeping a reference to the latest plane, the latest car (and start by creating blank objects outside of the main loop) but it feels ugly
Using Generics
Any nudge in the right direction would be welcome as I try to un-Python my brain!
Event driven parsing of XML lends itself particularly well to a scope driven approach, where each level is parsed by a different function.
For example, your main loop could look like this:
loop {
match reader.read_event(&mut buf) {
Ok(Event::Start(ref e)) => {
match e.name() {
b"car" => handle_car(&mut reader, &mut buf)?,
b"plane" => handle_plane(&mut reader, &mut buf)?,
_ => return Err("Unexpected Tag"),
}
},
Ok(Event::Eof) => break,
_ => (),
}
}
Note that the inner match statement only has to consider the XML tags that can occur at the top level; any other tag is unexpected and should generate an error.
handle_car would look something like this:
fn handle_car(reader: &mut Reader<&[u8]>, buf:&mut Vec<u8>) -> Result<(),ErrType> {
let mut car = Car::new();
loop {
match reader.read_event(buf) {
Ok(Event::Start(ref e)) => {
match e.name() {
b"name" => {
car.name = handle_name(reader, buf)?;
},
b"brand" => {
car.brand = handle_brand(reader, buf)?;
},
_ => return Err("bad tag"),
}
},
Ok(Event::End(ref e)) => break,
Ok(Event::Eof) => return Err("Unexpected EOF"),
_ => (),
}
}
car.save();
Ok(())
}
handle_car creates its own instance of Car, which lives within the scope of that function. It has its own loop where it handles all the tags that can occur within it. If those tags contain yet more tags, you just introduce a new set of handling functions for them. The function returns a Result so that if the input structure does not match expectations the error can be passed up (as can any errors produced by quick_xml, which I have ignored but real code would handle).
This pattern has some advantages when parsing XML:
The structure of the code matches the expected structure of the XML, making it easier to read and understand.
The state is implicit in the structure of the code. No need for state variables or depth counters.
Common tags, that appear in multiple places (such as <name> and <brand> can be handled by common functions that are re-used
If the XML format you are parsing has nested structures (eg. if <car> could contain another <car>) this is handled by recursion.
Your original problem of not knowing how to store the Car / Plane within the main loop is completely avoided.
TL;DR
I want to delay a publication, but can't figure out how to, er, combine the parts
In Brief
I have a Publisher
let generator = PassthroughSubject<Bool, Never>()
and want somehow to use the modifier
.delay(for: 2, scheduler: RunLoop.main)
so that when I call
generator.send(true)
the message is sent two seconds after the call to send()
Looking at the docs for Publishers.Delay made the type error more clear, but doesn't help me to find the right way to hook things up.
Code
import SwiftUI
import Combine
// Exists just to subscribe.
struct ContainedView : View {
private let publisher: AnyPublisher<Bool, Never>
init(_ publisher: AnyPublisher<Bool, Never> = Just(false).dropFirst().eraseToAnyPublisher()) {
self.publisher = publisher
}
var body: some View {
Rectangle().onReceive(publisher) { _ in print("Got it") }
}
}
struct ContentView: View {
let generator = PassthroughSubject<Bool, Never>()
// .delay(for: 2, scheduler: RunLoop.main)
// Putting it here doesn't work either.
var body: some View {
VStack {
Button("Tap") {
// Does not compile
self.generator.delay(for: 2, scheduler: RunLoop.main).send(true)
// Value of type 'Publishers.Delay<PassthroughSubject<Bool, Never>, RunLoop>' has no member 'send'
// https://developer.apple.com/documentation/combine/publishers/delay
// Does not compile
self.generator.send(true).delay(for: 2, scheduler: RunLoop.main)
// Value of tuple type '()' has no member 'delay'
// Just a broken-up version of the first try.
let delayed = self.generator.delay(for: 2, scheduler: RunLoop.main)
delayed.send(true)
// This, of course, builds and works.
self.generator.send(true)
print("Sent it")
}
ContainedView(generator.eraseToAnyPublisher())
.frame(width: 300, height: 200)
}
}
}
You can use the debounce property of a publisher to delay the publishing.
$yourProperty
.debounce(for: 0.8, scheduler: RunLoop.main)
.eraseToAnyPublisher()
.delay(for: 2, scheduler: RunLoop.main) is likely exactly what you need, but it'll be key to see how you're subscribing to fully understand the issue. Delay doesn't delay the sending of the value when using send() with a subject - that's a link for imperative code and sends the data whenever send is invoked, typically against some already existing subscription.
While you have a subscriber in the first bit of code, there isn't one with the subject to pin these together.
For example, if you updated:
Just(false).dropFirst().eraseToAnyPublisher()
to
Just(false).dropFirst().eraseToAnyPublisher().delay(for: 2, scheduler: RunLoop.main)
Then the print statement should trigger ~2 second after the the init() was invoked. Depending on what you're trying to accomplish here, using a closure trigger such as onAppear might make a lot more sense, having that call the subject.send(), which you can then delay as you like in the publisher chain that happens before whatever subscribes to it.
var cancellables: [AnyCancellable] = []
let generator = PassthroughSubject<Bool, Never>()
let generated = generator.delay(for: 2, scheduler: RunLoop.main).sink { value in
print(value.description + " " + Date().timeIntervalSinceReferenceDate.description)
}
print(Date().timeIntervalSinceReferenceDate.description)
generator.send(true)
generator.send(false)
output
641453284.840604
true 641453286.841731
false 641453286.847715
i've created my first substrate project successful and the built pallet also works fine. Now i wanted to create tests for the flow and the provided functions.
My flow is to generate a random hash and store this hash associated to the sender of the transaction
let _sender = ensure_signed(origin)?;
let nonce = Nonce::get();
let _random_seed = <randomness_collective_flip::Module<T>>::random_seed();
let random_hash = (_random_seed, &_sender, nonce).using_encoded(T::Hashing::hash);
ensure!(!<Hashes<T>>::contains_key(random_hash), "This new id already exists");
let _now = <timestamp::Module<T>>::get();
let new_elem = HashElement {
id: random_hash,
parent: parent,
updated: _now,
created: _now
};
<Hashes<T>>::insert(random_hash, new_pid);
<HashOwner<T>>::insert(random_hash, &_sender);
Self::deposit_event(RawEvent::Created(random_hash, _sender));
Ok(())
works good so far, when now i want to test the flow with a written test, i want to check if the hash emitted in the Created event is also assigned in the HashOwner Map. For this i need to get the value out of the event back.
And this is my problem :D i'm not professional in rust and all examples i found are expecting all values emitted in the event like this:
// construct event that should be emitted in the method call directly above
let expected_event = TestEvent::generic_event(RawEvent::EmitInput(1, 32));
// iterate through array of `EventRecord`s
assert!(System::events().iter().any(|a| a.event == expected_event));
When debugging my written test:
assert_ok!(TemplateModule::create_hash(Origin::signed(1), None));
let events = System::events();
let lastEvent = events.last().unwrap();
let newHash = &lastEvent.event;
i see in VSCode that the values are available:
debug window of vs code
but i dont know how to get this Hash in a variable back... maybe this is only a one liner ... but my rust knowledge is damn too small :D
thank you for your help
Here's a somewhat generic example of how to parse and check events, if you only care about the last event that your module put in system and nothing else.
assert_eq!(
System::events()
// this gives you an EventRecord { event: ..., ...}
.into_iter()
// map into the inner `event`.
.map(|r| r.event)
// the inner event is like `OuterEvent::mdouleEvent(EventEnum)`. The name of the outer
// event comes from whatever you have placed in your `delc_event! {}` in test mocks.
.filter_map(|e| {
if let MetaEvent::templateModule(inner) = e {
Some(inner)
} else {
None
}
})
.last()
.unwrap(),
// RawEvent is defined and imported in the template.rs file.
// val1 and val2 are things that you want to assert against.
RawEvent::Created(val1, val2),
);
Indeed you can also omit the first map or do it in more compact ways, but I have done it like this so you can see it step by step.
Print the System::events(), this also helps.
I now got it from the response of kianenigma :)
I wanted to reuse the given data in the event:
let lastEvent = System::events()
// this gives you an EventRecord { event: ..., ...}
.into_iter()
// map into the inner `event`.
.map(|r| r.event)
// the inner event is like `OuterEvent::mdouleEvent(EventEnum)`. The name of the outer
// event comes from whatever you have placed in your `delc_event! {}` in test mocks.
.filter_map(|e| {
if let TestEvent::pid(inner) = e {
Some(inner)
} else {
None
}
})
.last()
.unwrap();
if let RawEvent::Created(newHash, initiatedAccount) = lastEvent {
// there are the values :D
}
this can maybe be written better but this helps me :)
While answering a question I attempted to implement a setup where the main thread joins the efforts of the CommonPool to execute a number of independent tasks in parallel (this is how java.util.streams operates).
I create as many actors as there are CommonPool threads, plus a channel for the main thread. The actors use rendezvous channels:
val resultChannel = Channel<Double>(UNLIMITED)
val poolComputeChannels = (1..commonPool().parallelism).map {
actor<Task>(CommonPool) {
for (task in channel) {
task.execute().also { resultChannel.send(it) }
}
}
}
val mainComputeChannel = Channel<Task>()
val allComputeChannels = poolComputeChannels + mainComputeChannel
This allows me to distribute the load by using a select expression to find an idle actor for each task:
select {
allComputeChannels.forEach { chan ->
chan.onSend(task) {}
}
}
So I send all the tasks and close the channels:
launch(CommonPool) {
jobs.forEach { task ->
select {
allComputeChannels.forEach { chan ->
chan.onSend(task) {}
}
}
}
allComputeChannels.forEach { it.close() }
}
Now I have to write the code for the main thread. Here I decided to serve both the mainComputeChannel, executing the tasks submitted to the main thread, and the resultChannel, accumulating the individual results into the final sum:
return runBlocking {
var completedCount = 0
var sum = 0.0
while (completedCount < NUM_TASKS) {
select<Unit> {
mainComputeChannel.onReceive { task ->
task.execute().also { resultChannel.send(it) }
}
resultChannel.onReceive { result ->
sum += result
completedCount++
}
}
}
resultChannel.close()
sum
}
This gives rise to the situation where mainComputeChannel may be closed from a CommonPool thread, but the resultChannel still needs serving. If the channel is closed, onReceive will throw an exception and onReceiveOrNull will immediately select with null. Neither option is acceptable. I didn't find a way to avoid registering the mainComputeChannel if it's closed, either. If I use if (!mainComputeChannel.isClosedForReceive), it will not be atomic with the registration call.
This leads me to my question: what would be a good idiom to select over channels where some may get closed by another thread while others are still live?
The kotlinx.coroutines library is currently missing a primitive to make it convenient. The outstanding proposal is to add receiveOrClose function and onReceiveOrClosed clause for select that would make writing code like this possible.
However, you will still have to manually track the fact that your mainComputeChannel was closed and stop selecting on it when it was. So, using a proposed onReceiveOrClosed clause you'll write something like this:
// outside of loop
var mainComputeChannelClosed = false
// inside loop
select<Unit> {
if (!mainComputeChannelClosed) {
mainComputeChannel.onReceiveOrClosed {
if (it.isClosed) mainComputeChannelClosed = true
else { /* do something with it */ }
}
}
// more clauses
}
See https://github.com/Kotlin/kotlinx.coroutines/issues/330 for details.
There are no proposals on the table to further simplify this kind of pattern.
I am am struggling how to define a state change where one event can be posted per step but multiple removed. I have this model:
open util/ordering[State]
sig Event {}
sig State {
queue : set Event
}
pred State.post( next' : State, event : Event ) {
next'.queue = this.queue + event
}
pred State.deliver( next' : State ) {
next'.queue = this.queue - this.queue // STRUGGLE!
}
fact traces {
no first.queue
all s : State - last, next : s.next {
some e : Event | s.post[next,e] or s.deliver[next]
}
}
However, I want to model that in the deliver step I deliver some events by removing them. In the code I deliver all but how do I code it that it will actually try any subset of this.queue?
It seems the struggle come from the fact you try to write this predicate as an assignment.
The solution becomes clear when adopting a more declarative view on the problem. It is simply needed to enforce that the new queue be a proper subset of the previous queue:
pred State.deliver( next' : State ) {
next'.queue in this.queue and next'.queue != this.queue
}