1 |
On Wed, 31 May 2017 21:02:24 +0200 |
2 |
Michał Górny <mgorny@g.o> wrote: |
3 |
|
4 |
> On śro, 2017-05-31 at 19:39 +0200, Alexis Ballier wrote: |
5 |
> > > > Again, you *need* to process the constraints in order. '!a? |
6 |
> > > > ( b ) !b? ( a )' is not deterministic when none of a and b are |
7 |
> > > > enabled otherwise. |
8 |
> > > |
9 |
> > > You can't rely on any particular order of constraints, especially |
10 |
> > > when eclass stacking comes into play. You could try defining some |
11 |
> > > constraint- sorting algorithm but it's going to be complex and |
12 |
> > > it's usefulness will be limited anyway due to various kinds of |
13 |
> > > grouping. |
14 |
> > |
15 |
> > |
16 |
> > Better have some order: If half of the above constraint comes from |
17 |
> > ebuild and the other half comes from eclass, then PM might toggle |
18 |
> > 'a' or 'b' depending on the phase of the moon which is specifically |
19 |
> > what we're trying to avoid. |
20 |
> |
21 |
> No, it can't. That's the whole point. The algorithm must be defined so |
22 |
> that it is always predictable independently of order (maybe except |
23 |
> the ordering inside ^^, ||, ??) and independently of how it's nested |
24 |
> (i.e. 'a? ( b? ( c ) )' must give the same result as 'b? ( a? ( c ) |
25 |
> )'). |
26 |
|
27 |
This is a lot of handwaving without real description of how it would |
28 |
work. This starts to look a lot like confluence in rewriting systems |
29 |
and you want developers to write only confluent rules and repoman to |
30 |
decide that. Good luck with that. |
31 |
|
32 |
Let's look at real world examples: |
33 |
gtk+: |
34 |
|
35 |
REQUIRED_USE=" |
36 |
|| ( aqua wayland X ) |
37 |
xinerama? ( X ) |
38 |
" |
39 |
|
40 |
Let's assume aqua is masked, which reduces to: |
41 |
REQUIRED_USE=" |
42 |
|| ( wayland X ) |
43 |
xinerama? ( X ) |
44 |
" |
45 |
|
46 |
With USE='-* xinerama' this one is invalid: applying the first |
47 |
constraint first enables wayland, then the 2nd enables X, giving a |
48 |
result of USE="xinerama wayland X". Applying the 2nd first enables X, |
49 |
then the 1st does nothing, giving a result of USE="xinerama X". |
50 |
|
51 |
|
52 |
Now the funny one: |
53 |
$ portageq metadata / ebuild dev-lang/php-7.0.18 REQUIRED_USE |
54 |
cli? ( ^^ ( readline libedit ) ) truetype? ( gd ) webp? ( gd ) cjk? |
55 |
( gd ) exif? ( gd ) xpm? ( gd ) gd? ( zlib ) simplexml? ( xml ) soap? |
56 |
( xml ) wddx? ( xml ) xmlrpc? ( || ( xml iconv ) ) xmlreader? ( xml ) |
57 |
xslt? ( xml ) ldap-sasl? ( ldap ) mhash? ( hash ) phar? ( hash ) qdbm? |
58 |
( !gdbm ) readline? ( !libedit ) recode? ( !imap !mysqli ) sharedmem? |
59 |
( !threads ) mysql? ( || ( mysqli pdo ) ) || ( cli cgi fpm apache2 |
60 |
embed phpdbg ) |
61 |
|
62 |
|
63 |
|
64 |
There are probably dozens of ways to make that non deterministic. |
65 |
Here's one: USE='-*'. Apply '|| ( cli cgi fpm apache2 embed phpdbg )' |
66 |
last; this enables 'cli'. Since it's the last one, REQUIRED_USE is not |
67 |
satisfied because of 'cli? ( ^^ ( readline libedit ) )'. |
68 |
If you process it first, then you enable cli and readline and are good. |
69 |
|
70 |
> If you start relying on stuff like ordering, you're one step from |
71 |
> making stuff suddenly fail or change meaning due to minor changes, |
72 |
> like sorting stuff. |
73 |
|
74 |
What we want to ensure is that for 2 identical inputs the results are |
75 |
identical. If ordering is specified, then re-ordering REQUIRED_USE in |
76 |
an ebuild is not minor anymore. That's a trade off. |
77 |
|
78 |
|
79 |
> > eclass stacking is not a problem: specify if it's append or prepend |
80 |
> > and be done. |
81 |
> |
82 |
> What about multiple inherits with guards? Next thing I know, we end up |
83 |
> putting REQUIRED_USE outside guards (like we have to do with |
84 |
> EXPORT_FUNCTIONS now) because you need a specific order, and guards |
85 |
> make it unpredictable. |
86 |
|
87 |
guards wont make much of a difference: They'll simply de-duplicate |
88 |
constraints by keeping only the rightmost one in the prepend case and |
89 |
the leftmost one in the append case I think. |
90 |
|
91 |
> > Note that if you want to remove the need for an order, you'll need |
92 |
> > to ensure that all orderings of the constraints give the same |
93 |
> > result. It's not sufficient to "only" check all possible inputs. |
94 |
> |
95 |
> That's the matter of the algorithm. |
96 |
|
97 |
For what I know, this algorithm does not even exist. |
98 |
|
99 |
> > Also, what happens if we applied all the constraints and obtained |
100 |
> > some useflags setting that still fails REQUIRED_USE check ? |
101 |
> |
102 |
> It can't happen. If you can apply all the constraints, then implicitly |
103 |
> REQUIRED_USE is satisfied. If you can't apply all the constraints, |
104 |
> then it just fails. Of course, we want to ultimately avoid that case. |
105 |
|
106 |
See the php example above. How do you ensure this does not happen? |
107 |
|
108 |
Note that your assertion 'If you can apply all the constraints, then |
109 |
implicitly REQUIRED_USE is satisfied.' is false: You're changing the |
110 |
values of useflags, thus might violate some previously checked |
111 |
constraint. |
112 |
|
113 |
|
114 |
> > > The point would be: by definition, the solver should be able to |
115 |
> > > touch *any* USE flag. If it can't, it mostly implies that you |
116 |
> > > can't use the automatic solver, and so the case is irrelevant for |
117 |
> > > checking. Attempting to go beyond that is going to give a lot of |
118 |
> > > complexity and most likely kill the whole idea. |
119 |
> > > |
120 |
> > > One thing we need to worry about are masks. We need to think about |
121 |
> > > them. |
122 |
> > |
123 |
> > It makes zero difference for any solver if you replace variables |
124 |
> > (useflags) by 'true' or 'false' constants (masked/forced/user-forced |
125 |
> > useflags). It's even simpler actually. Whether the formula is not |
126 |
> > constantly 'true' (ie REQUIRED_USE is useless) or constantly |
127 |
> > 'false' (ie there's no way to solve it) is equivalent to solving |
128 |
> > SAT. We likely don't want that for repoman running on php. |
129 |
> > |
130 |
> |
131 |
> Well, probably yes. We just need to make sure to apply them correctly |
132 |
> in different contexts, to avoid accidentally skipping some |
133 |
> constraints. I think it would be reasonably to assume that: |
134 |
[...] |
135 |
|
136 |
Yes, you can eliminate constants. It is probably even confluent, i.e. |
137 |
the order in which you eliminate them does not matter and it always |
138 |
converges to the same result. |
139 |
|
140 |
Alexis. |