Skip to content

Commit

Permalink
tools/trim: implement trim for evalv3
Browse files Browse the repository at this point in the history
Trim now works on the result of evaluation for evalv3.

This new implementation only works for evalv3, and does not alter any
code paths for evalv2 and the existing trim.

The new implementation addresses all known bugs with trim.

Signed-off-by: Matthew Sackman <[email protected]>
Change-Id: If814b5f66ce2ea3ce37ddcbec71eb38f1bc97216
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1208658
Unity-Result: CUE porcuepine <[email protected]>
Reviewed-by: Marcel van Lohuizen <[email protected]>
TryBot-Result: CUEcueckoo <[email protected]>
  • Loading branch information
cuematthew committed Feb 19, 2025
1 parent 13fdb81 commit e3d44f0
Show file tree
Hide file tree
Showing 81 changed files with 4,569 additions and 64 deletions.
63 changes: 63 additions & 0 deletions cmd/cue/cmd/testdata/script/trim_package.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
exec cue mod init

# -- evalv3 --
env CUE_EXPERIMENT=evalv3=1
exec cue trim -o - ./...
cmp stdout expect-stdout-v3

# -- evalv2 --
env CUE_EXPERIMENT=evalv3=0
exec cue trim -o - ./...
cmp stdout expect-stdout-v2

-- a.cue --
package p

x: y: int
x: z: int
-- b/b.cue --
package p

x: y: 7
-- c/c.cue --
package p

x: z: 6
-- expect-stdout-v3 --
package p

x: y: int
x: z: int
package p

x: y: int
x: z: int
package p

x: y: 7
package p

x: y: int
x: z: int
package p

x: z: 6
-- expect-stdout-v2 --
package p

x: y: int
x: z: int
package p

x: y: int
x: z: int
package p

x: y: 7
package p

x: y: int
x: z: int
package p

x: z: 6
3 changes: 3 additions & 0 deletions internal/core/subsume/vertex.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ func (s *subsumer) verticesDev(x, y *adt.Vertex) bool {
return true
}

case nil:
return false

default:
panic(fmt.Sprintf("unexpected type %T", v))
}
Expand Down
77 changes: 77 additions & 0 deletions tools/trim/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2025 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package trim removes some redundant values from CUE sources.
//
// The most common use of trim is to remove duplicate values from data
// where a definition now provides the same value. For example:
//
// servers: [
// {role: "web", cpus: 1},
// {role: "db", cpus: 1},
// {role: "proxy", cpus: 1},
// ]
//
// #server: {
// role: string
// cpus: 1
// }
//
// servers: [...#server]
//
// Trim will simplify this to:
//
// servers: [
// {role: "web"},
// {role: "db"},
// {role: "proxy"},
// ]
//
// #server: {
// role: string
// cpus: 1
// }
//
// servers: [...#server]
//
// This works with defaults too. Given:
//
// servers: [
// {role: "web", cpus: 1},
// {role: "db", cpus: 4},
// {role: "proxy", cpus: 1},
// ]
//
// #server: {
// role: string
// cpus: *1 | int
// }
//
// servers: [...#server]
//
// Trim will simplify this to:
//
// servers: [
// {role: "web"},
// {role: "db", cpus: 4},
// {role: "proxy"},
// ]
//
// #server: {
// role: string
// cpus: *1 | int
// }
//
// servers: [...#server]
package trim
10 changes: 10 additions & 0 deletions tools/trim/testdata/1.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
TODO. This should get simplified in the same way as 6, but
doesn't. Possible bug in evaluator.

-- a.cue --
<10
7
-- out/trim --
== a.cue
<10
7
56 changes: 56 additions & 0 deletions tools/trim/testdata/10.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Similar to 9, but with list instead of struct. Note the simplification
of the pattern too.

See also 60.

-- a.cue --
d: [
{name: "jack", age: 5},
{name: "gill", age: >4},
{name: "hilbert", age: int},
]
d: [...{name: string, age: 5, age: number}]
-- out/trim-v3 --
== a.cue
d: [
{name: "jack"},
{name: "gill"},
{name: "hilbert"},
]
d: [...{name: string, age: 5}]
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -4,4 +4,4 @@
{name: "gill"},
{name: "hilbert"},
]
-d: [...{name: string, age: 5, age: number}]
+d: [...{name: string, age: 5}]
-- out/trim-v3-noshare --
== a.cue
d: [
{name: "jack"},
{name: "gill"},
{name: "hilbert"},
]
d: [...{name: string, age: 5}]
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -4,4 +4,4 @@
{name: "gill"},
{name: "hilbert"},
]
-d: [...{name: string, age: 5, age: number}]
+d: [...{name: string, age: 5}]
-- out/trim --
== a.cue
d: [
{name: "jack"},
{name: "gill"},
{name: "hilbert"},
]
d: [...{name: string, age: 5, age: number}]
30 changes: 30 additions & 0 deletions tools/trim/testdata/11.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Explicit unification of structs can lead to simplification.
Contrast with 4.

