-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unexpected behaviour with set comprehension #1794
Comments
Hello Gert,
There are two mechanisms at play here.
1) For a prime p, it must determine that p!=m*m' for all m and m'. As there are no rewrite rules to simplify the expression p==m*m'
it cannot but walk through all values for m and m' and this will not terminate. Fortunately, there is a bound on the number of
instantiations that are possible, and if this bound is reached the original expression is maintained.
2) The bound can be increased using the flag --qlimit=BOUND or -QBOUND.
Doing the following:
mcrl22lps prime.mcrl2 temp.lps
lps2lts -Q1000 temp.lps temp.aut
yields the following .aut file.
des (0,14,15)
(0,"isPrime(1, false)",1)
(1,"isPrime(2, forall m,m': Pos. 1 < m && 1 < m' => !(2 == m * m'))",2)
(2,"isPrime(3, forall m,m': Pos. 1 < m && 1 < m' => !(3 == m * m'))",3)
(3,"isPrime(4, false)",4)
(4,"isPrime(5, forall m,m': Pos. 1 < m && 1 < m' => !(5 == m * m'))",5)
(5,"isPrime(6, false)",6)
(6,"isPrime(7, forall m,m': Pos. 1 < m && 1 < m' => !(7 == m * m'))",7)
(7,"isPrime(8, false)",8)
(8,"isPrime(9, false)",9)
(9,"isPrime(10, false)",10)
(10,"isPrime(11, forall m,m': Pos. 1 < m && 1 < m' => !(11 == m * m'))",11)
(11,"isPrime(12, false)",12)
(12,"isPrime(13, forall m,m': Pos. 1 < m && 1 < m' => !(13 == m * m'))",13)
(13,"isPrime(14, false)",14)
Now all non-primes are detected as such.
But I think that the situation is easily changeable such that primes can be calculated.
Replace the definition for primes by the following, limiting the values of m and m'.
eqn
primes = { n: Pos | n > 1 && forall m, m': Pos . (n>m && m > 1 && n>m' && m'>1) => n != m * m' };
Using the -Q1000 flag I got all prime numbers in your example.
des (0,14,15)
(0,"isPrime(1, false)",1)
(1,"isPrime(2, true)",2)
(2,"isPrime(3, true)",3)
(3,"isPrime(4, false)",4)
(4,"isPrime(5, true)",5)
(5,"isPrime(6, false)",6)
(6,"isPrime(7, true)",7)
(7,"isPrime(8, false)",8)
(8,"isPrime(9, false)",9)
(9,"isPrime(10, false)",10)
(10,"isPrime(11, true)",11)
(11,"isPrime(12, false)",12)
(12,"isPrime(13, true)",13)
(13,"isPrime(14, false)",14)
Nice example!
Regards, Jan Friso
…------------------------------------------------------------------------------------------------------------------------
Jan Friso Groote, Eindhoven University of Technology, Department of Mathematics and
Computer Science, Metaforum room MF 6.079b, Groene Loper 5, 5612 AE Eindhoven.
The Netherlands. Mobile +31 6 81922128. Secretary: +31-40-247 5145.
***@***.******@***.***>, jfg.win.tue.nl<http://www.win.tue.nl/~jfg>,
Home: Hoekstraat 56, 5674 NP Nederwetten, +31 40 2845414.
From: Gert Veltink ***@***.***>
Date: Friday, 6 December 2024 at 19:19
To: mCRL2org/mCRL2 ***@***.***>
Cc: Subscribed ***@***.***>
Subject: [mCRL2org/mCRL2] unexpected behaviour with set comprehension (Issue #1794)
Either my understanding of set comprehension in mCRL2 is fundamentally flawed or there is something funky with its implementation.
I have tried to experiment with the definition of the prime numbers as given on the web site in the section "Data Specifications".
{ n: Pos | n > 1 && forall m, m': Pos . (m > 1 && m' > 1) => n != m * m' }
I expected to be able to use the term rewriter to test the primeness of numbers like:
1 in { n: Pos | n > 1 && forall m, m': Pos . (m > 1 && m' > 1) => n != m * m' }
This results in "false" es expected.
However, testing primeness of "2" does not result in "true", instead it results in:
forall m,m': Pos. 1 < m && 1 < m' => !(2 == m * m')
Testing "4" results in: "false" as expected.
Testing "6" results in: "false" as expected.
Testing "8" results in: "false" as expected.
However, testing "9" results in:
forall m,m': Pos. 1 < m && 1 < m' => !(9 == m * m')
and Testing "10" results in:
forall m,m': Pos. 1 < m && 1 < m' => !(10 == m * m')
I cannot see the pattern here!
To be able to quickly test a series of values I constructed the following small process specification.
Please help me, I am confused.
%
% A simple example to demonstrate the use of quantifiers
%
map
primes: Set(Pos);
eqn
primes = { n: Pos | n > 1 && forall m, m': Pos . (m > 1 && m' > 1) => n != m * m' };
%------------------------------------------
act
isPrime: Pos # Bool;
proc
ShowPrimes = ShowPrimes(1);
ShowPrimes(p : Pos) = (p < 15) -> isPrime(p, p in primes) . ShowPrimes(p + 1);
init
ShowPrimes;
—
Reply to this email directly, view it on GitHub<#1794>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ACE5HUDJ6HTX5ML5ZTVHQ3L2EHTBJAVCNFSM6AAAAABTFFMWBWVHI2DSMVQWIX3LMV43ASLTON2WKOZSG4ZDGNRWGI4DEOI>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Hi Jan Friso, Many thanks for your rapid reply! I have been able to successfully reproduce your results. But I get the point, we have to try to manually prune the search space of the quantifiers such that the tool is more likely to find the solution. I will check whether I can come up with a more restrictive definition of primes, such that a larger number of values can be found with the default settings. Cheers! Gert |
OK, I now have done some experiments.
I have been able to improve the value of -Q down to -Q33, but not the legibility, unfortunately! ;-) One small final request. Cheers! Gert |
Either my understanding of set comprehension in mCRL2 is fundamentally flawed or there is something funky with its implementation.
I have tried to experiment with the definition of the prime numbers as given on the web site in the section "Data Specifications".
{ n: Pos | n > 1 && forall m, m': Pos . (m > 1 && m' > 1) => n != m * m' }
I expected to be able to use the term rewriter to test the primeness of numbers like:
1 in { n: Pos | n > 1 && forall m, m': Pos . (m > 1 && m' > 1) => n != m * m' }
This results in "false" es expected.
However, testing primeness of "2" does not result in "true", instead it results in:
forall m,m': Pos. 1 < m && 1 < m' => !(2 == m * m')
Testing "4" results in: "false" as expected.
Testing "6" results in: "false" as expected.
Testing "8" results in: "false" as expected.
However, testing "9" results in:
forall m,m': Pos. 1 < m && 1 < m' => !(9 == m * m')
and Testing "10" results in:
forall m,m': Pos. 1 < m && 1 < m' => !(10 == m * m')
I cannot see the pattern here!
To be able to quickly test a series of values I constructed the following small process specification.
Please help me, I am confused.
The text was updated successfully, but these errors were encountered: