Provide Alloy with a "pool" of custom Strings - alloy

I'm interested in using the String type of Alloy, (especially due to the fact it allows the use of special character).
I noticed that in order to add a given String to an instance, it is sufficient to include it in an expression. e.g.
fact stringInsert{
none!="a"+"b"+"c"
}
will lead to the creation of atoms "a","b" and "c" in any generated instances.
Now my question is, is there a way to declare a pool of strings,defining all possible string atoms that might occur in satisfiable instances, BUT whose number respect the scope given and can be further constrained ?
As an example, if we consider the above fact as declaring a pool of string atom {"a","b","c"}, I would like instances obtained from the execution of a model using this pool with a global scope of 2 to only contain two of those three strings "a","b", and "c".

You can only declare an exact scope for String, e.g.,
run {} for 3 but exactly 5 String
It is currently not possible to only give an upper bound for Strings, e.g., for 5 String, and ask Alloy to find a solution (with respect to other constraints) with up to 5 strings. So if you try to set the scope for String to 2 in your example above, you will still get all 3 string literals declared in your model ("a", "b", "c"), which is consistent with string literals being "one sigs" extending the abstract String sig; if on the other hand you set the scope to 5, Alloy will generate 2 additional string atoms, "String$0" and "String$1".

Related

Any vs Nested Concrete type in Kotlin Collections

