Szalinski : A Tool for Synthesizing Structured CAD Models with - - PowerPoint PPT Presentation

szalinski a tool for synthesizing structured cad models
SMART_READER_LITE
LIVE PREVIEW

Szalinski : A Tool for Synthesizing Structured CAD Models with - - PowerPoint PPT Presentation

Szalinski : A Tool for Synthesizing Structured CAD Models with Equality Saturation and Inverse Transformations PLDI 2020 Chandrakana Nandi , Max Willsey, Adam Anderson, James R. Wilcox, Eva Darulova, Dan Grossman, Zachary Tatlock Designing


slide-1
SLIDE 1

Chandrakana Nandi, Max Willsey, Adam Anderson, James R. Wilcox, Eva Darulova, Dan Grossman, Zachary Tatlock

Szalinski: A Tool for Synthesizing Structured CAD Models with Equality Saturation and Inverse Transformations

PLDI 2020

slide-2
SLIDE 2

Designing Physical Objects is Programming!

slide-3
SLIDE 3

Share with others Make your own models

CAD and 3D Printing everywhere!

slide-4
SLIDE 4

Share with others Make your own models

CAD and 3D Printing everywhere!

Editability is key!

slide-5
SLIDE 5
slide-6
SLIDE 6
slide-7
SLIDE 7

Mesh Decompilers Recover Flat Programs

Mesh Decompilers *

* Reincarnate [ICFP 2018],

InverseCSG [SIGGRAPH Asia 2018], Shape2Prog [ICLR 2019], CSGNet [CVPR 2018], …

> 1500 LOC

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-8
SLIDE 8

Primitives

Mesh Decompilers Recover Flat Programs

Mesh Decompilers *

* Reincarnate [ICFP 2018],

InverseCSG [SIGGRAPH Asia 2018], Shape2Prog [ICLR 2019], CSGNet [CVPR 2018], …

> 1500 LOC

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-9
SLIDE 9

Mesh Decompilers Recover Flat Programs

Mesh Decompilers *

* Reincarnate [ICFP 2018],

InverseCSG [SIGGRAPH Asia 2018], Shape2Prog [ICLR 2019], CSGNet [CVPR 2018], …

> 1500 LOC

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Primitives

Affine operators

slide-10
SLIDE 10

Mesh Decompilers Recover Flat Programs

Mesh Decompilers *

* Reincarnate [ICFP 2018],

InverseCSG [SIGGRAPH Asia 2018], Shape2Prog [ICLR 2019], CSGNet [CVPR 2018], …

> 1500 LOC

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Binary operators

Primitives

Affine operators

slide-11
SLIDE 11

Mesh Decompilers Recover Flat Programs

Mesh Decompilers *

* Reincarnate [ICFP 2018],

InverseCSG [SIGGRAPH Asia 2018], Shape2Prog [ICLR 2019], CSGNet [CVPR 2018], …

> 1500 LOC

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Repetition of spokes is not captured by flat program

slide-12
SLIDE 12

Szalinski: flat CAD parametrized CAD

Szalinski

This talk

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-13
SLIDE 13

Szalinski: flat CAD parametrized CAD

Szalinski

This talk

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-14
SLIDE 14

Szalinski: flat CAD parametrized CAD

Szalinski

This talk

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Fold and Tabulate represent loops

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

A language, called Caddy that supports CAD features & functional programming features like Fold, Tabulate, Map

slide-15
SLIDE 15

Szalinski: flat CAD parametrized CAD

Szalinski

This talk

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 3) (Rotate [0, 0, 120i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 45i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 8) (Rotate [0, 0, 45i] (Translate [1,−0.5,0] (Cuboid [15, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [15, 1, 1]))))))

Fold and Tabulate represent loops

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

edits edits

slide-16
SLIDE 16

Szalinski

This talk

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 3) (Rotate [0, 0, 120i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 45i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 8) (Rotate [0, 0, 45i] (Translate [1,−0.5,0] (Cuboid [15, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [15, 1, 1]))))))

Fold and Tabulate represent loops

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

edits edits

Automatically infer loops from straight line programs in the form of Folds, Maps, and Tabulates

Hypothesis: Parametrized programs are easier to read/customize than flat programs

Szalinski: flat CAD parametrized CAD

slide-17
SLIDE 17

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input to Szalinski

