Prolog maximum term size - prolog

I'm considering using some very long terms to describe coordinates on an xy grid, and/or the entire xy grid itself. I tried to find some info in documentation, but didn't have any luck.
What's the maximum size of a compound term, and where can I find this information? I'm currently using SWI, but may use other Prologs too.

Relevant to your question are the standard flags max_arity and bounded. The max_arity flag can have the value unbounded, meaning only memory limits the number of arguments of a compound term, are a natural number. The bounded flag is a boolean flag. If true, it means that the also standard flags max_integer and min_integer specify the representable integers. Also relevant, but unfortunately not expressed by a standard flag, is the maximum atom size if not unbound; here you will need to check the documentation of the Prolog system.

Related

The smallest `max_arity` of compound terms in ISO Prolog programs

Prolog systems aiming at iso-prolog conformity do not have to support compound terms with arbitrarily large arities. The Prolog flag max_arity reflects this.
According to ISO/IEC 13211-1:1995:
7.11.2.3 Flag: max_arity
Possible values: The default value only
Default value: implementation defined
Changeable: No
Description: The maximum arity allowed for any compound term, or unbounded when the processor has no limit for the number of arguments for a compound term.
So Prolog systems may or may not impose an upper limit on max_arity ... but what about the lower limit? Is, say, 5 okay?
NO!
ISO/IEC 13211-1:1995/Cor.2:2012, Technical Corrigendum 2, defines call/2..8 as:
8.15.4 call/2..8 ...
NOTE — A standard-conforming processor may implement call/N in one of the following ways because error condition d is implementation dependent (3.91).
Implement only the seven built-in predicates call/2 up to call/8.
Implement call/2..N up to any N that is within 8..max_arity (7.11.2.3). Produce existence errors for larger arities below max_arity.
Implement call/9 and above only for certain execution modes.
All of these ways only imply Max_arity >= 8—but nothing more.
So my question has (at least) two sides:
Prolog User:
"What is the maximum arity I may use if I want to avoid vendor lock-in?"
Prolog Implementor:
"What is the smallest Max_arity I must support if I aim1 at ISO-Prolog conformity?"
Right now, I'm quite sure the answer is this:
Yes, Max_arity = 8 is okay.
But is it in fact so? Are there clues I am missing?
Footnotes: 1) I do.
Ad 2: Standard conformity is a precondition for a working system. It is by no means a guarantee that a system is fit for any purpose including the one you are (reasonably) interested in. Given that, I'd say 1 is the minimum, as zero cannot be the arity of a compound term. Of course, any attempt to produce a list would produce a representation error. It could be worse, see Purpose of this.
The usage of built-ins with higher arity (5 or 8) is not precluded in such a processor. After all, a conforming processor needs just to prepare Prolog text for execution (5.1.a) and correctly execute Prolog goals (5.1.b). Nowhere is it stated that such goals are represented as compound terms.
But of course that is what we expect, as we expect to be able to program our own top level loop which is itself out of scope of ISO/IEC 13211-1.
Ad 1: As for future portability, 255 appears to be the minimum. But IF has 127. Minerva 125. Of course unbounded would be the best choice, with up to 7 for fast and compact representation.
Are there clues I am missing?
The relation of compound terms to predicates is often overseen in this context. A system may support predicates with only a smaller arity than max_arity — the appropriate error to issue here would be a resource_error. Compare this situation to a system with current_prolog_flag(max_arity, unbounded) and the goal functor(F,f,N) with N exceeding the processor's address space (in current implementations). While such a goal would never succeed in current implementations, it still issues a resource_error and not a representation_error.
There is a gap somehow. max_arity only covers the compound size. But there is no flag for predicate size. The two things might vary as SWI-Prolog shows. But SWI-Prolog names the limit wrongly max_arity, although its not its max_arity flag:
/* SWI-Prolog 8.3.19 */
?- functor(_,f,10000).
true.
?- functor(F,f,10000), assertz(F).
ERROR: Cannot represent due to `max_arity' (limit is 1024, request = 10000)
?- current_prolog_flag(max_arity, X).
X = unbounded.
The predicate size limit might be more relevant to call/n than the compound size. The ISO core standard definition is a little unsatisfactory.
But its not thoroughly checked, but a fix on SWI-Prologs side is underway:
?- functor(F,f,10000), assertz(test:-F).
F = f(_ ...)
?- functor(F,f,10000), call(F,a).
%%% crash
Edit 25.02.2021:
The glitch in the error message is only explained when you look at the C-Code of SWI-Prolog, which has a C Constant MAXARITY with the meaning of predicate size. This Constant and the Error Message possibly predates the ISO core standard, which introduced another constant.
The ISO Prolog standard predicate with the larger number of arguments is sub_atom/5. We can use this predicate to justify at least call/6 and thus a maximum arity of at least 6:
| ?- call(sub_atom, A, B, C, D, E).
Of course, with call/6, nothing prevents the programmer to call e.g.
| ?- call(foo(A,B,C), D, E, F, G, H)

Generate a Random number in Uppaal

My question is Can I generate a random number in Uppaal?
I would like to generate a number from a range of values. Even more, I would like to generate not just integers I would like to generate double values as well.
for example: double [7.25,18.3]
I found this question that were talking about the same. I tried it.
However, I got this error: syntax error unexpected T_SELECT.
It doesn't work. I'm pretty new in Uppaal world, I would appreciate any help that you can provide me.
Regards,
This is a common and misunderstood question in Uppaal.
Simple answer:
double val; // declaration
val = random(18.3-7.25)+7.25; // use in update, works in SMC (Uppaal v4.1)
Verbose answer:
Uppaal supports symbolic analysis as well as statistical and the treatment and possibilities are radically different. So one has to decide first what kind of analysis is needed. Usually one starts with simple symbolic analysis and then augment with stochastic features, sometimes stochastic behavior needs also to be checked symbolically.
In symbolic analysis (queries A[], A<>, E<>, E[] etc), random is synonymous with non-deterministic, i.e. if the model contains some "random" behavior, then verification should check all of them any way. Therefore such behavior is modelled as non-deterministic choices between edges. It is easy to setup a set of edges over an integer range by using select statement on the edge where a temporary variable is declared and its value can be used in guards, synchronization and update. Symbolic analysis supports only integer data types (no floating point types like double) and continuous ranges over clocks (specified by constraints in guards and invariants).
Statistical analysis (via Monte-Carlo simulations, queries like Pr[...](<> p), E[...](max: var), simulate, etc) supports double types and floating point functions like sin, cos, sqrt, random(MAX) (uniform distribution over [0, MAX)), random_normal(mean, dev) etc. in addition to int data types. Clock variables can also be treated as floating point type, except that their derivative is set to 1 by default (can be changed in the invariants which allow ODEs -- ordinary differential equations).
It is possible to create models with floating point operations (including random) and still apply symbolic analysis provided that the floating point variables do not influence/constrain the model behavior, and act merely as a cost function over the state space. Here are systematic rules to achieve this:
a) the clocks used in ODEs must be declared of hybrid clock type.
b) hybrid clock and double type variables cannot appear in guard and invariant constraints. Only ODEs are allowed over the hybrid clocks in the invariant.

Representation of negative integers

Does ISO-Prolog have any prescriptions / recommendations
regarding the representation of negative integers and operations on them? 2's complement, maybe?
Asking as a programmer/user: Are there any assumptions I can safely make when performing bit-level operations on negative integers?
ISO/IEC 13211-1 has several requirements for integers, but a concrete representation is not required. If the integer representation is bounded, one of the following conditions holds
7.1.2 Integer
...
minint = -(*minint)
minint = -(maxint+1)
Further, the evaluable functors listed in 9.4 Bitwise functors, that is (>>)/2, (<<)/2, (/\)/2, (\/)/2, (\)/1, and xor/2 are implementation defined for negative values. E.g.,
8.4.1 (>>)/2 – bitwise right shift
9.4.1.1 Description
...
The value shall be implementation defined depending onwhether the shift is logical (fill with zeros) or arithmetic(fill with a copy of the sign bit).The value shall be implementation defined if VS is negative,or VS is larger than the bit size of an integer.
Note that implementation defined means that a conforming processor has to document this in the accompanying documentation. So before using a conforming processor, you have to read the manual.
De facto, there is no current Prolog processor (I am aware of) that does not provide arithmetic right shift and does not use 2's complement.
Strictly speaking these are two different questions:
Actual physical representation: this isn't visible at the Prolog level, and therefore the standard quite rightly has nothing to say about it. Note that many Prolog systems have two or more internal representations (e.g. two's complement fixed size and sign+magnitude bignums) but present a single integer type to the programmer.
Results of bitwise operations: while the standard defines these operations, it leaves much of their behaviour implementation defined. This is a consequence of (a) not having a way to specify the width of a bit pattern, and (b) not committing to a specific mapping between negative numbers and bit patterns.
This not only means that all bitwise operations on negative numbers are officially not portable, but also has the curious effect that the result of bitwise negation is totally implementation-defined (even for positive arguments): Y is \1 could legally give -2, 268435454, 2147483646, 9223372036854775806, etc. All you know is that negating twice returns the original number.
In practice, fortunately, there seems to be a consensus towards "The bitwise arithmetic operations behave as if operating on an unlimited length two's complement representation".

Why use 1 instead of -1?

At 29min mark of http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly Andrei Alexandrescu says when using constants to prefer 0 and mentions hardware knows how to handle it. I did some assembly and I know what he is talking about and about the zero flag on CPUs
Then he says prefer the constant 1 rather then -1. -1 IIRC is not actually special but because it is negative the sign flag on CPUs would be set. 1 from my current understanding is simply a positive number there is no bit on the processor flag for it and no way to distinguish from 0 or other positive numbers.
But Andrei says to prefer 1 over -1. Why? What does hardware do with 1 that is better then -1?
First, it should be noted that Andrea Alexandrescu emphasized the difference between zero and the other two good constants, that the difference between using one and negative one is less significant. He also bundles compiler issues with hardware issues, i.e., the hardware might be able to perform the operation efficiently but the compiler will not generate the appropriate machine code given a reasonably clear expression in the chosen higher level language.
While I cannot read his mind, there are at least two aspects that may make one better than negative one.
Many ISAs provide comparison operations (or flag to GPR transfers) that return zero or one (e.g., MIPS has Set on Less Than) not zero or negative one. (SIMD instructions are an exception; SIMD comparisons typically generate zero or negative one [all bits set].)
At least one implementation of SPARC made loading smaller signed values more expensive, and I seem to recall that at least one ISA did not provide an instruction for loading signed bytes. Naive implementation of sign extension adds latency because whether to set or clear the more significant bits is not known until the value has been loaded.
Negative one does have some benefits. As you mentioned, testing for negativity is often relatively easy, so if negative one is the only negative value used it may be handled less expensively. Also, conditionally clearing a value based on zero or negative one is simply an and operation. (For conditionally setting or clearing a single bit, one rather than negative one would be preferred since such would involve only a shift and an and.)

Algorithms to represent a set of integers with only one integer

This may not be a programming question but it's a problem that arised recently at work. Some background: big C development with special interest in performance.
I've a set of integers and want to test the membership of another given integer. I would love to implement an algorithm that can check it with a minimal set of algebraic functions, using only a integer to represent the whole space of integers contained in the first set.
I've tried a composite Cantor pairing function for instance, but with a 30 element set it seems too complicated, and focusing in performance it makes no sense. I played with some operations, like XORing and negating, but it gives me low estimations on membership. Then I tried with successions of additions and finally got lost.
Any ideas?
For sets of unsigned long of size 30, the following is one fairly obvious way to do it:
store each set as a sorted array, 30 * sizeof(unsigned long) bytes per set.
to look up an integer, do a few steps of a binary search, followed by a linear search (profile in order to figure out how many steps of binary search is best - my wild guess is 2 steps, but you might find out different, and of course if you test bsearch and it's fast enough, you can just use it).
So the next question is why you want a big-maths solution, which will tell me what's wrong with this solution other than "it is insufficiently pleasing".
I suspect that any big-math solution will be slower than this. A single arithmetic operation on an N-digit number takes at least linear time in N. A single number to represent a set can't be very much smaller than the elements of the set laid end to end with a separator in between. So even a linear search in the set is about as fast as a single arithmetic operation on a big number. With the possible exception of a Goedel representation, which could do it in one division once you've found the nth prime number, any clever mathematical representation of sets is going to take multiple arithmetic operations to establish membership.
Note also that there are two different reasons you might care about the performance of "look up an integer in a set":
You are looking up lots of different integers in a single set, in which case you might be able to go faster by constructing a custom lookup function for that data. Of course in C that means you need either (a) a simple virtual machine to execute that "function", or (b) runtime code generation, or (c) to know the set at compile time. None of which is necessarily easy.
You are looking up the same integer in lots of different sets (to get a sequence of all the sets it belongs to), in which case you might benefit from a combined representation of all the sets you care about, rather than considering each set separately.
I suppose that very occasionally, you might be looking up lots of different integers, each in a different set, and so neither of the reasons applies. If this is one of them, you can ignore that stuff.
One good start is to try Bloom Filters.
Basically, it's a probabilistic data structure that gives you no false negative, but some false positive. So when an integer matches a bloom filter, you then have to check if it really matches the set, but it's a big speedup by reducing a lot the number of sets to check.
if i'd understood your correctly, python example:
>>> a=[1,2,3,4,5,6,7,8,9,0]
>>>
>>>
>>> len_a = len(a)
>>> b = [1]
>>> if len(set(a) - set(b)) < len_a:
... print 'this integer exists in set'
...
this integer exists in set
>>>
math base: http://en.wikipedia.org/wiki/Euler_diagram

Resources