is using Any as collection type consume less memory than using concrete type?
suppose
val list1 = listOf<Any>("ABC", "DEF", "GHI", "JKL", "MNO")
val list2 = listOf<String>("ABC", "DEF", "GHI", "JKL", "MNO")
i wonder if list1 consume less memory than list2 since String type allocates memory to store its properties (e.g size)
So, is it better to use list1 if i dont use any String type function?
EDIT
what if i want to use other type in the collection?
list = listOf<Any>("ABC", 123, 12.34)
is it more efficient than
list = listOf<String>("ABC", "123", "12.34")
EDIT 2
thanks to #João Dias and #gidds
as #gidds says :
the list does not directly contain String objects, or Any objects — it contains references.
And a String reference is exactly the same size as an Any reference or a reference of any other type. 
So, The List<String> and List<Any> are the exactly the same because of the Type Erasure --which pointed out by #João Dias-- with a difference of compile-time & runtime type
but, does it mean that
val list1 = listOf<Any>("ABC", "DEF", "GHI")
and
val list2 = listOf<String>("ABC", "DEF", "GHI")
is consuming the same memory as
val list3 = listOf<List<List<List<String>>>>(
listOf(listOf(ListOf("ABC"))),
listOf(listOf(ListOf("DEF"))),
listOf(listOf(ListOf("GHI")))
)
AFAIK, String is basically collections of Char. A String contains a reference to the Char. And since everything is an object in Kotlin, then every Char inside the String should contain a reference to the value in the heap, am i correct up to here?
if thats the case, doesnt it make sense that List<String> consume more memory than List<Any> because List<String> is having more than 1 reference.
A point not addressed so far is that the list does not directly contain String objects, or Any objects — it contains references.
And a String reference is exactly the same size as an Any reference or a reference of any other type. (That size depends on the internals of the JVM running the code; it might be 4 or 8 bytes. See these questions.)
Of course, the objects being referred to will also take up their own space in the heap; but that will be the same in both cases.
EDITED TO ADD:
The internal details of how List and String are implemented is irrelevant to the original question. (Which is good, coz they vary between implementations.) JVM languages (such as Kotlin) have only two kinds of value: primitives (Int, Short, Long, Byte, Char, Double, Float, Boolean), and references (to an object or an array).
So any collection, if it's not a collection of primitives, is a collection of references. That applies to all List implementations. So your list1 and list2 objects will be exactly the same size, depending only on the number of references they hold (or can hold), not on what's in those references.
If you want a deeper picture, list1 is a reference, pointing to an object which implements the List interface. There are many different implementations, and I don't know off-hand which one Kotlin will pick (and again, that might change between versions), but say for example it's an ArrayList. That has at least two properties: a size (which is probably an Int), and a reference to an array which holds the references to the items in the list. (The array will usually be bigger than the current size of the list, so that you can add some more items without having to re-allocate the array each time; the current size of the array is known as the list's capacity.) If those items are Strings, then the exact internal representation depends on the JVM version, but it might be an object with at least three properties: an array of Char, an Int giving the start index of the string within the array, and another Int giving either the length.
But as I said, the details change over time and between JVM versions. What doesn't change is that List is a collection of references, and the size of a reference doesn't depend on its type. So a list of String references will (all other things being equal) take exactly the same space as a list of Any references to those same strings.
(And, as has been mentioned elsewhere, due to type erasure at runtime the JVM has no concept of type parameters, and so the objects will in fact be identical.)
Of course, the ‘deep size’ (the overall heap space taken up by the list and the objects it contains) will depend upon the size of those objects — but in the case we're discussing, those are the exact same String objects, so there's no difference in size there either.
It does not make any difference in memory consumption. You are building the exact same list with exactly the same content. Additionally, there is a thing called type erasure that goes something like this:
Type erasure can be explained as the process of enforcing type
constraints at compile-time and discarding the element type
information at runtime.
This means that at runtime, there is no List<String> or List<Any> just List making no difference whatsoever if you use the first or the second in regards to memory consumption. In regards to code readability, maintainability and robustness you definitely should go with List<String>. Given that in Kotlin lists exposed as List are read-only by default (thanks #Alex.T and #Tenfour04 for the hints, Lists can only be considered immutable if the elements in them are also immutable and if the concrete implementation of List is indeed immutable, e.g., consider a list : List<String> property with an underlying mutable ArrayList<String> then list is still not completely immutable since a since cast allows you to add or remove elements from it (list as ArrayList<String>).add("new-element")) you basically have only disadvantages on using List<Any> (because then if you want to iterate or use any of its elements all you will know at that time is that it is Any element which is way harder to work with than a specific type like String).

Why a function can be a literal and a expression can't?

I understand that the concept literal is applied to whenever you represent a fixed value in source code, exactly as it is meant to be interpreted, vs. a variable or a constant, which are names for several of a class or one of them respectively.
But they are also opposed to expressions. I thought it was because they could incorporate variables. But even expressions like 1+2 are not (see first answer in What does the word "literal" mean?).
So, when I define a variable this way:
var=1+2
1+2 is not a literal even though it is not a name and evaluates to a single value. I could then guess that it is because it doesn't represent the target value directly; in other words, a literal represents a value "exactly as it is".
But then how is it possible that a function like this one is a literal (as pointed it the same linked answer)?
(x) => x*x
Only anonymous functions can be literal because they are not bound to an identifier
so (x)=>x*x is a literal because it is a anonymous function,or function literal
but a
void my_func()
{#something}
is not a literal cause it is bound to an identifier;
read these,
https://en.wikipedia.org/wiki/Literal_(computer_programming)
https://en.wikipedia.org/wiki/Anonymous_function
Expressions can be divided into two general types: atomic expressions and composite expressions.
Composite expressions can be divided by operator, and so on; atomic expressions can be divided into variables, constants, and literals. I guess different authors might use other categories or boundaries here, so it might not be universal. But I will argue why this categorization might make sense.
It's fairly obvious why strings or numbers are literals, or why a sum isn't. A function call can be considered composite, as it operates on subexpressions - its parameters. A function definition does not operate on subexpressions. Only when the so defined function is called, that call passes parameters into the function. In a compiled language, the anonymous function will likely be replaced by a target address where the corresponding code is located - that memory location is obviously not dependent on any subexpression.
#rdRahul's answer references this Wikipedia article, which says that object literals, such as {"cat", "dog"} can be considered literals. This can be easily argued by pointing out that the object which is the value of the expression is just one opaque thing, such as a pointer to the memory location of the object.

Why is the keyword `string` used to verify a variable type

For example, suppose we have a variable named i and set to 10. To check if it is an integer, in tcl one types : string is integer $i.
Why is there the keyword string ? Does it mean the same as in python and C++ ? How to check if a tcl string (in the meaning of a sequence of characters) is a string ? string is string $myString does not work because string is not a class in tcl.
Tcl doesn't have types. Or rather it does, but they're all serializable to strings and that happens magically behind the scenes; it looks like it doesn't have types, and you're not supposed to talk about them. Tcl does have classes, but they're not used for types of atomic values; something like 1.3 is not an instance of an object, it's just a value (often of floating point type, but it could also be a string or a singleton list or version identifier, or even a command name or variable name if you really want). Tcl's classes define objects that are commands, and those are (deliberately!) heavyweight entities.
The string is family of tests check whether a value meets the requirements for being interpreted as a particular kind of value. There's quite a few kinds of value, some of which make no sense as types at all (e.g., an all-uppercase string). There's nothing for string is string because everything you can ask that about would automatically pass; all values are already strings, or may be transparently converted to them.
There's exactly one way to probe what the type of a value currently is, and that is the command ::tcl::unsupported::representation (8.6 only). That reports the current type of a value as part of its output, and you're not supposed to rely on it (there's quite a few types under the hood, many of which are pretty obscure unless you know a lot about Tcl's implementation).
% set s 1.3
1.3
% ::tcl::unsupported::representation $s
value is a pure string with a refcount of 4, object pointer at 0x100836ca0, string representation "1.3"
% expr {$s + 3}
4.3
% ::tcl::unsupported::representation $s
value is a double with a refcount of 4, object pointer at 0x100836ca0, internal representation 0x3ff4cccccccccccd:0x0, string representation "1.3"
As you can see, types are pretty flexible. You're supposed to ignore them. We mean it. Make your code demand the types it needs, and throw an error if it can't get them. That's what Tcl's C API does for you.

Why is it illegal for variables to start with numbers?

Why is it illegal for variables to start with numbers?I know it's a convention but what's the reason?
Edit:
I mean variables like "1foo" or "23bar" not only numbers like "3"
Because the lexer in most languages will assume you are trying to specify a numeric literal. And then you could declare variables that are indistinguishable from numeric literals, creating a huge bombshell of ambiguity.
Pop quiz: in a hypothetical language that permits a variable to begin with a number, what is this?
0xDEADBEEF
In C (and related languages) this can only be a hexadecimal number. If a language allows a variable name to begin with a digit, that could be a variable or a hexadecimal number. That's one quick example of potentially millions.
Numbers are interpreted 'as is' without any syntax whereas strings/characters are mostly represented with quotes.
So, the program can understand the difference between a variable name containing characters and a string of characters but it does not goes the same with numerals.
One reason, probably the most obvious one, is that it would make your life more difficult, without bringing anything reasonably useful to the table. For example, in C, you wouldn't be able to tell whether a string of digits is an identifier or a numeric literal.
int 10 = 15;
int 15 = 10 + 5;
In the second line, is 10 a variable holding the numeric literal 15 or is it the numeric literal 10?
Another reason is that allowing a variable name to begin with a digit makes error checking during compilation a lot more complicated, again, without bringing anything reasonably useful to the table.
In languages such as Prolog, Erlang, and some early versions of Fortran, you very nearly got to do this, for completely different reasons.
Prolog/Erlang don't have variable assignment, they have unification. IIRC, if X is a variable, then code following 2 = X, or X = 2 is processed if X may have the value 2. So if X is already unified with a value, then that value must be 2, and if not, X becomes 2 from then on. So writing 3 = 3 is fine - it should become a no-op, and 2 = 3 always fails - either a non-match in Prolog or (I think) a runtime error in Erlang. Numbers behave like variables which have already been unified with the value the numbers represent.
In early Fortran ( apologies for not having used fortran in twenty years and forgetting its syntax ), all function arguments were passed by reference, so if you have a function which was equivalent to void foo ( int &x ) { x = 3; } and called it with a number, the compiler would store the number in a static variable and pass that. So calling foo (2) would set that static stored value of 2 to 3. If it happened to use the same static variable for the literal 2 somewhere else, such as calling another function with the literal 2, then the value passed to the second function would be 3 instead.
So you can have variables which are syntactically identical to numbers, as long as they are automatically initialised to the value of the literal. But if you allow them to be mutable rather pure variables, weirdness abounds.

What is a strictly typed language? [duplicate]

This question already has answers here:
What are the key aspects of a strongly typed language?
(8 answers)
Closed 1 year ago.
What is a strictly typed language?
Strictly typed languages enforce typing on all data being interacted with.
For example
int i = 3
string s = "4"
From here on out, whenever you use i, you can only interact with it as an integer type. That means you are restricted to using with methods that work with integers.
As for string s you can only interact with it as a string type. You can concatenate it with other string, print it out, etc. However, even though it contains that character "4", you cannot add to an integer without using some function to convert the string to an integer type.
In a dynamically typed language, you have a lot more flexibility:
i = 3
s = "4"
Types are inferred; meaning they are determined based on the data they are set to. i is obstensively a number type, and s is a string type, based on how they were set. However when you have i + s; type inference is used and depending on your environment, you may get the result i + s = 7; since s was implicitly converted to an int by the programming environment. However, this operation could also result in the string "34", if the environment infers an int + string should equal a concatenation operation vs an addition operation.
This flexibility has made loosely typed languages very popular. However, because these type inference can sometimes produce unexpected results; they can also result in more bugs in your code if you're not careful. In a typed language, if I perform i + s, I am forced by the compiler to change s into an int first, so I know by adding i to s, I will get 7 because I was forced to convert s to an explicit int first. In a dynamic language, it attempts to do this for you implicitly, but the results may not be what you were expecting, since anything can be in i or s; a string, a number, or even an object. You don't know until you run your code and see what happens.
I tried to look up "strict typing" and wasn't able to find a definitive definition for the term. Perhaps it refers to a strongly typed language?
Strong typing refers to a type system in which there are restrictions to the operation on which two variables of different types can be performed. For example, in a very strongly typed language, trying to add a string and number may lead to an error.
string s;
number n;
s + n; <-- Type error.
The error may occur at compile time for statically typed languages or at runtime for dynamically typed languages. It should be noted that static/dynamic and strong/weak may sound like similar concepts, they are quite different.
A less strongly typed language may allow casting of variables to allow operations between variables originating from different types:
s + (string)n; <-- Allowed, as (number) has been explicitly
casted to (string), so variable types match.
In a weakly typed language, variables of differing types may become automatically casted to compatible types.
s + n; <-- Allowed, where the language will cast
the (number) to (string)
Perhaps, the "strictly typed language" refers to a very strongly typed language in which there are more strict restrictions as to how operations can be performed on variables of different types.
There's dissenting opinions about how strong or weak various type systems are, but I've generally heard "strictly typed programming language" to mean a very strongly typed programming language. This often describes the static type systems found in several functional languages.
Languages where variables must be declared to contain a specific type of data.
If your variable declarations look like:
String myString = "Fred";
then your language is strictly typed, variable "myString" is explicitly declared to contain only string data.
If the following works:
x = 10;
x = "Fred";
then it's loosely typed (two different types of data in the same variable and scope).
languages where '1' + 3 would be illegal, because it's adding a string to an integer.

Resources