slide-18
SLIDE 18

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Term Rewriting

slide-19
SLIDE 19

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

Term Rewriting

Fold Union Rewrite

slide-20
SLIDE 20

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Term Rewriting

Structure Finder

Fold Union Rewrite

slide-21
SLIDE 21

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Term Rewriting

Structure Finder Structure Finder

Fold Union Rewrite

*

slide-22
SLIDE 22

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Term Rewriting

Structure Finder Structure Finder Custom Solver

Fold Union Rewrite

* *

slide-23
SLIDE 23

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Term Rewriting

Structure Finder Structure Finder Custom Solver

Fold Union Rewrite

*

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Lift Tabulate Rewrite

* *

slide-24
SLIDE 24

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Term Rewriting

Structure Finder Structure Finder Custom Solver

Fold Union Rewrite

*

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Lift Tabulate Rewrite

* *

slide-25
SLIDE 25

Structure Finder

List (Op [param 1] (arg 1)) (Op [param 2] (arg 2)) (Op [param 3] (arg 3)) … Map2 Op (List [param 1] [param 2] [param 3]) (List (arg 1) (arg 2) (arg 3))

slide-26
SLIDE 26

Structure Finder

List (Op [param 1] (arg 1)) (Op [param 2] (arg 2)) (Op [param 3] (arg 3)) … Map2 Op (List [param 1] [param 2] [param 3]) (List (arg 1) (arg 2) (arg 3))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] [0, 0, 120] [0, 0, 180] [0, 0, 240] [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) … (Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Fold Union Rewrite

List 1

}

List 2

slide-27
SLIDE 27

Structure Finder

List (Op [param 1] (arg 1)) (Op [param 2] (arg 2)) (Op [param 3] (arg 3)) … Map2 Op (List [param 1] [param 2] [param 3]) (List (arg 1) (arg 2) (arg 3))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] [0, 0, 120] [0, 0, 180] [0, 0, 240] [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) … (Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Fold Union Rewrite

Map2 applies the operator to the ith element of the first list and ith element of the second list

List 1

}

List 2

slide-28
SLIDE 28

Structure Finder

List (Op [param 1] (arg 1)) (Op [param 2] (arg 2)) (Op [param 3] (arg 3)) … Map2 Op (List [param 1] [param 2] [param 3]) (List (arg 1) (arg 2) (arg 3))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] [0, 0, 120] [0, 0, 180] [0, 0, 240] [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) … (Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Fold Union Rewrite

Map2 applies the operator to the ith element of the first list and ith element of the second list

List 1

}

List 2 Also applies to this list

slide-29
SLIDE 29

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Custom Solvers

Structure Finder Custom solver

The concrete list of vectors is passed to a custom solver that finds a closed form arithmetic expression

slide-30
SLIDE 30

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Term Rewriting

Structure Finder Structure Finder Custom Solver

Fold Union Rewrite

*

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Lift Tabulate Rewrite

* *

slide-31
SLIDE 31

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Union (Cylinder [1, 5, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1])))))) (Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (Tabulate (i 6) (0, 0, 60i)) (Map2 Translate (Repeat 6 [1, −0.5, 0] (Repeat 6 (Cuboid [10, 1, 1]))))))

Structure Finder Structure Finder Custom Solver

Fold Union Rewrite

*

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Lift Tabulate Rewrite

* *

Inputs to Szalinski are rarely ideal!

Term Rewriting

slide-32
SLIDE 32

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-33
SLIDE 33

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-34
SLIDE 34

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Previous rewriting strategy no longer works!

slide-35
SLIDE 35

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Must interleave rewriting strategy with CAD identities to line up subexpressions

slide-36
SLIDE 36

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Must interleave rewriting strategy with CAD identities to line up subexpressions

Phase ordering problem: order of rewriting matters!

slide-37
SLIDE 37

