Gentoo Archives: gentoo-dev

From: Alexis Ballier <aballier@g.o>
To: gentoo-dev@l.g.o
Subject: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE)
Date: Wed, 14 Jun 2017 13:16:22
Message-Id: 20170614151606.70d5d559@gentoo.org
In Reply to: Re: [gentoo-dev] [RFC] Forced/automatic USE flag constraints (codename: ENFORCED_USE) by "Michał Górny"
1 On Wed, 14 Jun 2017 14:24:48 +0200
2 Michał Górny <mgorny@g.o> wrote:
3
4 > On śro, 2017-06-14 at 11:06 +0200, Alexis Ballier wrote:
5 > > On Wed, 14 Jun 2017 00:13:42 +0200
6 > > Michał Górny <mgorny@g.o> wrote:
7 > >
8 > > > On wto, 2017-06-13 at 12:27 +0200, Alexis Ballier wrote:
9 > > > > On Mon, 12 Jun 2017 21:17:16 +0200
10 > > > > Michał Górny <mgorny@g.o> wrote:
11 > > > >
12 > > > > > I've actually started typing the initial specification
13 > > > > > yesterday [1]. As you can see, banning the extra constraints
14 > > > > > has made the algorithms much simpler. In particular:
15 > > > > >
16 > > > > > 1. You do not have to define 'falsify' for anything other than
17 > > > > > pure flags -- which makes it easy to inline it.
18 > > > > >
19 > > > > > 2. ||, ??, ^^ groups are only flat lists of flags -- which
20 > > > > > makes reordering and processing them trivial.
21 > > > > >
22 > > > > > 3. The algorithm is recursive only on USE-conditional groups.
23 > > > > > This makes it trivial to make it iterative. Optimizations
24 > > > > > become trivially possible.
25 > > > >
26 > > > >
27 > > > > While you're right in one sense, you're mixing two different
28 > > > > things here. What you wrote *is* recursive. It does not recurse
29 > > > > just because you're assuming a restricted syntax. You're only
30 > > > > saving two things: you don't need to define how to enforce to
31 > > > > false (that is 3 lines not 3 pages :=) ) and you're avoiding
32 > > > > the nested use conditionals that are already ill defined per
33 > > > > the current spec (foo? bar is equivalent to && ( foo bar ) when
34 > > > > nested) which I believe is already another problem.
35 > > > >
36 > > > > Then, remember how I wanted to be much more drastic than you in
37 > > > > the beginning by killing all ||,&&,^^ etc. and keep only use
38 > > > > conditionals in REQUIRED_USE ? Well, that's where the
39 > > > > complexity comes. The whole deal then is to define rewriting
40 > > > > rules for the AST so that the algorithm you describe executes
41 > > > > the exact same instructions but the new AST only has use
42 > > > > conditionals. This is more like writing a compiler for the
43 > > > > spec, so this does not belong to the spec and there is no issue
44 > > > > here.
45 > > >
46 > > > I'm looking for a compromise here. Killing those groups
47 > > > completely is going to make things harder for users. Keeping them
48 > > > with functionality limited to what's used in ~99.9% ebuilds
49 > > > (based on your numbers) is IMO a better choice.
50 > >
51 > > I already said I see the limited syntax as a good thing because it
52 > > forces devs to write constraints that have a natural interpretation
53 > > in how it is solved. However, you can't limit the syntax without a
54 > > new EAPI, and more importantly, properly solving does not even
55 > > require limiting the syntax.
56 >
57 > Actually, you can, via a Gentoo policy. Since solving is not required
58 > by the PMS, there is no rule saying it has to work for every
59 > constraint allowed by the PMS.
60
61 Indeed. But you're trying to make rules that it has *not* to work for
62 some of them for reasons that look more like laziness in trying to
63 understand the problem than anything else.
64
65 > Much like, you can't force a particular ordering or forbid circular
66 > constraints without a new EAPI. Yet you do it because it gives
67 > a practical improvement.
68
69 I don't see this being enforced by a new EAPI. It's more a matter of QA
70 tools like repoman. The main difference is that there are real reasons
71 for forbidding circular constraints: For true circular ones, no solver
72 will ever be able to solve it...
73
74 [...]
75 > >
76 > > > > [BTW: checking the rewrite rules behave properly is what I
77 > > > > meant by rebasing solve() on top of it and being happy with
78 > > > > it]
79 > > >
80 > > > Could you reiterate the current solving rules (trueify/falsify)?
81 > > > Are they equal to the ones you listed last, or does the current
82 > > > implementation change anything?
83 > >
84 > > Let's recap a bit. nsolve() is poorly named and does not solve
85 > > anything. It translates to implications and checks whether the
86 > > implications solver will always provide a valid result in one pass.
87 > > So, if you only care about solving rules, read your spec man. For
88 > > the more general case it should behave like those trueify/falsify
89 > > with the change that nested implications are interpreted as && (so
90 > > no more !(a -> b) crap to worry about).
91 >
92 > How are && ( a b... ) falsified now? Leftmost only?
93
94 $ python3 to_impl.py '?? ( a ( b c ) )'
95 Normalized: [|| [!b, !c, !a]]
96 List of implications:
97 [[c, a]? => !b]
98
99 Sounds like it. This is the only "stable" way anyway.
100
101
102 > > If you take solve() as an implementation of your spec, you have:
103 > > solve(x) <=> solve(to_impl.convert_to_implications(x)) when solve(x)
104 > > is defined; with the added benefit that
105 > > 'solve(to_impl.convert_to_implications(x))' is defined and should
106 > > provide proper results on the whole REQUIRED_USE syntax as currently
107 > > defined (granted that nsolve(x) does not report anything wrong).
108 >
109 > The point is, solve() is supposed to work without any additional
110 > transformations.
111
112 Then I already explained how to make it work.
113
114 Transformations are out of scope of the spec and more for improving
115 code sharing: Those are required for checking that the solver will
116 provide a proper solution; if there is some flaw or undefined behavior
117 in the spec, then solve() might change, if both the solver and the
118 checker work on the same input data then at least there won't be some
119 desynchronization between them.
120
121 [...]
122 > > > > > [1]:https://wiki.gentoo.org/wiki/User:MGorny/GLEP:ReqUse
123 > > > >
124 > > > > I really don't like the reordering thing. Even the restricted
125 > > > > syntax does not fix the issue with '^^ ( a b ) b? ( a )' already
126 > > > > mentioned here. It'd be much better and simpler for the spec
127 > > > > just to assign a fixed value and use the solving rules with
128 > > > > those.
129 > > >
130 > > > You're not going to convince me by providing examples that are
131 > > > utterly broken by design and meaningless ;-).
132 > >
133 > > Well... if it's so obvious that the example is broken by design that
134 > > you don't even bother to explain why, I assume you have an
135 > > algorithm for that. Where is the code ? What are the numbers ? How
136 > > many ebuilds might fail after reordering ? How can this be
137 > > improved ?
138 >
139 > Are you arguing for the sake of arguing here? I just presumed that
140 > this example is so obviously broken there is no point wasting any
141 > more time on it. The code of nsolve clearly detects that, so I don't
142 > really understand what you're trying to prove here.
143
144 Those are real questions. You should take breath, think a bit about
145 it, and try to run the 2 possible orderings of the ^^ through nsolve or
146 even solve.py. They both are very happy (and are right to be) with
147 the above ordering. You might want to think a bit more about what is the
148 relation between this broken 10 chars example and the 10 lines python
149 targets one below.
150
151 You should also realize that all the above questions have already been
152 answered in length if you do as I suggest.
153
154 [...]
155 > > As for a real world example, I'll let you find some more interesting
156 > > ones, but this one will probably be interesting to you and is a
157 > > good start:
158 > >
159 > > app-text/wklej-0.2.1-r1 ^^ ( python_single_target_pypy
160 > > python_single_target_pypy3 python_single_target_python2_7
161 > > python_single_target_python3_4 python_single_target_python3_5
162 > > python_single_target_python3_6 ) python_single_target_pypy?
163 > > ( python_targets_pypy ) python_single_target_pypy3?
164 > > ( python_targets_pypy3 ) python_single_target_python2_7?
165 > > ( python_targets_python2_7 ) python_single_target_python3_4?
166 > > ( python_targets_python3_4 ) python_single_target_python3_5?
167 > > ( python_targets_python3_5 ) python_single_target_python3_6?
168 > > ( python_targets_python3_6 ) vim? ( ^^
169 > > ( python_single_target_python2_7 ) )
170 > >
171 > >
172 > > Hint: It loops as written here. Reordering the ^^ in a proper way
173 > > makes it solvable. Putting the 'vim? ( ... )' part first makes it
174 > > solvable in one pass.
175 >
176 > And that's the exact case where I was considering the problem of
177 > ebuild- eclass ordering. And yes, putting the 'vim?' first is an
178 > acceptable solution here. What's the problem here?
179
180 Forget about putting vim?() first, it just makes it require an extra
181 pass in the best case and is not the real issue here.
182
183 > Yes, without reordering you get more 'reliable' results. However,
184 > AFAICS nsolve detects a problem in all of the cases: if py2.7 is
185 > sorted first, it detects ordering issue; in all other cases, it
186 > detects circular dep. Am I missing something?
187
188 Again, where is the code to check those 'all other cases' ?
189 This is a real question as you don't seem to get the combinatorial
190 explosion that happens here. I fear that unless you experiment it first
191 hands you'll still be doubting it.
192
193 Also, it seems very wrong that PM will now happily toggle flags from USE
194 but will completely fail if I configure it with "please prefer python3
195 over python2".
196
197 Alexis.

Replies