"No instance found" when using seq - alloy

I'm puzzled by the fact that Alloy reports No instance found for this model using seq:
one sig Const {
T: seq (seq Int)
}
fact const_facts {
Const.T = {
0 -> {0->1 + 1->9} +
1 -> {0->3 + 1->15}
}
}
run {} for 20 but 6 Int, 8 seq
While the following model, where I simply replaced each seq with Int ->, has an instance as one would expect:
one sig Const {
T: Int -> (Int -> Int)
}
fact const_facts {
Const.T = {
0 -> {0->1 + 1->9} +
1 -> {0->3 + 1->15}
}
}
run {} for 20 but 6 Int
It's especially confusing to me since https://alloytools.org/quickguide/seq.html seems to imply that seq X and Int -> X are the same thing type-wise.
Any thoughts?

The Const.T you create has an arity of 3 while a seq must be an arity of 2.
┌──────────┬──────┐
│this/Const│T │
├──────────┼─┬─┬──┤
│Const⁰ │0│0│1 │
│ │ ├─┼──┤
│ │ │1│9 │
│ ├─┼─┼──┤
│ │1│0│3 │
│ │ ├─┼──┤
│ │ │1│15│
└──────────┴─┴─┴──┘
The predicates and functions for seq assume an arity of 2. I.e. a seq is not like an object, it is a convention for functions and predicates that take an arity 2 tupleset where the first column is an integer.

Related

An argument definition must end with a newline

