penrose / penrose Goto Github PK
View Code? Open in Web Editor NEWCreate beautiful diagrams just by typing notation in plain text.
Home Page: https://penrose.cs.cmu.edu
License: MIT License
Create beautiful diagrams just by typing notation in plain text.
Home Page: https://penrose.cs.cmu.edu
License: MIT License
Set A, B
f: A -> B
AutoLabel A, B
Label f $\sum_i^n \frac{x^2}{10}$
We support three kinds of statements in our labeling DSL:
Nolabel xs
: forbids Substance objects from having labels. xs
is a comma separated list of Substance identifiers.Label x s
: normal declaration of labels. Gives a Substance object with identifier x
a label, where the content of the label is specified by s
. s
is a TeX expression in math environment ("$f$"
) (TODO: do we want to have labels that are outside of math env as well, say "hello world"
?)Autolabel xs
: automatically generates labels for all identifiers in xs
. By default, a Substance id a
will be translated into TeX math environment as $a$
.
All
can replace xs
, which just refers to all Substance ids.The semantics of label statements are determined by the ordering of them in the source file.
A
will end up not having any label.Label A "AA"
AutoLabel A
NoLabel A
In the system, we would add the two kinds of label declarations (manual vs. auto labeling) to the options of Substance statements.
data SubStmt = {- all other Substance stmts -} | LabelDecl String String | AutoLabel [String]
Set A, B
AutoLabel A, B
f: A -> B
Label f $\sum_i^n \frac{x^2}{10}$
X
, will have a Graphical Primitive Instance (GPI) X.text
, which is of type Text
. If more than one shape is related to X
and we want to assign labels to these objects, we can do:Set A {
component_1 = Circle {
text = concat(A.text, "_1")
}
component_2 = Square {
text = concat(A.text, "_2")
}
}
"hello world"
? If everything is by default in math env, then the following will be rendered as the label:Label A "hello $f$"
). --> Currently this is NOT supported and label text has to be enclosed by either quotes or dollar signs. The two cannot be mixed
\textrm
works in MathJax!if x.labeled
, where labeled
is a built-in field in a Substance objectSet A {
if A.labeled: labelFn = encourage -- some objective
}
Labeled
in the core Substance language, so that we can write selectors for them:Set A
where Labeled(A) { labelFn = encourage -- some objective }
e.g. linear algebra and mesh diagrams, or see L. Kuper's comment on Twitter.
Currently only the gloss frontend outputs debug messages.
...to make sure the diagram fits well and is centered.
In particular, it could be nice to check the properties of exhaustiveness and non-redundancy (in analogy to pattern-matching).
Checking exhaustiveness “statically” would entail showing that a Style can “visualize anything writable in this DSL.”
Checking exhaustiveness “dynamically” would entail showing that a Style will “visualize everything in this particular Substance program” (nothing has been accidentally left out).
Checking non-redundancy “statically” would entail checking that no selectors are the same or equivalent.
See PFPL, 1st ed, chapter 13.
Right now all points in the curve are fixed. Can we make them a part of the optimization parameters?
Parse forall x, P(x)
and exists x, P(x)
in Substance
Handle the binding structure of nesting quantifiers
Design a quantifier pattern-matching mechanism in Style
Find common diagrams that show the visual semantics of forall
or exists
Write the visual semantics in Style programs
Design interaction techniques for the semantics (e.g. forall
lets you drag a point and exists
does not)
Implication: ?
This GitHub issue tracker has too many "bucket list" and "nice to have, one day" research ideas as issues. It's useful to track and label these ideas for future students, but it's hard to find the real issues among them. Therefore, I plan to make a separate repository or README to store the bucket list.
The system seems to have problems optimizing certain constraints. Running the following command has several problems. ./Main snap sub/twosets.sub sty/venn_comp.sty
constraint contains(y, x)
does not work well in two scenarios: 1. with any objective on the labels, or 2. if the constraint on containment starts off violated.constraintFlag = True
means that the Subset constraint is initially satisfied, which defeats the purpose. Even if the flag is false, the system does not guarantee that at least one constraint is violated, as the rng seed might be set such that the constraints happen to be satisfied.strictSubset
being written incorrectly? (Seems to work though.) A problem with circle packing and unpacking?Temporarily resolved. To fully resolve:
strictSubset
still work as a valid penalty?TBD.
In frontend, show toolbar with some of the following:
With adjustable parameters, e.g. a
and b
in line search.
Notes:
(Could the design of optimization visualization/debugging UIs be a research question in itself??)
computeOn
so people don't have to implement typechecking.Give examples of how to add/modify new objects, functions, computations.
A lot of these can be done using Template Haskell's quoting and reification features: https://wiki.haskell.org/A_practical_Template_Haskell_Tutorial#Reification
After the optimization is done in snap with autostep, sometimes the diagrams will disappear:
Also, sometimes the diagram will disappear after autostep is changed from on to off.
Maybe the server is dropping frames?
I've sometimes been able to get the disappearing problem to stop by restarting the Haskell server.
This happens on branch shapes
, with either of the following two commands: ./Main snap sub/cart-test.sub sty/cart-test.sty
or ./Main snap sub/twopoints.sub sty/twopoints.sty
Similar to Elm's online editor. http://elm-lang.org/examples/buttons
The first step here is to replace some of the parameters in the computations/objectives with negative numbers (see the sample programs in the wiki), see what breaks, and then fix the parser.
Possibly following this guide: https://www.schoolofhaskell.com/school/to-infinity-and-beyond/pick-of-the-week/parsing-floats-with-parsec#minus
...perhaps with an emacs or Atom mode.
GUI changes to the diagram (location, duplication, etc.) should be inferred/applied/stored in the Substance program, and vice versa. Depends on #17.
...instead of just one diagram at a time.
If an optimization involves a computation, e.g. objective repel(f(x), g(y), 10)
, and the parameters are varying, let the optimization/autodiff differentiate through f
and g
by having the user provide df/dx
and dg/dy
.
This issue has two goals:
Some first steps:
venn.sty
where the circles are now semi-transparent spheres.More specifically:
Later:
Stretch goal:
To look into:
More internal discussion, and links to related work, can be found here.
Style writers and implementers need abstractions for optimizing the relationships between any pair of objects, rather then having to write special-purpose graphics code for every new objective/constraint function and every n-ary combination of graphical primitives.
Therefore, to improve the generality of our optimizer and the user experience for Style implementers, do the following:
For any object and any point in the plane, add the ability to compute a signed distance function from that point to the object (positive if outside, negative if inside). Additionally, compute level sets of distances for use in margins.
Test how well your implementation works with the existing optimizer and how well it works with the existing Styles. Specifically, test the following two important applications of signed distance:
This issue depends on issue #75.
I've started documenting the test infrastructure and the working and not-working program pair examples in the Penrose wiki.
Would be nice to have code coverage stats. stack test --coverage
doesn't yet work.
TODO:
Eventually:
All function comments should be illustrated by and accompanied by concrete examples.
For example, "f gives the head of a reversed list" is better written as "On an example list y = [1,2,3], f reverses the list to [3,2,1] and returns the head element [3]."
Even better, these concrete examples should just be written as unit tests (#8). Better readability and usability.
Also, make all assumptions explicit, e.g. "f assumes that the input list y is nonempty." Ideally, enforce them via invariants: "f [] = error 'empty list'" or better.
All function declarations should have type annotations, unless typeclasses and polymorphism make it too unwieldy.
Try to avoid single-letter variable names unless it's i
, j
, (index), n
(number), or a specific parameter without meaning (e.g. a
in line search).
In where
clauses, declare things in definition order, like you would in a series of let
clauses.
Standardize where
vs. let
usage. (I prefer let, since it enforces an order that is more readable.)
With constraint at(A, 0, 0)
, the set sizes blow up and then NaN. Only happens in snap, not gloss. Programs: https://www.dropbox.com/s/pqhphxgrn31wp98/Screenshot%202017-10-23%2017.57.20.png?dl=0
[Potential ramp-up task for Lily]
If we implemented our own PRG (or family of PRGs) with the autodiff, depending on the kind of PRG, we might be able to differentiate with respect to the PRG's parameters to minimize a loss. (Being able to differentiate with respect to the PRG's input would probably break the "pseudorandom" property.) That means we could, say, generate new "random" points (or other mathematical objects) that improve label legibility in a smaller bounding box.
Now
Fixed/varying
Soon
computeRadius
function, allow attributes (or references to attributes?) to be passed in to computationsLater
~
and *
syntax in StyleOne day
I ran ghc Runtime.hs
to compile the system and got the following error message:
$ ghc Runtime.hs
[2 of 2] Compiling Main ( Runtime.hs, Runtime.o )
Runtime.hs:1231:42: error:
• Could not deduce (Floating a0)
from the context: (Floating a2,
Show a3,
Ord a3,
Floating a3,
Real a3)
bound by the type signature for:
objFnUnconstrained :: (Floating a2, Show a3, Ord a3, Floating a3,
Real a3) =>
[a3] -> [a3] -> a3
at Runtime.hs:1231:42-63
The type variable ‘a0’ is ambiguous
• In the ambiguity check for ‘objFnUnconstrained’
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature:
objFnUnconstrained :: Floating a => ObjFn2 a
In an equation for ‘objFnPenalty’:
objFnPenalty weight
= combineObjfns objFnUnconstrained weight
where
objFnUnconstrained :: Floating a => ObjFn2 a
objFnUnconstrained = centerObjs
I had to enable AllowAmbiguousTypes
to compile normally.
Learn the Substance program from a sketch or series of strokes, similar to this paper: https://arxiv.org/abs/1707.09627
See graphics class and DDG course notes.
Create GUI capabilities that are aware of optimization objectives and constraints. Cinderella and CAD tools are examples of tools that are constraint-aware. The novelty is in designing a UI for Penrose that is also objective-aware. Some interesting problems:
The initial exterior point weight seems very high. But the error doesn't happen in snap.
Candidates: Elm, Purescript, Typescript, Javascript, maybe using d3, Svelte, Snap, React.
Figure out the state of web support in the following:
Figure out which parts of the backend to leave in Haskell.
To accomplish the cartesian coordinate system visualization for function, we need the following new geometries:
initCurve
function, where I hard coded a list of points for testing purposesCurve { path = [(0, 0), (100, 100)] }
computation
.Located
interface, I had to do some computation to properly do translation of all points on a path. I awkwardly returned the center of the bbox for getX
and getY
. We should change Located
very soon. #22 requires a total rewrite on this, so I guess we can deal with it soon.[(a, a)]
M
C
[(10, 100), (50, 0), (60, 0), (100, 100), (250, 250), (300, 100)]
gets translated into "M 10 100 C 50 0, 60 0, 100 100 S 250 250, 300 100"
Curve
type geometry with a path of only two points is a lineCurve { style = "dashed" }
where a lookup for style
is hardcoded in Runtime.hs
in initCurve
function. The righthand side can be arbitrary strings here. It is up to the frontend to decide what to render.-- Substance
Set A, B
f: A -> B
-- Style
Map f x y {
-- Shape of the curve determined by the hard coded path
shape = Curve {
style = "dashed" -- if unspecified or set to anything else, a solid line appears
}
}
In principle, the exterior point method requires the initial state to start in the exterior of the feasible region; that is, at least one of the constraints should be violated. See this overview of the EP method.
In practice, it doesn't seem to matter for our small examples (so this issue isn't really a bug yet). Currently we sample an initial state according to the initRng
seed and it may or may not satisfy all the constraints (it's more likely not to if there are more constraints).
But we should do the principled thing eventually, and provide a boolean constraint function with each penalty-version constraint function, so sampleConstrainedState
can use it according to the Style program.
...and rename the fields of objects accordingly to be much more concise and consistent. https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields
With commit 5a705a on shapes
, the Bézier curve does not show up in snap, in Chrome, on a Mac. It seems to be caused by a Chrome extension that I have, since it works in incognito and in Safari, and the CB is successfully sent in JSON.
Chrome version: Version 62.0.3202.89 (Official Build) (64-bit)
Programs: cart-test.sub
cart-test.sty
There are a lot of inline TODOs and FIXMEs. Let's document the reasons behind them, remove them, or fix them.
We currently support lines that look something like this:
Vector v, w
Scalar u
InnerProduct u v w
We want to support a line like this: u := <v, w>
We need:
u, v, w
(and/or do typechecking)innerProduct
u := <v, w> + det(x) + 4
(and figure out what we want to allow the user to write)See Keenan's linear algebra spec for examples.
With the debug output in the computation
branch, it seems that Style programs are being analyzed and parsed multiple times during runtime, each time a diagram is re-sampled. This is unnecessary as programs won't change during runtime.
See project proposal here (internal link).
Better to just support one frontend.
What needs to be changed across Substance, Style, Runtime, etc. if an implementer simply wants to add a statement like Scalar c := innerProduct(v, w)
and style it in a custom manner?
The following program does not parse and I believe it should:
Set A
Point B
In B A
Running ./Main snap sub/venn_comp_pt.sub sty/venn_comp_simple.sty
gives this error:
Main: sub/venn_comp_pt.sub:3:1:
unexpected 'I'
expecting alphanumeric character, end of input, letter, or newline
CallStack (from HasCallStack):
error, called at ./Substance.hs:341:18 in main:Substance
Add language constructs for specifying the staging, or order, or a diagram, as it might be used in a talk, animation, or presentation.
Comment from Keenan: Would also be good to infer, as much as possible, a default ordering (e.g., based on logical dependencies).
Also we need to allow users to specify diagram display / layering order (so shapes with transparency don't display on top of labels, and so on).
In most diagrams, there is on the order of tens of parameters to optimize, and the system visibly takes a few seconds to lay it out. Figure out where the bottleneck is: JSON message-passing? optimization? something else?
For example, ellipses take an especially long time to optimize: ./Main snap sub/composition.sub sty/composition.sty
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.