(Union (Cylinder [1, 5]) (Union (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Ideal Input vs Actual Input

(Union (Scale [5,5,1] (Cylinder [1,1])) (Union (Rotate [0,0,120] (Translate [1,−0.5,0] (Cuboid [10,1,1]))) (Scale [10,1,1] (Translate [0.1,−0.5,1] (Cuboid [1,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Translate [−1,0.5,0] (Scale [−1,−1,1] Cuboid [10,1,1])) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

E-graphs* can solve phase ordering

* Equality Saturation: A New Approach to Optimization. Tate, Stepp, Tatlock, Lerner. POPL’09

Must interleave rewriting strategy with CAD identities to line up subexpressions

Phase ordering problem: order of rewriting matters!

slide-38
SLIDE 38

Semantically Equivalent, Syntactically Different

(Union (Cylinder [1, 5]) (Fold Union (List (Translate [1, −0.5, 0] (Cube [10, 1, 1])) (Rotate [0,0,60] (Translate [1,−0.5,0] (Cube[10,1,1]))) (Rotate [0,0,120] (Translate [1,−0.5,0] (Cube[10,1,1]))) (Scale [−1,−1,1] (Translate [1,−0.5,0] (Cube[10,1,1]))) (Rotate [0,0,240] (Translate [1,−0.5,0] (Cube[10,1,1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cube [10, 1, 1]))))))

Rotate [0, 0, 180] is replaced by equivalent Scale [-1, -1, 1]

slide-39
SLIDE 39

Rotate [0, 0, 180] (Translate [1,−0.5,0] (Cube[10,1,1]))

= Syntactic rewrite

Rotate (0, 0, 180, c)) ↭ Scale (−1, − 1, 1, c))

Scale [-1, -1, 1] (Translate [1,−0.5,0] (Cube[10,1,1]))

Semantically Equivalent, Syntactically Different

slide-40
SLIDE 40

Rotate [0, 0, 180] (Translate [1,−0.5,0] (Cube[10,1,1]))

= Syntactic rewrite

Scale [-1, -1, 1] (Translate [1,−0.5,0] (Cube[10,1,1]))

Store Expressions in an E-graph

Rotate (0, 0, 180, c)) ↭ Scale (−1, − 1, 1, c))

Cube

[0, 0, 180] [1, -0.5, 0]

Rotate Translate

slide-41
SLIDE 41

Rotate [0, 0, 180] (Translate [1,−0.5,0] (Cube[10,1,1]))

= Syntactic rewrite

Scale [-1, -1, 1] (Translate [1,−0.5,0] (Cube[10,1,1]))

Store Expressions in an E-graph

Rotate (0, 0, 180, c)) ↭ Scale (−1, − 1, 1, c))

EClass

Edges from Enodes to Eclasses

Cube

[0, 0, 180] [1, -0.5, 0]

ENode Rotate Translate

slide-42
SLIDE 42

Syntactic rewrite

Rotate [0, 0, 180] (Translate [1,−0.5,0] (Cube[10,1,1]))

=

Scale [-1, -1, 1] (Translate [1,−0.5,0] (Cube[10,1,1]))

Cube

Store Expressions in an E-graph

Scale

Rotate (0, 0, 180, c)) ↭ Scale (−1, − 1, 1, c))

EClass

Edges from Enodes to Eclasses

Cube

[0, 0, 180] [1, -0.5, 0]

ENode

[0, 0, 180] [1, -0.5, 0] [-1, -1, 1]

Rotate Rotate Translate Translate

slide-43
SLIDE 43

Union

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Fold

Custom Solvers in E-graph

Outer List

Outer list

slide-44
SLIDE 44

Outer List

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers in E-graph

Outer list

Union Fold Map2

slide-45
SLIDE 45

Outer List

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers in E-graph

Outer list

Union Fold Rotate Map2

slide-46
SLIDE 46

Outer List

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers in E-graph

Outer list

Union Fold Rotate List Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

slide-47
SLIDE 47

Outer List

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers in E-graph

Outer list

Union Fold Rotate … List Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

CAD arguments

slide-48
SLIDE 48

Union Rotate

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

… Fold List

Custom Solvers in E-graph

Outer List

Outer list

Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

[0, 0, 60 * i]

slide-49
SLIDE 49

Union Rotate

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

… Fold List

Tabulate

Custom Solvers in E-graph

Outer List

Outer list

Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

[0, 0, 60 * i]

slide-50
SLIDE 50

Union Rotate

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

… Fold List

Custom Solvers in E-graph

Outer List

Outer list

Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

[0, 0, 60 * i]

Tabulate

Bounds i to 6

slide-51
SLIDE 51

Union Rotate

(Union (Cylinder [1, 5, 5]) (Fold Union (Map2 Rotate (List [0, 0, 0] [0, 0, 60] … [0, 0, 300]) (List (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])) …

Structure Finder

(Union (Cylinder [1, 5]) (Fold Union (List (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

… Fold List

Custom Solvers in E-graph

Outer List

Outer list

Map2

[0, 0, 60] [0, 0, 0] [0, 0, 240] [0, 0, 120] [0, 0, 180] [0, 0, 300]

[0, 0, 60 * i]

Tabulate

slide-52
SLIDE 52

Custom Solvers for Non-Ideal Inputs

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Expressions are arbitrarily ordered Parameters of Rotate are not sorted

slide-53
SLIDE 53

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers for Non-Ideal Inputs

slide-54
SLIDE 54

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers for Non-Ideal Inputs

Parameters of Rotate are NOT sorted

slide-55
SLIDE 55

Parameters of Rotate are NOT sorted

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

List of vectors must be sorted for the solver to be able to find the closed form and unify the Tabulate with the concrete list

Custom Solvers for Non-Ideal Inputs

slide-56
SLIDE 56

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom Solvers for Non-Ideal Inputs

Parameters of Rotate are NOT sorted

slide-57
SLIDE 57

Naive Solution for Finding Closed Form

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Add all permutations

  • f the list elements in

the E-graph

slide-58
SLIDE 58

Naive Solution Causes the AC-Matching Problem

Add all permutations

  • f the list elements in

the E-graph

Exponentially many choices in an E-graph due to associative- commutative operations like permuting lists, called AC- matching in the SMT community

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

slide-59
SLIDE 59

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Inverse Transformations

Key insight: allows solvers to speculatively transform their inputs to enable more profitable rewriting

slide-60
SLIDE 60

Inverse Transformations

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-61
SLIDE 61

Inverse Transformations

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Structure Finder

slide-62
SLIDE 62

Inverse Transformations

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Structure Finder

Union

Rotate

Map2

List

[0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60] Fold

slide-63
SLIDE 63

Inverse Transformations

(Union (Scale [5,5,1] (Cylinder [1,1])) (Fold Union (List (Rotate [0, 0, 120] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 0] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 300] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 180] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 240] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))) (Rotate [0, 0, 60] (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Structure Finder

Union

Rotate

Map2

List Outer List

Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

slide-64
SLIDE 64

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-65
SLIDE 65

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form! (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-66
SLIDE 66

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form! (Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-67
SLIDE 67

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form!

Solver annotates the expression with the profitable permutation

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-68
SLIDE 68

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form!

Solver annotates the expression with the profitable permutation

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

If a solver cannot simplify A, but it can simplify (A) to B, then -1(B) can be unified with A

f f

slide-69
SLIDE 69

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form!

Flexibly combines solvers with an egraph-driven rewrite system Solvers allowed to transform their input however they want BUT they must 'undo' the transformation to restore equivalence

Solver annotates the expression with the profitable permutation

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

slide-70
SLIDE 70

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form!

Solver annotates the expression with the profitable permutation

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

If a solver cannot simplify A, but it can simplify (A) to B, then -1(B) can be unified with A

f f

slide-71
SLIDE 71

Inverse Transformations

(Fold Union (Map2 Rotate (List [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 180] [0, 0, 240] [0, 0, 60]) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Solver permutes the list to find closed form!

Solver annotates the expression with the profitable permutation

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

If a solver cannot simplify A, but it can simplify (A) to B, then -1(B) can be unified with A

f f

This unification is sound!

slide-72
SLIDE 72

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Goal

slide-73
SLIDE 73

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Syntactic rewrites Propagate and Eliminate

Goal

slide-74
SLIDE 74

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))) (Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

slide-75
SLIDE 75

Inverse Transformations

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-76
SLIDE 76

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List

Unsort

Unsort added to the e-class of Map2 and the Outer List

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-77
SLIDE 77

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Unsort

slide-78
SLIDE 78

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Unsort

slide-79
SLIDE 79

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

Unsort

slide-80
SLIDE 80

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

Unsort

Sorts Outer List which is equivalent to Map2

Outer List

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-81
SLIDE 81

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Syntactic rewrites Propagate and Eliminate Effectively a no-op, but allows sorting the concrete list equivalent to Map2

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

Unsort

Structure Finder and Custom Solvers apply

  • n this sorted

list

(Fold Union (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))

slide-82
SLIDE 82

Inverse Transformations

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

(Fold Union (Unsort <1 5 0 3 4 2> (Tabulate (i 6) (Rotate [0, 0, 60 * i]) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Custom solvers

  • n the sorted
  • uter list

Goal

Map2

Outer List Tabulate

<1 5 0 3 4 2>

Unsort

Union Fold [0, 0, 180] [0, 0, 120] [0, 0, 0] [0, 0, 300] [0, 0, 240] [0, 0, 60]

List Sort

Unsort

Structure Finder and Custom Solvers apply

  • n this sorted

list

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

slide-83
SLIDE 83

Inverse Transformations

Syntactic rewrite to eliminate Unsort

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

(Fold Union (Unsort <1 5 0 3 4 2> (Tabulate (i 6) (Rotate [0, 0, 60 * i]) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Fold Union is invariant to list order

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Custom solvers

  • n the sorted
  • uter list
slide-84
SLIDE 84

Inverse Transformations

Syntactic rewrite to eliminate Unsort

(Union (Cylinder [1, 5, 5]) (Fold Union (Tabulate (i 6) (Rotate [0, 0, 60i] (Translate [1,−0.5,0] (Cuboid [10, 1, 1]))))))

Goal

(Fold Union (Unsort <1 5 0 3 4 2> (Tabulate (i 6) (Rotate [0, 0, 60 * i]) (Translate [1, −0.5, 0] (Cuboid [10, 1, 1]))))))

Fold Union is invariant to list order

(Fold Union (Unsort <1 5 0 3 4 2> (Sort <1 5 0 3 4 2> (Map2 Rotate (Unsort <1 5 0 3 4 2> (Tabulate (i 6) [0, 0, 60 * i])) (Repeat 6 (Translate [1, −0.5, 0] (Cuboid [10, 1, 1])))))))

Custom solvers

  • n the sorted
  • uter list

Rewrites applied until saturation (or timeout) and a cost function (AST size) used to extract best program

Example transformations: sorting, partitioning, cartesian-to-spherical

slide-85
SLIDE 85

Implementation

~ 2000 LOC in Rust 65 rewrites https://github.com/uwplse/szalinski Uses the Egg E-graph library: https://github.com/mwillsey/egg

Talk to Max about Egg!

slide-86
SLIDE 86

End-to-End Evaluation

Results of running Szalinski on

  • utputs of

Reincarnate*

AST size 100 200 300 400 Benchmarks

Input AST size Output AST size

* [ICFP 2018]

slide-87
SLIDE 87

2127 programs from Thingiverse Tiny: AST size < 30 Small: 30 < AST size < 100 Medium: 100 < AST size < 300 Large: AST size > 300

Larger programs shrink more < 1 second

Scalability

% shrunk Tiny Small Medium Large 20 40 60 80 100

slide-88
SLIDE 88

Examples

(Fold Difference (List (Union (Cylinder [100, 80, 80]) (Cylinder [50, 120, 120])) (Translate [0, 0, -1] (Cylinder [102, 25, 25])) (Fold Union (Tabulate (i 60) (Rotate [0, 0, 6 * i] (Translate [125, 0, 0] (Scale [2.5, 1, 1] (Rotate [0, 0, 45] (Translate [0, 0, 25] (Cuboid [10, 10, 52])))))))))) (Fold Union (Tabulate (i 10) (j 5) (Translate [12.2 * i + 12.2, 12.2 * j + 12.2, 0] (Difference (Cylinder [13, 7.1, 7.1]) (Translate [0, 0, 3] (Cylinder [11, 5.1, 5.1]))))))

350 LOC 250 LOC

(Fold Union (Tabulate (i 12) (Translate [0, 13* i, 0] (Fold Difference (List (Cuboid [53.1 14.5 58]) (Translate [1.5, 1.5, 1.5] (Cuboid [51.6, 11.5, 56.6])) (Translate [0 0 58] (Rotate [0, 45, 0] (Cuboid [101.5, 14.5, 100]))))))))

100 LOC

slide-89
SLIDE 89

Szalinski: A Tool for Synthesizing Structured CAD Models with Equality Saturation and Inverse Transformations

Chandrakana Nandi, Max Willsey, Adam Anderson, James R. Wilcox, Eva Darulova, Dan Grossman, Zachary Tatlock

https://github.com/uwplse/szalinski

Inverse Transformations with E-graphs to find concise, structured programs in < 1 second