I have a dynamic block in aws_cloudfront_distribution which is the following:
dynamic "ordered_cache_behavior" {
for_each = var.ordered_cache_behaviors
content {
path_pattern = ordered_cache_behavior.value.path_pattern
allowed_methods = ordered_cache_behavior.value.allowed_methods
cached_methods = ordered_cache_behavior.value.cached_methods
target_origin_id = var.origin_id
cache_policy_id = var.cache_policy_ids["${var.policy_prefix}${ordered_cache_behavior.value.cache_policy_name}"]
origin_request_policy_id = ordered_cache_behavior.value.path_pattern = "/" ? var.origin_request_policy_ids["whitelist_policy"] : null
dynamic "lambda_function_association" {
for_each = var.enable_auth ? var.default_cache_behavior.lambda_function_association : ordered_cache_behavior.value.lambda_function_association
content {
event_type = lambda_function_association.value.event_type
include_body = lambda_function_association.value.include_body
lambda_arn = lambda_function_association.value.lambda_arn != "" ? lambda_function_association.value.lambda_arn : local.lambda_mapping[lambda_function_association.value.event_type]
}
}
compress = ordered_cache_behavior.value.compress
viewer_protocol_policy = ordered_cache_behavior.value.viewer_protocol_policy
}
I got :
│ Error: Missing newline after argument
│
│ on main.tf line 111, in resource "aws_cloudfront_distribution" "web_distribution":
│ 111: origin_request_policy_id = ordered_cache_behavior.value.path_pattern = "/" ? var.origin_request_policy_ids["origin_1H_1D_plp_pdp_whitelist_whitelist_none"] : null
│
│ An argument definition must end with a newline.
I still dont know why I am getting the error, so what I basically wanna do is to define origin_request_policy_id based on if path pattern is / .
am I missing something?
Terraform's parser is rejecting what you wrote here because you used the = symbol in the middle of an expression. Terraform doesn't understand what you intended and so it's guessing that the expression ends after ordered_cache_behavior.value.path_pattern and then complaining that there isn't a newline at that point.
However, I think what you really intended to do here was test for equality between ordered_cache_behavior.value.path_pattern and "/". The operator for equality test is == rather than =, so you can add the extra equals character to make this valid:
origin_request_policy_id = ordered_cache_behavior.value.path_pattern == "/" ? var.origin_request_policy_ids["whitelist_policy"] : null
Because this expression is long and has multiple complex parts, I might suggest rewriting it to be a multi-line expression like this for readability, but of course that's subjective and optional:
origin_request_policy_id = (
ordered_cache_behavior.value.path_pattern == "/" ?
var.origin_request_policy_ids["whitelist_policy"] :
null
)
I think that you can't assign something in an definition in the same line.
origin_request_policy_id = ordered_cache_behavior.value.path_pattern = "/"...

Rust polars : unexpected befaviour of when().then().otherwise() in groupby-agg context

I have a complicated mapping logic which I seek to execute within groupby context. The code compiles and doesn't panic, but results are incorrect. I know the logic implementation is correct. Hence, I wonder if when-then-otherwise is supposed to be used within groupby at all?
use polars::prelude::*;
use polars::df;
fn main() {
let df = df! [
"Region" => ["EU", "EU", "EU", "EU", "EU"],
"MonthCCY" => ["APRUSD", "MAYUSD", "JUNEUR", "JULUSD", "APRUSD"],
"values" => [1, 2, 3, 4, 5],
].unwrap();
let df = df.lazy()
.groupby_stable([col("MonthCCY")])
.agg( [
month_weight().alias("Weight"),
]
);
}
pub fn month_weight() -> Expr {
when(col("Region").eq(lit("EU")))
.then(
// First, If MonthCCY is JUNEUR or AUGEUR - apply 0.05
when(col("MonthCCY").map( |s|{
Ok( s.utf8()?
.contains("JUNEUR|AUGEUR")?
.into_series() )
}
, GetOutput::from_type(DataType::Boolean)
))
.then(lit::<f64>(0.05))
.otherwise(
// Second, If MonthCCY is JANEUR - apply 0.0225
when(col("MonthCCY").map( |s|{
Ok( s.utf8()?
.contains("JANEUR")?
.into_series() )
}
, GetOutput::from_type(DataType::Boolean)
))
.then(lit::<f64>(0.0225))
.otherwise(
// Third, If MonthCCY starts with JUL or FEB (eg FEBUSD or FEBEUR)- apply 0.15
when(col("MonthCCY").apply( |s|{
let x = s.utf8()?
.str_slice(0, Some(3))?;
let y = x.contains("JUL|FEB")?
.into_series();
Ok(y)
}
, GetOutput::from_type(DataType::Boolean)
))
.then(lit::<f64>(0.15))
//Finally, if none of the above matched, apply 0.2
.otherwise(lit::<f64>(0.20))
)
)
).otherwise(lit::<f64>(0.0))
}
The result I am getting is:
┌──────────┬─────────────┐
│ MonthCCY ┆ Weight │
│ --- ┆ --- │
│ str ┆ list [f64] │
╞══════════╪═════════════╡
│ APRUSD ┆ [0.2, 0.15] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ MAYUSD ┆ [0.2] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ JUNEUR ┆ [0.05] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ JULUSD ┆ [0.2] │
└──────────┴─────────────┘
Clearly, I would expect JULUSD to be [0.15] and APRUSD to be [0.2, 0.2].
Is my expectation of how when().then().otherwise() works within groupby wrong?
I am on Windows11, rustc 1.60.
Yep, you're doing the groupby and the mapping in the wrong order. month_weight() is not an aggregation expression but a simple mapping expression.
As it is, each group of the DataFrame is getting agged into a series that ultimately derives from order of the data in the original frame.
You first want to create a Weight column with values given by the mapping you specify in month_weight(), and then you want to aggregate this column into a list for each group.
So, what you want is the following:
let df = df
.lazy()
.with_column(month_weight().alias("Weight")) // create new column first
.groupby_stable([col("MonthCCY")]) // then group
.agg([col("Weight").list()]); // then collect into a list per group
println!("{:?}", df.collect().unwrap());
Output:
shape: (4, 2)
┌──────────┬────────────┐
│ MonthCCY ┆ Weight │
│ --- ┆ --- │
│ str ┆ list [f64] │
╞══════════╪════════════╡
│ APRUSD ┆ [0.2, 0.2] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ MAYUSD ┆ [0.2] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ JUNEUR ┆ [0.05] │
├╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌┤
│ JULUSD ┆ [0.15] │
└──────────┴────────────┘
Also, as an aside, .when().then() can be chained indefinitely; you don't need to nest them. So just as you can write a chained if ... else if ... else if ... else, you can write col().when().then().when().then() ... .otherwise(), which is a lot simpler than nesting each additional condition.

How can I extract a verb definition as data? [duplicate]

In the console, typing a single verb without parameters will print its content:
tolower
3 : 0
x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y
($y) $ ((x{n) { (97+i.26){a.) x}t
)
That's nice for development, but unexploitable during execution. Is there a way to do that dynamically? Is there a verb that can return the contents of another verb?
For example:
showverb 'tolower'
or
showverb tolower
You can use its representation. For example the boxed representation (5!:2) of tolower is:
(5!:2) <'tolower'
┌─┬─┬────────────────────────────────────────┐
│3│:│x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y│
│ │ │($y) $ ((x{n) { (97+i.26){a.) x}t │
└─┴─┴────────────────────────────────────────┘
its linear (5!:5) is:
(5!:5) <'tolower'
3 : 0
x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y
($y) $ ((x{n) { (97+i.26){a.) x}t
)

How to define Heap datastructure in Alloy (Homework)

As a homework, I have to define a heap data structure in Alloy.
I have come up with these rules
A node can have up to 1 father, left-son, right-son, left-brother and right-brother. It also has exactly 1 value and 1 level (as in how deep in the heap it is).
A node can have right-son if it has left-son.
A node cannot be in transitive closure over any of its relations (father, left-son, right-son, left-brother, right-brother).
The relations have to point to distinct nodes.
A node has a value and values must belong to a node.
A node's value must be less than the node's sons' values.
If a node has left-son and not left-brother, then the rightmost brother of its father has a right-son.
Node is its left-brother's right-brother and so on for all its relations.
Node's father's level is one less than node's level.
If there is a node with level two less, then all the nodes with that level must have both sons.
For any 2 nodes m, n that have the same level, m must be in transitive closure over left-brother of n, or in transitive closure over right-brother.
The question is twofold
A) I am not sure whether these rules are sufficient, or whether there is a better way to solve this altogether. (I think I could just resolve this all by having node consist of index and a value and transcribe heap-in-array algorithm into Alloy, but that seems rather inelegant.)
B) I have trouble implementing some of these rules.
I have implemented rules 1, 2, 3, 4, 5, 6, 7, 8 and 9. At least I think I did, and the generated graph does not contradict my expectations.
I do not know how to implement the last 2.
Also, the code I have so far:
open util/ordering [Key] as KO
open util/ordering [Level] as LO
sig Key{}
sig Level{}
sig Node {
key: one Key,
level: one Level,
father: lone Node,
left_brother: lone Node,
right_brother: lone Node,
left_son: lone Node,
right_son: lone Node
}
// There's exactly one root
fact {
one n : Node | n.father = none
}
// Every key has to belong to some node
fact {
all k : Key | some n:Node | n.key = k
}
fact {
all n : Node | (n.left_son != none && n.right_son != none) => #(KO/nexts[n.key] & (n.left_son.key + n.right_son.key)) = 2
}
// Son's father's son shall be Son etc
fact {
all n : Node | all m : Node | (n.left_son = m) => m.father = n
}
fact {
all n : Node | all m : Node | (n.right_son = m) => m.father = n
}
fact {
all n : Node | all m : Node | (m.father = n) => (n.left_son = m || n.right_son = m)
}
// Is this redundant?
fact {
all n : Node | all m : Node | (n.left_brother = m) => (m.right_brother = n)
}
fact {
all n : Node | all m : Node | (n.right_brother = m) => (m.left_brother = n)
}
// If a node has right-son, it must have a left-son.
fact {
all n : Node | (n.right_son != none) => (n.left_son != none)
}
// node having left son and left brother means that his left brother has a right son
fact {
all n: Node | (n.left_son != none && n.left_brother != none) => (n.left_brother.right_son != none)
}
// nodes father must be a level higher.
fact {
all n : Node | (n.father != none) => (LO/prev[n.level] = n.father.level)
}
// FIXME: this is wrong: There needs to be difference of 2 levels, not just a single level.
fact {
all n : Node | all m : Node | (LO/prevs[m.level] & n.level = n.level) => (n.left_son != none && n.right_son != none)
}
// TODO: If 2 nodes are in the same level, then they must be in left-brother* or right-brother* relation
// ????
// No node can be its own father
fact {
all n : Node | n.father != n
}
// No node can be in transitive closure over its ancestors
fact {
no n : Node | n in n.^father
}
// No node cannot be its own brother, son, etc...
fact {
all n: Node | n.left_brother != n
}
// Nor in its transitive closure
fact {
no n: Node | n in n.^left_brother
}
fact {
all n: Node | n.right_brother != n
}
fact {
no n: Node | n in n.^right_brother
}
fact {
all n: Node | n.left_brother != n
}
fact {
no n: Node | n in n.^left_brother
}
fact {
all n: Node | n.right_son != n
}
fact {
no n: Node | n in n.^right_son
}
fact {
all n: Node | n.left_son != n
}
fact {
no n: Node | n in n.^left_son
}
// All node relatives have to be distinct
fact {
all n: Node | n.left_son & n.right_son = none && n.left_brother & n.right_brother = none && (n.left_brother + n.right_brother) & (n.left_son + n.right_son) = none
&& (n.right_son + n.left_son + n.left_brother + n.right_brother) & n.father = none
}
run{}
For 10. something along the lines of
all m : Node | some father.father.m implies some m.left and m.right
would work, which is equivalent to
fact {
all m, n : Node | (n.father.father != none && n.father.father.level = m.level) => (m.left_son != none && m.right_son != none)
}
For 11., you can formulate it quite straightforwardly from the textual definition (of course, with using appropriate operators, namely for transitive closure).
As a general suggestion, try not to formulate such direct questions about homework problems (see this discussion). Since this answer comes pretty late, I think it's fine to try to give you some hints.

How to list the code of a verb in J

In the console, typing a single verb without parameters will print its content:
tolower
3 : 0
x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y
($y) $ ((x{n) { (97+i.26){a.) x}t
)
That's nice for development, but unexploitable during execution. Is there a way to do that dynamically? Is there a verb that can return the contents of another verb?
For example:
showverb 'tolower'
or
showverb tolower
You can use its representation. For example the boxed representation (5!:2) of tolower is:
(5!:2) <'tolower'
┌─┬─┬────────────────────────────────────────┐
│3│:│x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y│
│ │ │($y) $ ((x{n) { (97+i.26){a.) x}t │
└─┴─┴────────────────────────────────────────┘
its linear (5!:5) is:
(5!:5) <'tolower'
3 : 0
x=. I. 26 > n=. ((65+i.26){a.) i. t=. ,y
($y) $ ((x{n) { (97+i.26){a.) x}t
)

Resources