Sum of nested values in Alloy - alloy

I'm starting with definitions similar to these below
sig Sub { vals : set Int }
sig Top { subs : set Sub }
I'd like an expression that can produce the sum of all values contained inside something of type Top. Top when written as a nested set, would be something like {{3, 4}, {7}}. The result of the nested sum in this case should be 14.
This function of course just gives the number of elements in the outer set.
fun allsum[t: Top] : one Int { #t }
I believe I need to use the built-in sum function and a set comprehension, but Alloy syntax is still somewhat arcane to me.

For this, you need a nested sum expression:
fun allsum[t: Top] : Int {
sum s: t.subs | (sum v: s.vals | v)
}
The general format is:
sum e: <set> | <expression involving e>

Related

sort strings according to the highest

can I combine below closures into one or do this in a more functional and elegant way in groovy. I am using the sortMethod in some other places( for testing purpose) too.
for eg : countAndMap should take
["a b c a a c" , "b b c"] and return[x1 : [a:3,c:2,b:1] , x2 : [b:2,c:1]]
def countAndMap(List<String> stringList) {
stringList.withIndex().collect { String s, Integer i -> [(num.call(i)): count.call(s)] }
}
Closure count = {sortMethod.call(it.split().countBy {it}) }
Closure sortMethod = { it.sort { x, y -> x.value <=> y.value } }
Closure num = { "x ${it + 1}".toString()}
there are no errors but I wonder if it's possible to do it in a more functional way
I am not sure what you mean with "more functional", but you could use a fold operation (called inject in groovy):
list = ["a b c a a c" , "b b c"]
def createSortedHistogram(String toCount) {
toCount
.split() // Create list of words
.inject([:]){ acc, word -> acc[word] = 1 + (acc[word] ?: 0);acc} // create histogram
.sort{-it.value} // sort histogram map by value desc
}
def countAndMap(List<String> list) {
list.withIndex().collectEntries{ sublist, i -> ["x ${i+1}": createSortedHistogram(sublist)] }
}
countAndMap(list)
I think the most interesting part is the inject method.
This solution uses the initial value [:] in order to use a map as result. In each iteration the inject operation either adds a new entry with value 1 to the map (if the word/key does not exist in the map) or increases the value of the word/key if it is already present in the map.
See the inject definition from Collections GroovyDoc.
public Object inject(Object initialValue, Closure closure) - Iterates through the given Collection, passing in the initial value to the 2-arg closure along with the first item. The result is passed back (injected) into the closure along with the second item. The new result is injected back into the closure along with the third item and so on until the entire collection has been used. Also known as foldLeft or reduce in functional parlance.

sort list of maps in grovvy

Hi I have a list of maps in groovy like
def v=[[val1:'FP'],[val1:'LP'],[val1:'MP'],[val1:'MP'],[val1:'LP'],[val1:'FP']]
I wanted to sort based on the following order FP,MP,LP
I tried doing
v.sort{x,y->
x.val1 <=> y.val1
}
which prints [[val1:FP], [val1:FP], [val1:LP], [val1:LP], [val1:MP], [val1:MP]] which is sorted alphabetically, but I need it to be sorted in the following format
FP,MP,LP
An alternative: Whenever I am dealing with a fixed, ordered list of strings I immediately think of using enums instead:
enum PValue { FP, MP, LP }
Now we have an ordered set of constants that readily converts to and from string values. So sorting looks as simple as this:
v.sort { x, y -> PValue[x.val1] <=> PValue[y.val1] }
EDIT: Or even simpler:
v.sort { PValue[it.val1] }
As has been said int the comments, you need to define a preferred order, and then sort based on that... so with your list of maps:
def v=[[val1:'FP'],[val1:'LP'],[val1:'MP'],[val1:'MP'],[val1:'LP'],[val1:'FP']]
And a preferred order of results:
def preferredOrder = ['FP', 'MP', 'LP']
You can then sort based on the values index into this preferred order:
v.sort(false) { preferredOrder.indexOf(it.val1) }
Or, if you want unknown elements (ie: [val1:'ZP']) to go at the end of the sorted list, then you an do:
v.sort(false) { preferredOrder.indexOf(it.val1) + 1 ?: it.val1 }
So if they are not found (index -1) then they are compared on their String name
This question is similar to this one btw, which has more options in the answer

disjoint union and Cartesian product in Alloy

I have two set comprehension predicates (uniary) as bellow in Alloy:
pred A (o : Object){ .. }
pred B (o : Object) { ..}
I would like to define predicates, one of which is disjoint union and another one is Cartesian product of A and B.
PS: To define their union and intersection I can define the following predicate:
pred Union(o : Object){
A[o] or B[o]
}
pred Inter(o:Object){
A[o] and B[o]
}
I would like to get similar predicates for Cartesian product and disjoint union.
Thanks
You may be conflating the concepts of predicates and the concepts of sets. You have good company (Frege, for one), but it turns out to be dangerous.
The expressions o in A[o] and o in B[o] should raise a type error, since if A and B are predicates, then the expressions A[o] and B[o] should evaluate to true or false, and not to sets of which o could conceivably be a member.
If you want a predicate U which is true of an object when either A or B or both are true for that object, then you want something like
pred U[o : Object] { A[o] or B[o] }
And if you want an exclusive disjunction -- I assume that this is what you mean when you speak of a disjoint union -- then
pred X[o : Object] { (A[o] and not B[o]) or (B[o] and not A[o]) }
If you want the sets for which A, B, and X are true, then you want to write
{ o : Object | A[o] }
{ o : Object | B[o] }
{ o : Object | X[o] }
The third of these can of course be written
{ o : Object | (A[o] and not B[o]) or (B[o] and not A[o]) }
The set comprehension notation (again, I encourage you to read the relevant documentation) can also handle sets of tuples; the Cartesian product of the sets of objects satisfying A and B would be written this way:
{ a, b : Object | A[a] and B[b] }
Here is the solution to what I was looking for:
cartesian product of A and B are defined as A * B = {(a,b) | a in A and b in B}. So putting it in Alloy syntax with set comprehension expression would be as follows:
pred ACartesB(o1:Object, o2: Object){
A[o1] and B[o2]
}
disjoint union of A and B are defined as A+B= {(a,1) union (b,2) | a in A and b in B}. 1 and 2 are indexes to distinguish the same elements of A and B in A+B. So putting it in alloy context would be as the following:
pred AdisjUnionB(o:Object, i: Int){
(A[o] and i=1) or (B[o] and i=2)
}
PS:
we assume that we have sig Object {} in our signature.

Use literal operators (eg "and", "or") in Groovy expressions?

My current work project allows user-provided expressions to be evaluated in specific contexts, as a way for them to extend and influence the workflow. These expressions the usual logical ones f. To make it a bit palatable for non-programmers, I'd like to give them the option of using literal operators (e.g. and, or, not instead of &, |, !).
A simple search & replace is not sufficient, as the data might contains those words within quotes and building a parser, while doable, may not be the most elegant and efficient solution.
To make the question clear: is there a way in Groovy to allow the users to write
x > 10 and y = 20 or not z
but have Groovy evaluate it as if it were:
x > 10 && y == 20 || !z
Thank you.
Recent versions of Groovy support Command chains, so it's indeed possible to write this:
compute x > 10 and y == 20 or not(z)
The word "compute" here is arbitrary, but it cannot be omitted, because it's the first "verb" in the command chain. Everything that follows alternates between verb and noun:
compute x > 10 and y == 20 or not(z)
───┬─── ──┬─── ─┬─ ───┬─── ─┬─ ──┬───
verb noun verb noun verb noun
A command chain is compiled like this:
verb(noun).verb(noun).verb(noun)...
so the example above is compiled to:
compute(x > 10).and(y == 20).or(not(z))
There are many ways to implement this. Here is just a quick & dirty proof of concept, that doesn't implement operator precedence, among other things:
class Compute {
private value
Compute(boolean v) { value = v }
def or (boolean w) { value = value || w; this }
def and(boolean w) { value = value && w; this }
String toString() { value }
}
def compute(v) { new Compute(v) }
def not(boolean v) { !v }
You can use command chains by themselves (as top-level statements) or to the right-hand side of an assignment operator (local variable or property assignment), but not inside other expressions.
If you can swap operators like > and = for the facelets-like gt and eq, respectively, i THINK your case may be doable, though it will require a lot of effort:
x gt 10 and y eq 20 or not z
resolves to:
x(gt).10(and).y(eq).20(or).not(z)
And this will be hell to parse.
The way #Brian Henry suggested is the easiest way, though not user-friendly, since it needs the parens and dots.
Well, considering we can swap the operators, you could try to intercept the Integer.call to start expressions. Having the missing properties in a script being resolved to operations can solve your new keywords problem. Then you can build expressions and save them to a list, executing them in the end of the script. It's not finished, but i came along with this:
// the operators that can be used in the script
enum Operation { eq, and, gt, not }
// every unresolved variable here will try to be resolved as an Operation
def propertyMissing(String property) { Operation.find { it.name() == property} }
// a class to contain what should be executed in the end of the script
#groovy.transform.ToString
class Instruction { def left; Operation operation; def right }
// a class to handle the next allowed tokens
class Expression {
Closure handler; Instruction instruction
def methodMissing(String method, args) {
println "method=$method, args=$args"
handler method, args
}
}
// a list to contain the instructions that will need to be parsed
def instructions = []
// the start of the whole mess: an integer will get this called
Integer.metaClass {
call = { Operation op ->
instruction = new Instruction(operation: op, left: delegate)
instructions << instruction
new Expression(
instruction: instruction,
handler:{ String method, args ->
instruction.right = method.toInteger()
println instructions
this
})
}
}
x = 12
y = 19
z = false
x gt 10 and y eq 20 or not z
Which will give an exception, due the not() part not being implemented, but it can build two Instruction objects before failing:
[Instruction(12, gt, 10), Instruction(19, eq, 20)]
Not sure if it is worth it.
The GDK tacks on and() and or() methods to Boolean. If you supplied a method like
Boolean not(Boolean b) {return !b}
you could write something like
(x > 10).and(y == 20).or(not(4 == 1))
I'm not sure that's particularly easy to write, though.

How can I sort a list of strings in Dart?

I see in the API docs there is a sort() method on List, but I'm not clear what it needs for a parameter. The current need is for a very simple straight up alpha comparison.
1. A Quick Solution
Thanks for the question! You can sort a list of Strings like this:
main() {
final List<String> fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort();
print(fruits);
}
The above code prints:
[apples, bananas, oranges]
2. Slightly more advanced usage
Notice that sort() does not return a value. It sorts the list without creating a new list. If you want to sort and print in the same line, you can use method cascades:
print(fruits..sort());
For more control, you can define your own comparison logic. Here is an example of sorting the fruits based on price.
main() {
final List<String> fruits = <String>['bananas', 'apples', 'oranges'];
fruits.sort((a, b) => getPrice(a).compareTo(getPrice(b)));
print(fruits);
}
Let's see what's going on here.
A List has a sort method, which has one optional parameter: a Comparator. A Comparator is a typedef or function alias. In this case, it's an alias for a function that looks like:
int Comparator(T a, T b)
From the docs:
A Comparator function represents such a total ordering by returning a negative integer if a is smaller than b, zero if a is equal to b, and a positive integer if a is greater than b.
3. How to do it with a list of custom objects
Additionally, if you create a list composed of custom objects, you could add the Comparable<T> as a mixin or as inheritance (extends) and then override the compareTo method, in order to recreate the standard behavior of sort() for your list of custom objects. For more info, do check out this other, related StackOverflow answer.
Here is the one line code to achieve it.
fruits.sort((String a, String b)=>a.compareTo(b)); //fruits is of type List<String>
For Sorting Simple List of Integers or Strings:
var list = [5 , -5 ,1];
list.sort(); //-5 , 1 , 5
For Reversing the list order:
list.reversed;
For Sorting List of Objects or Map by field of it:
List<Map<String, dynamic>> list= [
{"name": "Shoes", "price": 100},
{"name": "Pants", "price": 50},
];
// from low to high according to price
list.sort((a, b) => a["price"].compareTo(b["price"]));
// from high to low according to price
list.sort((a, b) => b["price"].compareTo(a["price"]));
To add just one point to Seth's detailed answer, in general, in
(a, b) => foo(a, b)
passed into sort, the function foo should answer an integer result as follows:
if a < b, result should be < 0,
if a = b, result should be = 0, and
if a > b, result should be > 0.
For the above law of trichotomy to hold, both a and b must be Comparables.
use compareAsciiUpperCase instead of compareTo, as it supports strings and automatically ignores case sensitive:
import "package:collection/collection.dart";
data.sort((a, b) {
return compareAsciiUpperCase(a.name, b.name);
});
After today, you should just be able to do list.sort() .
The sort method's argument is now optional, and it defaults to a function that calls compareTo on the elements themselves. Since String is Comparable, it should Just Work now.
How I have solved this problem.
List<Product> _dataSavingListProducts = [];
List<Product> _dataSavingListFavoritesProducts = [];
void _orderDataSavingLists() {
_dataSavingListProducts.toList().reversed;
_dataSavingListFavoritesProducts.toList().reversed;
}

Resources