1 |
On wto, 2017-05-30 at 14:00 +0200, Ulrich Mueller wrote: |
2 |
> > > > > > On Tue, 30 May 2017, Alexis Ballier wrote: |
3 |
> > The way I see it, this boils down to spec'ing something that |
4 |
> > guarantees there's a unique solution given an input. The solution |
5 |
> > does not have to be good or bad (we don't have a good metric on that |
6 |
> > anyway), it just has to be deterministic so that developers can |
7 |
> > arrange their REQUIRED_USE constraints to have PM chose the proper |
8 |
> > solution. |
9 |
> |
10 |
> Right. As I see it, the problem we must solve is that for k USE flags |
11 |
> there are 2**k possible combinations, but there may be only n |
12 |
> combinations that are valid, with n < 2**k. For example, for |
13 |
> IUSE="foo bar baz" there are 2**3 = 8 possible combinations, but with |
14 |
> REQUIRED_USE="|| ( foo bar baz )" or "^^ ( foo bar baz )" only 7 or 3 |
15 |
> of them are valid, respectively. |
16 |
> |
17 |
> Now we can either just specify which of the combinations are valid; |
18 |
> this is what REQUIRED_USE currently does. Or we can specify a complete |
19 |
> mapping from every invalid input combination of flags to a valid |
20 |
> output combination. I think we should do the latter. |
21 |
> |
22 |
|
23 |
Well, you have a point. My proposal was to do the latter, reusing |
24 |
the syntax from the former. |
25 |
|
26 |
Strictly speaking, the following REQUIRED_USE are equivalent: |
27 |
|
28 |
foo? ( bar ) (1) |
29 |
|
30 |
!bar? ( !foo ) (2) |
31 |
|
32 |
However, the developers already select between the two to suggest |
33 |
a specific solution to the user. (1) is used to suggest that enabling |
34 |
the 'bar' flag is the more obvious solution; (2) is used to suggest that |
35 |
disabling 'foo' would be most likely preferred. |
36 |
|
37 |
If we stick to that, I think we can easily achieve the latter goal |
38 |
without sacrificing much of readability and/or making things much harder |
39 |
for developers. That is, treating the '?' as implication: |
40 |
|
41 |
foo? ( bar ) -> foo implies bar |
42 |
|
43 |
!bar? ( !foo ) -> !bar implies !foo |
44 |
|
45 |
The problem is: how far is that going to work? That's what I would like |
46 |
to try determining in the first place. |
47 |
|
48 |
I'm most worried about complex constructs like: |
49 |
|
50 |
foo? ( bar ) ^^ ( baz bar ) |
51 |
|
52 |
But I do not have any obvious ideas how to express them safely while |
53 |
preserving readability and relative simplicity of the constructs, i.e. |
54 |
not having to write a big mapping table. |
55 |
|
56 |
Especially if we are to allow having a preference on baz, the mapping |
57 |
for ^^ alone would be: |
58 |
|
59 |
!bar !baz -> !bar baz |
60 |
bar !baz -> bar !baz [valid] |
61 |
!bar baz -> !bar baz [valid] |
62 |
bar baz -> !bar baz |
63 |
|
64 |
With the additional foo constraint, it becomes harder but not |
65 |
impossible. However, with more constraints we may reach a dead end. |
66 |
|
67 |
Of course, we could just validate all the possible cases via repoman, |
68 |
and reject the ebuild if there's at least one conflict between them. Not |
69 |
sure how to express that properly in the spec though. Not sure how it |
70 |
would work practically. |
71 |
|
72 |
As I said, it's an early RFC to figure out any tips before starting to |
73 |
investigate the technical mysteries. Probably worth to look into |
74 |
existing REQUIRED_USE uses and put them into some trivial constraint |
75 |
solver. |
76 |
|
77 |
-- |
78 |
Best regards, |
79 |
Michał Górny |