I am trying to construct a recursive function in Alloy. According to the grammar displayed on Daniel Jackson's book, this is possible. My function is:
fun auxiliaryToAvoidCyclicRecursion[idTarget:MethodId, m:Method]: Method{
(m.b.id = idTarget) => {
m
} else (m.b.id != idTarget) => {
(m.b = LiteralValue) => {
m
} else {
some mRet:Method, c:Class | mRet in c.methods && m.b.id = mRet.id => auxiliaryToAvoidCyclicRecursion[idTarget, mRet]
}
}
}
But the solver claims about the call auxiliaryToAvoidCyclicRecursion[idTarget, mRet] saying that:
"This must be a formula expression.
Instead, it has the following possible type(s):
{this/Method}"
The problem is exactly what the error message says: the return type of your auxiliaryToAvoidCyclicRecursion function is Method, which you are trying to use in a boolean implication, where formula is expected (i.e., something of type Boolean). You'd get the same kind of error in any other statically typed language.
You could rewrite your function as a predicate to work around this problem:
pred auxiliaryToAvoidCyclicRecursion[idTarget:MethodId, m:Method, ans: Method] {
(m.b.id = idTarget) => {
ans = m
} else (m.b.id != idTarget) => {
(m.b = LiteralValue) => {
ans = m
} else {
some mRet:Method, c:Class {
(mRet in c.methods && m.b.id = mRet.id) =>
auxiliaryToAvoidCyclicRecursion[idTarget, mRet, ans]
}
}
}
}
This should not give you a compilation error, but to run it make sure you enable recursion (Options -> Recursion Depth). As you will see, the maximum recursion depth is 3, meaning that the Alloy Analyzer can unroll your recursive calls up to 3 times, regardless of the scope of your analysis. When that is not enough, you still have the option to rewrite your model such that the recursive predicate in question is modeled as a relation. Here is a simple example to illustrate that.
Linked list with a recursively defined function for computing the list length:
sig Node {
next: lone Node
} {
this !in this.^#next
}
fun len[n: Node]: Int {
(no n.next) => 1 else plus[1, len[n.next]]
}
// instance found when recursion depth is set to 3
run { some n: Node | len[n] > 3 } for 5 but 4 Int
// can't find an instance because of too few recursion unrollings (3),
// despite the scope being big enough
run { some n: Node | len[n] > 4 } for 5 but 4 Int
Now the same list where len is modeled as a relation (i.e., a field in Node)
sig Node {
next: lone Node,
len: one Int
} {
this !in this.^#next
(no this.#next) => this.#len = 1 else this.#len = plus[next.#len, 1]
}
// instance found
run { some n: Node | n.len > 4 } for 5 but 4 Int
Note that the latter approach, which doesn't use recursion (and therefore does not depend on the value of the "recursion depth" configuration option), can be (and typically is) significantly slower than the former.
Related
I'm looking for some way to shorten an iterator by some condition. A bit like an inverse filter but it stops iterating at the first true value. Let's call it until(f). Where:
iterator.until(f)
Would return an iterator that only runs until f is true once.
Let's use an example of finding the next prime number.
We have some structure containing known primes and a function to extend it.
// Structure for caching known prime numbers
struct PrimeGenerator {
primes:Vec<i64>
}
impl PrimeGenerator {
// Create a new prime generator
fn new()->Self{
let primes = vec![2,3];
Self {
primes,
}
}
// Extend the list of known primes by 1
fn extend_by_one(&mut self){
let mut next_option = self.primes.last().unwrap()+2;
while self.primes.iter().any(|x| next_option%x == 0) { // This is the relevant line
next_option += 2;
}
self.primes.push(next_option);
}
}
Now this snippet is a bit too exhaustive as we should only have to check until the square root of next_option, so I was looking for a some method that would shorten the iterator based on some condition, so I could write something like:
self.iter().until(|x| x*x > next_option).any(|x| next_option%x == 0)
Is there any similar pattern available?
Looks like your until is similar to inverted take_while.
self.iter().take_while(|x| x*x <= next_option).all(|x| next_option%x != 0)
I have the next code:
import zio._
import scala.concurrent.Future
case class AppError(description: String) extends Throwable
// legacy-code imitation
def method(x: Int): Task[Boolean] = {
Task.fromFuture { implicit ec => Future.successful(x == 0) }
}
def handler(input: Int): IO[AppError, Int] = {
for {
result <- method(input)
_ <- IO.fail(AppError("app error")).when(result)
} yield input
}
but this code does not compile, because compiler says result type is:
ZIO[Any, Throwable, Int]
How to convert from Task (where I call method) to IO?
You'll need to decide what you want to do with Throwable errors which are not AppError.
If you decide you want to map them to an AppError you can do:
method(input).mapError {
case ae: AppError => ae
case other => AppError(other.getMessage)
}
If you want to refine those errors and only keep the ones that are AppError then you can use one of the refine* family of operators, which will keep errors that match the predicate and terminate the fiber otherwise.
method(input).refineToOrDie[AppError] // IO[AppError, Boolean]
// Or
method(input).refineOrDie { case ae: AppError => ae } // IO[AppError, Boolean]
Or if you want to assume that all errors from method are considered "Fiber terminating", then you can use .orDie to absorb the error and kill the fiber:
method(input).orDie // UIO[Boolean]
Or if you want to recover from the error and handle it a different way then you could use the catch* family
method(input).catchAll(_ => UIO.succeed(false)) // UIO[Boolean]
Finally if you wanted to have the result mapped into an Either you could use .either, which will lift the error out of the error channel and map it into Either[E, A]
method(input).either // UIO[Either[Throwable, Boolean]]
There is a great cheat sheet (though admittedly a bit out of date) here as well
I have an Observable source where several items are emitted. For each item, I need to execute a long process in the background and start each process only after the previous one is completed. So, I get the desired behavior using these operators:
'0, 1, 2, 3' are observable items, 'A, B, C' are process results. I start the processing of '0' manually using startWith to start this processing circle. The problem is that 'A, B, C' are emitted by BehaviorSubject (in other places I need the latest calculation result), so if I have already processed the old items, the BehaviorSubject returns the old result and then I get the following:
So how can I skip that old result 'X'? If I use skip(1) then the result 'A' is skipped if there is no processing before. Or maybe there is another more appropriate way to reach my goal?
A bit of code to bring specifics, what am I doing:
val decodedChannelsSource =
BehaviorSubject.create<List<ChannelData>>()
fun startTransmitting(channels: List<ChannelData>, frameSize: Int, frameCount: Int) {
transmitSubscription?.dispose()
transmitSubscription = Observable
.create<List<ChannelData>> {
for (i in 1 until frameCount) {
val chls = channels.map { c ->
c.apply { frameData = UserDataProvider.generateData(frameSize) }
}
it.onNext(chls)
}
}
.zipWith(decodedChannelsSource) { trans, rec -> trans }
.startWith(channels.map { c ->
c.apply { frameData = UserDataProvider.generateData(frameSize) }
})
.subscribeOn(Schedulers.io())
.subscribe{ processChannels(it) }
}
fun processChannels(channels: List<ChannelData>) {
... // do calculations with channels in the background
decodedChannelsSource.onNext(channels)
}
I am attempting to implement one iteration of Conway's Game of Life in Rust using the ndarray library.
I thought a 3x3 window looping over the array would be a simple way to count the living neighbours, however I am having trouble doing the actual update.
The array signifies life with # and the absence of life with :
let mut world = Array2::<String>::from_elem((10, 10), " ".to_string());
for mut window in world.windows((3, 3)) {
let count_all = window.fold(0, |count, cell| if cell == "#" { count + 1 } else { count });
let count_neighbours = count_all - if window[(1, 1)] == "#" { 1 } else { 0 };
match count_neighbours {
0 | 1 => window[(1, 1)] = " ".to_string(), // Under-population
2 => {}, // Live if alive
3 => window[(1, 1)] = "#".to_string(), // Re-produce
_ => window[(1, 1)] = " ".to_string(), // Over-population
}
}
This code does not compile! The error is within the match block with "error: cannot borrow as mutable" and "error: cannot assign to immutable index". I attempted for &mut window... but the library does not implement this(?)
I'm relatively new to Rust and I believe this may be an issue with the implementation of windows by the library. However, I'm not sure and I don't know if there perhaps some variation/fix that allows me to continue with this approach. Do I need to scrap this approach entirely? I'm not sure what the best approach would be here.
Any other suggestions or improvements to the code would be greatly appreciated.
(This code doesn't implement proper rules as I am mutating as I loop and I am ignoring the outer edge, however that is okay in this case. Also, any variations which do these things are also okay - the details are not important.)
Your general approach using ndarray and windows is ok, but the problem is that the values that you get from the windows iterator will always be immutable. You can work around that by wrapping the values in Cell or RefCell, which gives you interior mutability. That is, they wrap a value as if it was immutable, but provide an API to let you mutate it anyway.
Here is your code, fairly brutally adapted to use RefCell:
use ndarray::Array2;
use std::cell::RefCell;
fn main() {
// creating variables for convenience, so they can be &-referenced
let alive = String::from("#");
let dead = String::from(" ");
let world = Array2::<String>::from_elem((10, 10), " ".to_string());
let world = world.map(RefCell::new);
for mut window in world.windows((3, 3)) {
let count_all = window.fold(0, |count, cell| if *cell.borrow() == &alive { count + 1 } else { count });
let count_neighbours = count_all - if *window[(1, 1)].borrow() == &alive { 1 } else { 0 };
match count_neighbours {
0 | 1 => *window[(1, 1)].borrow_mut() = &dead, // Under-population
2 => {}, // Live if alive
3 => *window[(1, 1)].borrow_mut() = &alive, // Re-produce
_ => *window[(1, 1)].borrow_mut() = &alive, // Over-population
}
}
}
What I've done above is really just to get your code working, pretty much as-is. But, as E_net4 pointed out, your solution has a major bug because it is mutating as it reads. Also, in terms of best-practices, your usage of String isn't ideal. An enum is much better because it's smaller, can be stack-allocated and better captures the invariants of your model. With an enum you would derive Copy as below, which would let you use a Cell instead of RefCell, which is likely to be better performance because it copies the data, instead of having to count references.
#[derive(Debug, PartialEq, Clone, Copy)]
enum CellState {
Alive,
Dead
}
I'm trying to follow a specific implementation of a recursive (in-order traversal) isBST function.
I tried to simulate it with the simple invalid BST example:
root=5, root.left=3, root.left.right=8
5
/
3
\
8
i'm getting either 'true' or 'false' but without having to check the last node '8'.
the code is as follows:
/* wrapper that keeps track of the previous value */
class PrevWrapper {
int data = Integer.MIN_VALUE;
}
boolean isBST(Node root, PrevWrapper prev) {
/* base case: we reached null*/
if (root == null) {
return true;
}
if(!isBST(root.left, prev)) {
return false;
}
/* If previous in-order node's data is larger than
* current node's data, BST property is violated */
if (prev.data > root.data) {
return false;
}
/* set the previous in-order data to the current node's data*/
prev.data = root.data;
return isBST(root.right, prev);
}
boolean isBST(Node root) {
return isBST(root, new PrevWrapper());
}
what is the correct order of returning the recursive calls?
EDIT:
I was thinking:
(#)isBST(5,min), isBST(3,min), isBST(3.left=null,min) - returns true, skips to prev=3, isBST(8,3), isBST(8.left=null,3) - returns true, skips to prev=8, isBST(8.right=null,8) - returns true to (#), checks 8 > 5? returns false.
I think I got it, is this the correct order of calls?
thanks in advance.