penrose (empty) → 0.1.0.0
raw patch · 6 files changed
+235/−0 lines, 6 filesdep +addep +aesondep +basesetup-changed
Dependencies added: ad, aeson, base, containers, gloss, megaparsec, old-time, random, text, websockets
Files
- ChangeLog.md +5/−0
- LICENSE +21/−0
- README.md +98/−0
- Setup.hs +3/−0
- penrose.cabal +25/−0
- src/Main.hs +83/−0
+ ChangeLog.md view
@@ -0,0 +1,5 @@+# Revision history for penrose++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2017 ++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,98 @@+# Penrose++We're building a prototype for set theory. Not ready for contributions or public use yet, but hopefully will be after this summer! See penrose.ink for more information.++----++### Usage++Install any relevant packages: `cabal install $PACKAGE_NAME` (though I'm told the Haskell community has moved on to the better `stack` package manager).++To compile both:+`ghc Runtime.hs`++To just compile Compiler:+`ghc Compiler.hs`++To use:+`./Runtime <filename>.sub <filename>.sty`++User interface:+* You can click and drag the objects, including labels. The optimization will pause while dragging and re-layout when the mouse is lifted. The object on top is semi-arbitrary, decided by the order of the objects in the internal list.+* Pressing the `R` key will resample the configuration. +* Pressing the `A` key will turn autostep (automatically stepping the optimization) on or off. +* Pressing the `S` key will step the optimization by one step if autostep is off. It won't do anything if autostep is on.++Examples of existing pairs:+* twosets.sub settheory.sty+* continuousmap1.sub continuousmap1.sty (system doesn't currently handle this)++----++### Organization++`src` contains the compiler and runtime.++`src/GC-slides` contains slides from weekly group meetings.++`src/gifs` and `src/pictures` contain GIFs and pictures documenting new features in the system.++Other directories in the root contain documentation and old parts of the system.++----++### More information++I use the following library to handle the graphics, animation, and user input: [gloss](https://hackage.haskell.org/package/gloss-1.10.2.3/docs/Graphics-Gloss-Interface-Pure-Game.html).++Functionality of the current code:++* gradient-descent-based layout +* with backtracking line search +* for set theory with points, sets, and certain constraints on points and sets+* with very simple objective functions provided (e.g. centering)+* where the layout is animated and interactive (v. useful for debugging)++Some limitations: ++* line search sometimes doesn't terminate+* need a better debugging interface for optimization, e.g. live parameter tuning++Parameters: ++* stepsPerSecond: number of simulation steps for `gloss` to take for each second of real time+* picWidth, picHeight: canvas dimensions+* stepFlag: turns stepping the simulation on and off for debugging (no stepping = objects don't move)+* clampFlag: turns clamping gradient values on and off for debugging+* debug: turns on/off the debug print functions+* constraintFlag: turns constraint satisfaction on/off (currently off because we're doing unconstrained optimization)+* Default ambient objective functions are specified in `ambientObjFns`, and analogously for `ambientConstrFns`.+* Default objective functions are specified in `genObjsAndFns`.+* btls: turn on/off the backtracking line search for debugging (off = use a fixed timestep specified in the code)+* alpha and beta: parameters for the backtracking line search (see code for a more detailed description)+* stopEps: stopping condition sensitivity for gradient descent. Stop when magnitude of gradient is less than stopEps.++Debugging:++* Use the flags above.+* I also use `ghci`, the Haskell REPL. To load the file, do `:l filename.hs`. To import a library, paste in the normal import statement. To declare something, start with a `let` statement, e.g. `let x = 5`.+* For printing internal values, I use the [Debug.Trace](https://hackage.haskell.org/package/base-4.9.0.0/docs/Debug-Trace.html) library.++----+ +### Design++* Compiler parses the Substance and Style programs and combines their abstract syntax trees into Layout (the intermediate layout representation).+* Runtime calls Compiler on the input files, and transforms the data in Layout to Opt (the representations used by the optimization code).+* Runtime imports Compiler as a module.++----++### Usage for old code++Compile: `ghc settheory.hs`++Create SVG: `./settheory -w 500 -h 500 -o set.svg`+(The parameters are the width and height of the rendered picture.)++Open SVG: `chrome set.svg`
+ Setup.hs view
@@ -0,0 +1,3 @@+import Distribution.Simple++main = defaultMain
+ penrose.cabal view
@@ -0,0 +1,25 @@+-- Initial penrose.cabal generated by cabal init. For further +-- documentation, see http://haskell.org/cabal/users-guide/++name: penrose+version: 0.1.0.0+synopsis: A system that automatically visualize mathematics+-- description: +homepage: http://penrose.ink+license: MIT+license-file: LICENSE+author: team-penrose+maintainer: kqy@cs.cmu.edu+-- copyright: +-- category: +build-type: Simple+extra-source-files: ChangeLog.md, README.md+cabal-version: >=1.10++executable penrose+ main-is: Main.hs+ -- other-modules: + other-extensions: AllowAmbiguousTypes, RankNTypes, UnicodeSyntax, NoMonomorphismRestriction, OverloadedStrings, DeriveGeneric, DuplicateRecordFields+ build-depends: base >=4.9 && <4.10, random >=1.1 && <1.2, containers >=0.5 && <0.6, gloss >=1.11 && <1.12, megaparsec >=5.3 && <5.4, ad >=4.3 && <4.4, aeson >=1.2 && <1.3, text >=1.2 && <1.3, websockets >=0.11 && <0.12, old-time >=1.1 && <1.2+ hs-source-dirs: src+ default-language: Haskell2010
+ src/Main.hs view
@@ -0,0 +1,83 @@+-- | Main module of the Penrose system+module Main where+import Graphics.Gloss+import Graphics.Gloss.Data.Vector+import Graphics.Gloss.Interface.Pure.Game+import qualified Server+import qualified Runtime as R+import qualified Compiler as C+import qualified StyAst as SA+import qualified Text.Megaparsec as MP (runParser, parseErrorPretty)+import System.Environment+import System.IO+import System.Exit+import Control.Monad(when)+++divLine = putStr "\n--------\n\n"++-- | `main` runs the Penrose system+main :: IO ()+main = do+ -- Reading in from file+ -- Objective function is currently hard-coded+ -- Comment in (or out) this block of code to read from a file (need to fix parameter tuning!)+ args <- getArgs+ when (length args /= 3) $ die "Usage: ./Main <snap|gloss> prog1.sub prog2.sty"+ let (mode, subFile, styFile) = (head args, args !! 1, args !! 2)+ subIn <- readFile subFile+ styIn <- readFile styFile+ putStrLn "\nSubstance program:\n"+ putStrLn subIn+ divLine+ putStrLn "Style program:\n"+ putStrLn styIn+ divLine++ let subParsed = C.subParse subIn+ putStrLn "Parsed Substance program:\n"+ putStrLn $ C.subPrettyPrint' subParsed++ case MP.runParser SA.styleParser styFile styIn of+ Left err -> putStr $ MP.parseErrorPretty err+ Right styParsed -> do+ divLine+ putStrLn "Parsed Style program:\n"+ -- putStrLn $ C.styPrettyPrint styParsed+ mapM_ print styParsed+ divLine+ let initState = R.genInitState (C.subSeparate subParsed) styParsed+ putStrLn "Synthesizing objects and objective functions"+ -- let initState = compilerToRuntimeTypes intermediateRep+ -- divLine+ -- putStrLn "Initial state, optimization representation:\n"+ -- putStrLn "TODO derive Show"+ -- putStrLn $ show initState++ divLine+ putStrLn "Visualizing notation:\n"++ if mode == "snap" then+ -- Starting serving penrose on the web+ let (domain, port) = ("127.0.0.1", 9160) in+ Server.servePenrose domain port initState++ else+ -- Running with hardcoded parameters+ play+ (InWindow "optimization-based layout" -- display mode, window name+ (picWidth, picHeight) -- size+ (10, 10)) -- position+ white -- background color+ R.stepsPerSecond -- number of simulation steps to take for each second of real time+ initState -- the initial world, defined as a type below+ R.picOf -- fn to convert world to a pic+ R.handler -- fn to handle input events+ R.step -- step the world one iteration; passed period of time (in secs) to be advanced++picWidth, picHeight :: Int+picWidth = 800+picHeight = 700++stepsPerSecond :: Int+stepsPerSecond = 10000