What is the size of an LTL formula? - model-checking

What is generally meant by the size of an LTL formula, |p|, in terms of complexity? Number of atomic propositions, depth or something else?
Thanks in advance!!

In terms of complexity it makes sense to count the number of X and U operators used in the formula. Please note that you can regard operators like F, G, R and W as syntactic sugar that uses U (see Syntax of LTL).
Justification:
When model checking the system you have to consider each possible future for each state of the system. So you have to consider that a sub-formula of the form X... or ...U... might be true or false. Thus, you have 2^n possibilities for each state, where n is the number of X and U operators.
More precisely, when you use e.g. Lichtenstein and Pnueli's algorithm to verify the formula, you search for strongly connected components (SCC) in a graph of a size <= s*2^n with s being the number of states.
If your LTL syntax allows past operators, too, then you can add the operators Y and S analogously.

Related

Why are OpenMP Reduction Clauses Non-deterministic for Statically Scheduled Loops?

I have been working on a multi-GPU project where I have had problems with obtaining non-deterministic results. I was surprised when it turned out that I obtained non-deterministic results due to a reduction clause executed on the CPU.
In the book Using OpenMP - The Next Step it is written that
"[...] the order in which threads combine their value to construct the
value for the shared result is non-deterministic."
Maybe I just don't understand how the reduction clauses are implemented. Does it mean that if I use schedule(monotonic:static) in combination with a reduction clause each thread will execute its chunk of the iterations in a deterministic order, but that the order in which the partial results are combined at the end of the parallel region is non-deterministic?
Does it mean that if I use schedule(monotonic:static) in combination
with a reduction clause each thread will execute its chunk of the
iterations in a deterministic order, but that the order in which the
partial results are combined at the end of the parallel region is
non-deterministic?
It is known that the end result is non-determinist, detailed information can be found in:
What Every Computer Scientist Should Know about Floating Point Arithmetic. For instance:
Another grey area concerns the interpretation of parentheses. Due to roundoff errors, the associative laws of algebra do not necessarily hold for floating-point numbers. For example, the expression (x+y)+z has a totally different answer than x+(y+z) when x = 1e30, y = -1e30 and z = 1 (it is 1 in the former case, 0 in the latter).
Now regarding the order in which the threads perform the reduction action, as far as I know, the OpenMP standard does not enforce any order, or requires that the order has to be deterministic. Hence, this is an implementation detail that is left up to the compiler that is implementing the OpenMP standard to decide, and consequently, it is something that your code should not reply upon.
Programming language semantics usually declares that a+b+c+d is evaluated as ((a+b)+c)+d. This is not parallel, so an OpenMP reduction is probably evaluated as (a+b)+(c+d). And so on for larger numbers of summands.
So you immediately have that, because of the non-associativity of floating point arithmetic, the result may be subtly different from the sequential value.
But more importantly, the exact value will depend on precisely how the combination is done. Is it a+(b+c) (on 2 threads) or (a+b)+c? So the result is at least "indeterministic" in the sense that you can not reconstruct how it was formed. It could probably even be done in two different ways, if you run the same reduction twice. That's what I would call "non-deterministic", but look in the standard for the exact definition of the term.
By the way, if you want to get some idea of how OpenMP actually does it, write your own reduction operator, and let each invocation print out what it computes. Here is a decent illustration: https://victoreijkhout.github.io/pcse/omp-reduction.html#Initialvalueforreductions
By the way, the standard actually doesn't use the word "non-deterministic" for this case. The following passage explains the issue:
Furthermore, using different numbers of threads may result in
different numeric results because of changes in the association of
numeric operations. For example, a serial addition reduction may have
a different pattern of addition associations than a parallel
reduction.

Should I use n or * if I have exact number of things in the model?

