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 09:07:16
Message-Id: 20170614110659.6bf4d1c2@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 00:13:42 +0200
2 Michał Górny <mgorny@g.o> wrote:
3
4 > On wto, 2017-06-13 at 12:27 +0200, Alexis Ballier wrote:
5 > > On Mon, 12 Jun 2017 21:17:16 +0200
6 > > Michał Górny <mgorny@g.o> wrote:
7 > >
8 > > > I've actually started typing the initial specification yesterday
9 > > > [1]. As you can see, banning the extra constraints has made the
10 > > > algorithms much simpler. In particular:
11 > > >
12 > > > 1. You do not have to define 'falsify' for anything other than
13 > > > pure flags -- which makes it easy to inline it.
14 > > >
15 > > > 2. ||, ??, ^^ groups are only flat lists of flags -- which makes
16 > > > reordering and processing them trivial.
17 > > >
18 > > > 3. The algorithm is recursive only on USE-conditional groups. This
19 > > > makes it trivial to make it iterative. Optimizations become
20 > > > trivially possible.
21 > >
22 > >
23 > > While you're right in one sense, you're mixing two different things
24 > > here. What you wrote *is* recursive. It does not recurse just
25 > > because you're assuming a restricted syntax. You're only saving two
26 > > things: you don't need to define how to enforce to false (that is 3
27 > > lines not 3 pages :=) ) and you're avoiding the nested use
28 > > conditionals that are already ill defined per the current spec
29 > > (foo? bar is equivalent to && ( foo bar ) when nested) which I
30 > > believe is already another problem.
31 > >
32 > > Then, remember how I wanted to be much more drastic than you in the
33 > > beginning by killing all ||,&&,^^ etc. and keep only use
34 > > conditionals in REQUIRED_USE ? Well, that's where the complexity
35 > > comes. The whole deal then is to define rewriting rules for the AST
36 > > so that the algorithm you describe executes the exact same
37 > > instructions but the new AST only has use conditionals. This is
38 > > more like writing a compiler for the spec, so this does not belong
39 > > to the spec and there is no issue here.
40 >
41 > I'm looking for a compromise here. Killing those groups completely is
42 > going to make things harder for users. Keeping them with functionality
43 > limited to what's used in ~99.9% ebuilds (based on your numbers) is
44 > IMO a better choice.
45
46 I already said I see the limited syntax as a good thing because it
47 forces devs to write constraints that have a natural interpretation in
48 how it is solved. However, you can't limit the syntax without a new
49 EAPI, and more importantly, properly solving does not even require
50 limiting the syntax.
51
52 BTW, I don't know how you get that info from my data because I never
53 voluntarily checked for a restricted syntax :)
54
55 > > [BTW: checking the rewrite rules behave properly is what I meant by
56 > > rebasing solve() on top of it and being happy with it]
57 >
58 > Could you reiterate the current solving rules (trueify/falsify)? Are
59 > they equal to the ones you listed last, or does the current
60 > implementation change anything?
61
62 Let's recap a bit. nsolve() is poorly named and does not solve
63 anything. It translates to implications and checks whether the
64 implications solver will always provide a valid result in one pass.
65 So, if you only care about solving rules, read your spec man. For the
66 more general case it should behave like those trueify/falsify with
67 the change that nested implications are interpreted as && (so no
68 more !(a -> b) crap to worry about).
69
70 If you take solve() as an implementation of your spec, you have:
71 solve(x) <=> solve(to_impl.convert_to_implications(x)) when solve(x)
72 is defined; with the added benefit that
73 'solve(to_impl.convert_to_implications(x))' is defined and should
74 provide proper results on the whole REQUIRED_USE syntax as currently
75 defined (granted that nsolve(x) does not report anything wrong).
76
77 > > > Nevertheless, feel free to play with the full implementation. If
78 > > > you're interested, you can play with the complex cases more. In
79 > > > particular, I'm wondering whether nsolve will actually consider
80 > > > most of them solvable.
81 > > >
82 > > > As for the results, I think it is the point where we start
83 > > > preparing pull requests with REQUIRED_USE changes to see whether
84 > > > the developers agree with such changes.
85 > >
86 > > If by that you also include code cleanup and writing tests then
87 > > yes :)
88 >
89 > I'm not sure if we're talking about the same thing. I'm talking about
90 > filing pull requests against ebuilds whose REQUIRED_USE is rejected by
91 > nsolve. I think it'd serve as a reasonable field test for whether
92 > developers agree with the imposed restrictions.
93
94 I was talking about PRs against portage & repoman.
95
96 > > > [1]:https://wiki.gentoo.org/wiki/User:MGorny/GLEP:ReqUse
97 > >
98 > > I really don't like the reordering thing. Even the restricted
99 > > syntax does not fix the issue with '^^ ( a b ) b? ( a )' already
100 > > mentioned here. It'd be much better and simpler for the spec just to
101 > > assign a fixed value and use the solving rules with those.
102 >
103 > You're not going to convince me by providing examples that are utterly
104 > broken by design and meaningless ;-).
105
106 Well... if it's so obvious that the example is broken by design that
107 you don't even bother to explain why, I assume you have an algorithm for
108 that. Where is the code ? What are the numbers ? How many ebuilds might
109 fail after reordering ? How can this be improved ?
110
111 Extra question: Is there *really* a point in pushing user preferences
112 that way, esp. when developers can write '!b? ( a )' instead of '|| ( a
113 b )' and just kill any possibility of changing the order ?
114
115 As for a real world example, I'll let you find some more interesting
116 ones, but this one will probably be interesting to you and is a
117 good start:
118
119 app-text/wklej-0.2.1-r1 ^^ ( python_single_target_pypy
120 python_single_target_pypy3 python_single_target_python2_7
121 python_single_target_python3_4 python_single_target_python3_5
122 python_single_target_python3_6 ) python_single_target_pypy?
123 ( python_targets_pypy ) python_single_target_pypy3?
124 ( python_targets_pypy3 ) python_single_target_python2_7?
125 ( python_targets_python2_7 ) python_single_target_python3_4?
126 ( python_targets_python3_4 ) python_single_target_python3_5?
127 ( python_targets_python3_5 ) python_single_target_python3_6?
128 ( python_targets_python3_6 ) vim? ( ^^ ( python_single_target_python2_7
129 ) )
130
131
132 Hint: It loops as written here. Reordering the ^^ in a proper way makes
133 it solvable. Putting the 'vim? ( ... )' part first makes it solvable in
134 one pass.
135
136 Extra bonus: If your algorithm solves that in reasonable time,
137 run it again as if PYTHON_COMPAT also contained
138 'python3_{7,8,9,10,11,12}'
139
140 Alexis.

Replies