-- a.cue --
x: {a: bool, b: "hi"} & {a: true, b: string}
-- out/trim-v3 --
== a.cue
x: {b: "hi"} & {a: true}
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: "hi"} & {a: true, b: string}
+x: {b: "hi"} & {a: true}
-- out/trim-v3-noshare --
== a.cue
x: {b: "hi"} & {a: true}
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: "hi"} & {a: true, b: string}
+x: {b: "hi"} & {a: true}
-- out/trim --
== a.cue
x: {a: bool, b: "hi"} & {a: true, b: string}
30 changes: 30 additions & 0 deletions tools/trim/testdata/12.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
A variant of 11, with fields slightly rearranged. We do not currently
simplify explicit unification where one side is top.

-- a.cue --
x: {a: bool, b: string} & {a: true, b: "hi"}
-- out/trim-v3 --
== a.cue
x: _ & {a: true, b: "hi"}
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string} & {a: true, b: "hi"}
+x: _ & {a: true, b: "hi"}
-- out/trim-v3-noshare --
== a.cue
x: _ & {a: true, b: "hi"}
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string} & {a: true, b: "hi"}
+x: _ & {a: true, b: "hi"}
-- out/trim --
== a.cue
x: {a: bool, b: string} & {a: true, b: "hi"}
30 changes: 30 additions & 0 deletions tools/trim/testdata/13.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
A variant of 12, to ensure the ellipsis does not prevent
simplification of the struct to top.

-- a.cue --
x: {a: bool, b: string, ...} & {a: true, b: "hi"}
-- out/trim-v3 --
== a.cue
x: _ & {a: true, b: "hi"}
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string, ...} & {a: true, b: "hi"}
+x: _ & {a: true, b: "hi"}
-- out/trim-v3-noshare --
== a.cue
x: _ & {a: true, b: "hi"}
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string, ...} & {a: true, b: "hi"}
+x: _ & {a: true, b: "hi"}
-- out/trim --
== a.cue
x: {a: bool, b: string, ...} & {a: true, b: "hi"}
30 changes: 30 additions & 0 deletions tools/trim/testdata/14.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Further variation on 11: make sure patterns are kept, even if they're
not used.

-- a.cue --
x: {a: bool, b: string, [>"b"]: int} & {a: true, b: "hi"}
-- out/trim-v3 --
== a.cue
x: {[>"b"]: int} & {a: true, b: "hi"}
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string, [>"b"]: int} & {a: true, b: "hi"}
+x: {[>"b"]: int} & {a: true, b: "hi"}
-- out/trim-v3-noshare --
== a.cue
x: {[>"b"]: int} & {a: true, b: "hi"}
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: {a: bool, b: string, [>"b"]: int} & {a: true, b: "hi"}
+x: {[>"b"]: int} & {a: true, b: "hi"}
-- out/trim --
== a.cue
x: {a: bool, b: string, [>"b"]: int} & {a: true, b: "hi"}
30 changes: 30 additions & 0 deletions tools/trim/testdata/15.txtar
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Similar to 11, but with lists: explicit unification of lists can lead
to simplification.

-- a.cue --
x: [int, int, int] & [9, 8, 7]
-- out/trim-v3 --
== a.cue
x: [_, _, _] & [9, 8, 7]
-- diff/-out/trim-v3<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: [int, int, int] & [9, 8, 7]
+x: [_, _, _] & [9, 8, 7]
-- out/trim-v3-noshare --
== a.cue
x: [_, _, _] & [9, 8, 7]
-- diff/-out/trim-v3-noshare<==>+out/trim --
diff old new
--- old
+++ new
@@ -1,2 +1,2 @@
== a.cue
-x: [int, int, int] & [9, 8, 7]
+x: [_, _, _] & [9, 8, 7]
-- out/trim --
== a.cue
x: [int, int, int] & [9, 8, 7]
Loading

0 comments on commit e3d44f0

Please sign in to comment.