I need to create UML diagrams for homework about a game ( called Downfall). I have to create it so that it works on any number (n) of player.
If this is an exact number that appears in multiple places of the diagram, should I use n or *? I would use it in multiplicity parameters and in size of array.
For example: There are n sides, and if there is a dial on a side, there has to be dial on each side at that position, so the dial has n-1 connected dials.
TL;DR
You can use a constant, like n. I would though recommend using a self-explanatory constant name like numberOfPlayers or at least noOfPlayers to make it obvious that it is always the same constant.
The name of the constant should be written without quotes (to distinguish it from strings, which are presented in double-quotes).
You can also use expression like n-1 as long as it evaluates to a non-negative Integer all the time.
Full explanation
Let's go by the UML specification. All section and figure references are from it.
1. Multiplicity definition (7.5.3.2)
The multiplicity is defined as lowerValue and upperValue.
The lower and upper bounds for the multiplicity of a MultiplicityElement are specified by ValueSpecifications (see Clause 8), which must evaluate to an Integer value for the lowerBound and an UnlimitedNatural value for the upperBound (see Clause 21 on Primitive Types)
2. ValueSpecification definition
ValueSpecification is defined as either LiteralSpecification (8.2) or Expression or OpaqueExpression (both described in 8.3).
LiteralSpecification is essentially just a number in the case interesting for us, so it is not what you need. But it is not the only option as www.admiraalit.nl suggests in his answer.
3. Expression definition (8.3.3.1)
An Expression is a mechanism to provide a value through some textual representation and eventually computation (I'm simplifying here). For instance:
An Expression is evaluated by first evaluating each of its operands and then performing the operation denoted by the Expression symbol to the resulting operand values
If you use a simple expression without operands, it simply becomes a constant that is a template for your model. So feel free to use a constant as a multiplicity value, as long as the constant evaluates to non-negative Integer (or UnlimitedNatural in case of an upper Limit).
It may even be an expression that changes its value over the lifecycle of the object however ensuring that this kind of multiplicity is met all the time might become challenging.
According to the UML specification, n is syntactically a valid multiplicity (see Ister's answer), but to make sure it is also semantically correct, you would have to define the meaning of n somewhere. Usually, n is not used as a multiplicity in UML diagrams.
I would advise you to use * in this case. If the minimum number of players is 2, you may use 2..*.
Additionally, you may use notes or constraints, e.g. { the number of connected dials is equal to the number of sides minus one }. You may also use a formal constraint language, like OCL.

Calculate number of nodes from numbers of arcs in a tree - Induction

If a tree has k arcs, how many nodes does it have?
Base case:
If k=0 => n=(k+1)=1
Inductive hypothesis: For every k, n=(k+1) is true
Proof:
Is it true for k=1?
k=n-1
1=n-1
1=(k+1)-1
k=1,so:
1=1+1-1
1=1
Proved?
Am I missing something?
You never want to use 0 or 1 as your base case for proof by induction
If k=0 => n=(k+1)=1
You can prove anything you want if you use 0 (or often 1) as your base case. The classic example of this being that all horses are the same color. This is your mistake.
In addition, you can make graphs with the same number of arcs have different numbers of nodes, which immediately shows that you are not going to be able to use proof by induction to solve your problem.
Good luck!

Power operator inconsistency

I hope this won't end as philosophical question, but which of theese is the right result of (2^5^2)
Excel:
Matlab:
Wolfram|Alpha: http://www.wolframalpha.com/input/?i=2%5E5%5E2
33554432
I know I can add braces to get desired behavior, but I want to know why those Math softwares are implementing it differently?
In MATLAB operators of equal precedence are always evaluated left to right which explain the result you are seeing. The same is true with Excel.
In essence they are assuming that operations are always left associative. Wolfram alpha, as well as Mathematica define exp. as right associative which afaik is more 'correct' mathematically. In doubt use parenthesis.

Why do most programming languages only give one answer to square root of 4?

Most programming languages give 2 as the answer to square root of 4. However, there are two answers: 2 and -2. Is there any particular reason, historical or otherwise, why only one answer is usually given?
Because:
In mathematics, √x commonly, unless otherwise specified, refers to the principal (i.e. positive) root of x [http://mathworld.wolfram.com/SquareRoot.html].
Some languages don't have the ability to return more than one value.
Since you can just apply negation, returning both would be redundant.
If the square root method returned two values, then one of those two would practically always be discarded. In addition to wasting memory and complexity on the extra return value, it would be little used. Everyone knows that you can multiple the answer returned by -1 and get the other root.
I expect that only mathematical languages would return multiple values here, perhaps as an array or matrix. But for most general-purpose programming languages, there is negligible gain and non-negligible cost to doing as you suggest.
Some thoughts:
Historically, functions were defined as procedures which returned a single value.
It would have been fiddly (using primitive programming constructs) to define a clean function which returned multiple values like this.
There are always exceptions to the rule:
0 for example only has a single root (0).
You cannot take the square root of a negative number (unless the language supports complex numbers). This could be treated as an exception (like "divide by 0") in languages which don't support imaginary numbers or the complex number system.
It is usually simple to deduce the 2 square roots (simply negate the value returned by the function). This was probably left as an exercise by the caller of the sqrt() function, if their domain depended on dealing with both the positive (+) and negative (-) roots.
It's easier to return one number than to return two. Most engineering decisions are made in this manner.
There are many functions which only return 1 answer from 2 or more possibilities. Arc tangent for example. The arc tangent of 1 is returned as 45 degrees, but it could also be 225 or even 405. As with many things in life and programming there is a convention we know and can rely on. Square root functions return positive values is one of them. It is up to us, the programmers, to keep in mind there are other solutions and to act on them if needed in code.
By the way this is a common issue in robotics when dealing with kinematics and inverse kinematics equations where there are multiple solutions of links positions corresponding to Cartesian positions.
In mathematics, by convention it's always assumed that you want the positive square root of something unless you explicitly say otherwise. The square root of four really is two. If you want the negative answer, put a negative sign in front. If you want both, put the plus-or-minus sign. Without this convention it would be impossible to write equations; you would never know what the person intended even if they did put a sign in front (because it could be the negative of the negative square root, for example). Also, how exactly would you write any kind of computer code involving mathematics if operators started returning two values? It would break everything.
The unfortunate exception to this convention is when solving for variables. In the following equation:
x^2 = 4
You have no choice but to consider both possible values for X. if you take the square root of both sides, you get x = 2 but now you must put in the plus or minus sign to make sure you aren't missing any possible solutions. Also, remember that in this case it's technically X that can be either plus or minus, not the square root of four.
Because multiple return types are annoying to implement. If you really need the other result, isn't it easy enough to just multiple the result by -1?
Because most programmers only want one answer.
It's easy enough to generate the negative value from the positive value if the caller wants it. For most code the caller only uses the positive value.
However, nowadays it's easy to return two values in many languages. In JavaScript:
var sqrts=function(x) {
var s=Math.sqrt(x);
if (s>0) {
return [s,-s];
} else {
return [0];
}
}
As long as the caller knows to iterate through the array that comes back, you're gold.
>sqrts(2)
[1.4142135623730951, -1.4142135623730951]
I think because the function is called "sqrt", and if you wanted multiple roots, you would have to call the function "sqrts", which doesn't exist, so you can't do it.
The more serious answer is that you're suggesting a specific instance of a larger issue. Many equations, and commonly inverse functions (including sqrt) have multiple possible solutions, such as arcsin, etc, and these are, in general, an issue. With arcsin, for example, should one return an infinite number of answers? See, for example, discussions about branch cuts.
Because it was historically defined{{citation needed}} as the function which gives the side length of a square of known surface. And length is positive in that context.
you can always tell what is the other number, so maybe it's not necessary to return both of them.
It's likely because when people use a calculator to figure out a square root, they only want the positive value.
Go one step further and ask why your calculator won't let you take the square root of a negative number. It's possible, using imaginary numbers, but the average user has absolutely zero use for this.
On imaginary numbers.

Resources