diff --git a/.github/gen_readme.js b/.github/gen_readme.js
new file mode 100755
index 0000000000..a3345ee1fe
--- /dev/null
+++ b/.github/gen_readme.js
@@ -0,0 +1,45 @@
+#!/usr/bin/env node
+
+const fs = require("fs");
+const Handlebars = require("handlebars");
+const path = require("path");
+
+const slurp = (p) => fs.readFileSync(p).toString();
+const example = (p) => slurp(path.join("packages/examples/src", p));
+
+const sub = "tree";
+const sty = "venn";
+
+const { trios, domains, styles, substances } = JSON.parse(
+ example("registry.json")
+);
+
+const matching = trios.filter(
+ ({ substance, style }) => substance === sub && style === sty
+);
+if (matching.length !== 1) {
+ throw Error(`expected exactly one matching trio, got ${matching.length}`);
+}
+const [{ substance, style, domain, variation }] = matching;
+
+const dslURI = domains[domain].URI;
+const subURI = substances[substance].URI;
+const styURI = styles[style].URI;
+
+for (const name of ["domain", "substance", "style"]) {
+ Handlebars.registerPartial(name, `{{{${name}}}}`);
+}
+
+fs.writeFileSync(
+ "README.md",
+ Handlebars.compile(slurp(".github/readme_template.hbs"))({
+ svg: `diagrams/${sub}-${sty}.svg`,
+ variation,
+ dsl: path.basename(dslURI),
+ sub: path.basename(subURI),
+ sty: path.basename(styURI),
+ domain: example(dslURI),
+ substance: example(subURI),
+ style: example(styURI),
+ })
+);
diff --git a/.github/readme_template.hbs b/.github/readme_template.hbs
new file mode 100644
index 0000000000..653dba84ab
--- /dev/null
+++ b/.github/readme_template.hbs
@@ -0,0 +1,45 @@
+# Penrose [![Build](https://github.com/penrose/penrose/actions/workflows/build.yml/badge.svg)](https://github.com/penrose/penrose/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/penrose/penrose/branch/main/graph/badge.svg?token=opGTmY4rkK)](https://codecov.io/gh/penrose/penrose) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![license](https://img.shields.io/github/license/penrose/penrose)](LICENSE) [![Twitter: @UsePenrose](https://img.shields.io/twitter/follow/UsePenrose?style=social)](https://twitter.com/UsePenrose)
+
+[Penrose](https://penrose.cs.cmu.edu/) is a platform that enables people to
+**create beautiful diagrams just by typing mathematical notation in plain
+text.** The goal is to make it easy for non-experts to create and explore
+high-quality diagrams and provide deeper insight into challenging technical
+concepts. We aim to democratize the process of creating visual intuition.
+
+Check out our [SIGGRAPH '20 paper](https://penrose.cs.cmu.edu/siggraph20) and
+[video](https://vimeo.com/416822487) on Penrose!
+
+## Usage
+
+You can [try Penrose in your browser](https://penrose.cs.cmu.edu/try/) without
+any installation. For a more detailed step-by-step introduction, check out our
+[tutorials](https://penrose.cs.cmu.edu/docs/tutorial/welcome). Or, for more
+reference-style information, take a look at our
+[documentation](https://penrose.cs.cmu.edu/docs/ref/).
+
+## Example
+
+Here's a simple Penrose visualization in the domain of set theory.
+
+
+
+It's specified by the following trio of Domain, Substance, and Style programs
+(with variation `{{variation}}`):
+
+- `{{dsl}}`:
+
+ ```
+ {{> domain }}
+ ```
+
+- `{{sub}}`:
+
+ ```
+ {{> substance }}
+ ```
+
+- `{{sty}}`:
+
+ ```
+ {{> style }}
+ ```
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 42084ceb83..eb76a1fb63 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -26,7 +26,7 @@ jobs:
with:
name: diagrams
path: packages/automator/out/
- - name: Copy generated diagrams into diagrams/
+ - name: Check that the generated diagrams/ are all up to date
run: |
rm -r diagrams/
mkdir diagrams/
@@ -35,9 +35,7 @@ jobs:
name=${dir%/output.svg}
cp "$filename" "diagrams/$name.svg"
done
- - name: Ensure no generated diagrams have changed
- run: |
- "$GITHUB_WORKSPACE/.github/report_git_status.sh"
+ .github/report_git_status.sh
build:
runs-on: ubuntu-latest
@@ -92,6 +90,18 @@ jobs:
- name: Lint
run: yarn lint
+ readme:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Install packages
+ uses: ./.github/actions/packages
+ - name: Check that the generated README is up to date
+ run: |
+ .github/gen_readme.js
+ .github/report_git_status.sh
+
storybook:
runs-on: ubuntu-latest
defaults:
diff --git a/.prettierignore b/.prettierignore
index 74ef7b1ce7..a5b842f723 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,3 +1,4 @@
+**/*.hbs
**/build/
**/coverage/
**/dist/
@@ -14,3 +15,4 @@ packages/core/src/parser/SubstanceParser.ts
packages/core/src/renderer/not_found.json
packages/docs-site/.docusaurus/
packages/roger/oclif.manifest.json
+README.md
diff --git a/README.md b/README.md
index d0385ff0d8..9b8cfc3fef 100644
--- a/README.md
+++ b/README.md
@@ -1,71 +1,100 @@
# Penrose [![Build](https://github.com/penrose/penrose/actions/workflows/build.yml/badge.svg)](https://github.com/penrose/penrose/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/penrose/penrose/branch/main/graph/badge.svg?token=opGTmY4rkK)](https://codecov.io/gh/penrose/penrose) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) [![license](https://img.shields.io/github/license/penrose/penrose)](LICENSE) [![Twitter: @UsePenrose](https://img.shields.io/twitter/follow/UsePenrose?style=social)](https://twitter.com/UsePenrose)
-**Penrose is an early-stage system that is still in development.** Our system is not ready for contributions or public use yet, but hopefully will be soon. Send us an email if you're interested in collaborating.
+[Penrose](https://penrose.cs.cmu.edu/) is a platform that enables people to
+**create beautiful diagrams just by typing mathematical notation in plain
+text.** The goal is to make it easy for non-experts to create and explore
+high-quality diagrams and provide deeper insight into challenging technical
+concepts. We aim to democratize the process of creating visual intuition.
-- See [the site](http://www.penrose.ink/) for more information and examples.
-- See the [wiki](https://github.com/penrose/penrose/wiki) for more system-specific information on building, running, testing, and debugging the system.
-- For even more documentation, see Nimo Ni's [README](https://github.com/wodeni/notes-public/blob/master/penrose/archive/ramp-down.md).
+Check out our [SIGGRAPH '20 paper](https://penrose.cs.cmu.edu/siggraph20) and
+[video](https://vimeo.com/416822487) on Penrose!
-### Example
+## Usage
+
+You can [try Penrose in your browser](https://penrose.cs.cmu.edu/try/) without
+any installation. For a more detailed step-by-step introduction, check out our
+[tutorials](https://penrose.cs.cmu.edu/docs/tutorial/welcome). Or, for more
+reference-style information, take a look at our
+[documentation](https://penrose.cs.cmu.edu/docs/ref/).
+
+## Example
Here's a simple Penrose visualization in the domain of set theory.
-
+
-It's specified by the following Substance and Style programs.
+It's specified by the following trio of Domain, Substance, and Style programs
+(with variation `CasalViper643`):
+
+- `setTheory.dsl`:
-- `tree.sub`
```
- Set A
- Set B
- Set C
- Set D
- Set E
- Set F
- Set G
- Subset B A
- Subset C A
- Subset D B
- Subset E B
- Subset F C
- Subset G C
- NoIntersect E D
- NoIntersect F G
- NoIntersect B C
+ type Set
+
+ predicate Not(Prop p1)
+ predicate Intersecting(Set s1, Set s2)
+ predicate IsSubset(Set s1, Set s2)
```
-- `venn.sty`
+
+- `tree.sub`:
```
- Set x {
- shape = Circle { }
- constraint contains(x, x.label)
- }
+ Set A, B, C, D, E, F, G
+
+ IsSubset(B, A)
+ IsSubset(C, A)
+ IsSubset(D, B)
+ IsSubset(E, B)
+ IsSubset(F, C)
+ IsSubset(G, C)
+
+ Not(Intersecting(E, D))
+ Not(Intersecting(F, G))
+ Not(Intersecting(B, C))
+
+ AutoLabel All
+ ```
- Intersect x y {
- constraint overlapping(x, y)
- constraint disjoint(y.label, x)
- constraint disjoint(x.label, y)
- }
+- `venn.sty`:
- NoIntersect x y {
- constraint nonOverlapping(x, y)
+ ```
+ canvas {
+ width = 800
+ height = 700
}
-
- Subset x y {
- constraint contains(y, x)
- constraint smallerThan(x, y)
- constraint disjoint(y.label, x)
+
+ forall Set x {
+ x.icon = Circle {
+ strokeWidth : 0
+ }
+
+ x.text = Equation {
+ string : x.label
+ fontSize : "25px"
+ }
+
+ ensure contains(x.icon, x.text)
+ encourage sameCenter(x.text, x.icon)
+ x.textLayering = x.text above x.icon
}
-
- NoSubset x y {
- objective repel(x, y)
- constraint disjoint(x, y)
- constraint disjoint(y.label, x)
- constraint disjoint(x.label, y)
- constraint nonOverlapping(x, y)
+
+ forall Set x; Set y
+ where IsSubset(x, y) {
+ ensure smallerThan(x.icon, y.icon)
+ ensure disjoint(y.text, x.icon, 10)
+ ensure contains(y.icon, x.icon, 5)
+ x.icon above y.icon
+ }
+
+ forall Set x; Set y
+ where Not(Intersecting(x, y)) {
+ ensure disjoint(x.icon, y.icon)
+ }
+
+ forall Set x; Set y
+ where Intersecting(x, y) {
+ ensure overlapping(x.icon, y.icon)
+ ensure disjoint(y.text, x.icon)
+ ensure disjoint(x.text, y.icon)
}
```
-
-Here's how the optimization looks live in the UI.
-
-
diff --git a/diagrams/tree-venn.svg b/diagrams/tree-venn.svg
index 9623e6c745..1f73eb96f4 100644
--- a/diagrams/tree-venn.svg
+++ b/diagrams/tree-venn.svg
@@ -1,39 +1,39 @@
F.icon
@@ -122,29 +122,29 @@
B.icon
E.icon
@@ -183,18 +183,18 @@
D.icon
@@ -233,7 +233,7 @@
@@ -272,7 +272,7 @@
@@ -311,7 +311,7 @@
diff --git a/package.json b/package.json
index 8c661e800b..83e11b1fe2 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
},
"devDependencies": {
"cross-env": "^7.0.3",
+ "handlebars": "^4.7.7",
"lerna": "^3.22.1",
"prettier": "2.2.1",
"prettier-plugin-organize-imports": "^2.3.4",
diff --git a/packages/core/src/compiler/Style.test.ts b/packages/core/src/compiler/Style.test.ts
index 5a6b06f2cb..4a5a304010 100644
--- a/packages/core/src/compiler/Style.test.ts
+++ b/packages/core/src/compiler/Style.test.ts
@@ -374,7 +374,7 @@ describe("Compiler", () => {
describe("Expected Style errors", () => {
const subProg = loadFile("set-theory-domain/twosets-simple.sub");
- const domainProg = loadFile("set-theory-domain/setTheory.dsl");
+ const domainProg = loadFile("set-theory-domain/functions.dsl");
// We test variations on this Style program
// const styPath = "set-theory-domain/venn.sty";
diff --git a/packages/core/src/compiler/Substance.test.ts b/packages/core/src/compiler/Substance.test.ts
index 06598d1b7a..c93d76d994 100644
--- a/packages/core/src/compiler/Substance.test.ts
+++ b/packages/core/src/compiler/Substance.test.ts
@@ -18,7 +18,7 @@ const outputDir = "/tmp/contexts";
const subPaths = [
// "linear-algebra-domain/twoVectorsPerp.sub",
["set-theory-domain/setTheory.dsl", "set-theory-domain/tree.sub"],
- ["set-theory-domain/setTheory.dsl", "set-theory-domain/continuousmap.sub"],
+ ["set-theory-domain/functions.dsl", "set-theory-domain/continuousmap.sub"],
["set-theory-domain/setTheory.dsl", "set-theory-domain/twosets-simple.sub"],
["set-theory-domain/setTheory.dsl", "set-theory-domain/multisets.sub"],
["set-theory-domain/setTheory.dsl", "set-theory-domain/nested.sub"],
diff --git a/packages/core/src/utils/Graph.test.ts b/packages/core/src/utils/Graph.test.ts
deleted file mode 100644
index 1502723cdd..0000000000
--- a/packages/core/src/utils/Graph.test.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import {
- CompressedAdjacencyGraph,
- createAdjacencyMatrix,
- createCompressedMatrix,
- NodeWithEdges,
- Vertex,
-} from "./Graph";
-class IntNode implements NodeWithEdges {
- value: number;
- children: NodeWithEdges[] = [];
- constructor(value: number) {
- this.value = value;
- }
-}
-
-describe("Adjacency matrix creation tests", () => {
- test("cycle between two nodes", () => {
- const one = new IntNode(1);
- const two = new IntNode(2);
- one.children.push(two);
- two.children.push(one);
- expect(createAdjacencyMatrix([one, two])).toEqual([
- [false, true],
- [true, false],
- ]);
- });
- test("no edges two nodes", () => {
- const one = new IntNode(1);
- const two = new IntNode(2);
- expect(createAdjacencyMatrix([one, two])).toEqual([
- [false, false],
- [false, false],
- ]);
- });
- test("six node tree", () => {
- const one = new IntNode(1);
- const two = new IntNode(2);
- const three = new IntNode(3);
- const four = new IntNode(4);
- const five = new IntNode(5);
- const six = new IntNode(6);
- one.children.push(two);
- two.children.push(three);
- three.children.push(four);
- three.children.push(five);
- three.children.push(six);
- expect(createAdjacencyMatrix([one, two, three, four, five, six])).toEqual([
- [false, true, false, false, false, false],
- [false, false, true, false, false, false],
- [false, false, false, true, true, true],
- [false, false, false, false, false, false],
- [false, false, false, false, false, false],
- [false, false, false, false, false, false],
- ]);
- });
-});
-
-describe("Compressed Adjacency Matrix tests", () => {
- test("cycle between two nodes", () => {
- const adjacencyMatrix = [
- [false, true],
- [true, false],
- ];
- const cm = createCompressedMatrix(adjacencyMatrix);
- expect(cm.rowIndices).toEqual([1, 0]);
- expect(cm.cumulativeEntriesByColumn).toEqual([1, 2]);
- expect(cm.columnIndices).toEqual([1, 0]);
- expect(cm.cumulativeEntriesByRow).toEqual([1, 2]);
- });
- test("keenan slide http://15462.courses.cs.cmu.edu/fall2021/lecture/meshes/slide_021", () => {
- const adjacencyMatrix = [
- [true, true, false],
- [false, false, true],
- [false, true, false],
- ];
- const cm = createCompressedMatrix(adjacencyMatrix);
- expect(cm.rowIndices).toEqual([0, 0, 2, 1]);
- expect(cm.cumulativeEntriesByColumn).toEqual([1, 3, 4]);
- expect(cm.columnIndices).toEqual([0, 1, 2, 1]);
- expect(cm.cumulativeEntriesByRow).toEqual([2, 3, 4]);
- });
-});
-
-describe("Graph adjacency matrix tests", () => {
- test("keenan slide http://15462.courses.cs.cmu.edu/fall2021/lecture/meshes/slide_021", () => {
- const adjacencyMatrix = [
- [true, true, false],
- [false, false, true],
- [false, true, false],
- ];
- const cm = createCompressedMatrix(adjacencyMatrix);
- const nodeList: Vertex[] = [
- { index: 0, value: 1 },
- { index: 1, value: 2 },
- { index: 2, value: 3 },
- ];
- const g = new CompressedAdjacencyGraph(nodeList, cm);
- expect(g.childrenOf(0)).toEqual([0]);
- expect(g.childrenOf(1)).toEqual([0, 2]);
- expect(g.childrenOf(2)).toEqual([1]);
- expect(g.parentsOf(0)).toEqual([0, 1]);
- });
- test("one node, no edges test", () => {
- const adjacencyMatrix = [[false]];
- const cm = createCompressedMatrix(adjacencyMatrix);
- const nodeList: Vertex[] = [{ index: 0, value: 1 }];
- const g = new CompressedAdjacencyGraph(nodeList, cm);
- expect(g.childrenOf(0)).toEqual([]);
- });
- test("one node, self-edge test", () => {
- const adjacencyMatrix = [[true]];
- const cm = createCompressedMatrix(adjacencyMatrix);
- const nodeList: Vertex[] = [{ index: 0, value: 1 }];
- const g = new CompressedAdjacencyGraph(nodeList, cm);
- expect(g.childrenOf(0)).toEqual([0]);
- expect(g.childrenOf(0)).toEqual([0]);
- });
-});
diff --git a/packages/core/src/utils/Graph.ts b/packages/core/src/utils/Graph.ts
index 7174a15fc0..ed6432c1e7 100644
--- a/packages/core/src/utils/Graph.ts
+++ b/packages/core/src/utils/Graph.ts
@@ -1,121 +1,5 @@
import * as graphlib from "graphlib";
-//#region compressed matrix
-
-export interface NodeWithEdges {
- value: T;
- children: NodeWithEdges[];
-}
-
-export interface Vertex {
- index: number;
- value: T;
-}
-
-export const createAdjacencyMatrix = (
- nodeList: NodeWithEdges[]
-): boolean[][] => {
- const matrix = createSquareMatrix(nodeList.length, false);
- let i = 0;
- nodeList.forEach((node) => {
- node.children.forEach((childNode) => {
- const j = nodeList.lastIndexOf(childNode);
- matrix[i][j] = true;
- });
- i++;
- });
- return matrix;
-};
-
-export interface CompressedMatrix {
- rowIndices: Array;
- cumulativeEntriesByColumn: Array;
- columnIndices: Array;
- cumulativeEntriesByRow: Array;
-}
-
-// immutable Graph
-export interface Graph {
- nodeList: Vertex[];
- parentsOf: (nodeIndex: number) => number[];
- childrenOf: (nodeIndex: number) => number[];
-}
-
-export class CompressedAdjacencyGraph implements Graph {
- nodeList: Vertex[];
- cm: CompressedMatrix;
-
- constructor(nodeList: Vertex[], cm: CompressedMatrix) {
- this.nodeList = nodeList;
- this.cm = cm;
- }
- parentsOf = (nodeIndex: number): number[] => {
- let startIndex = 0;
- if (nodeIndex > 0) {
- startIndex = this.cm.cumulativeEntriesByRow[nodeIndex - 1];
- }
- const endIndex = this.cm.cumulativeEntriesByRow[nodeIndex];
- return this.cm.columnIndices.slice(startIndex, endIndex);
- };
- childrenOf = (nodeIndex: number): number[] => {
- let startIndex = 0;
- if (nodeIndex > 0) {
- startIndex = this.cm.cumulativeEntriesByColumn[nodeIndex - 1];
- }
- const endIndex = this.cm.cumulativeEntriesByColumn[nodeIndex];
- return this.cm.rowIndices.slice(startIndex, endIndex);
- };
-}
-
-export const createCompressedMatrix = (
- adjacencyMatrix: boolean[][]
-): CompressedMatrix => {
- const cm = {
- rowIndices: new Array(),
- cumulativeEntriesByColumn: new Array(),
- columnIndices: new Array(),
- cumulativeEntriesByRow: new Array(),
- };
- let cumulativeEntries = 0;
- const size = adjacencyMatrix.length;
- for (let i = 0; i < size; i++) {
- for (let j = 0; j < size; j++) {
- if (adjacencyMatrix[j][i]) {
- cm.rowIndices.push(j);
- cumulativeEntries++;
- }
- }
- cm.cumulativeEntriesByColumn.push(cumulativeEntries);
- }
- cumulativeEntries = 0;
- for (let i = 0; i < size; i++) {
- for (let j = 0; j < size; j++) {
- if (adjacencyMatrix[i][j]) {
- cm.columnIndices.push(j);
- cumulativeEntries++;
- }
- }
- cm.cumulativeEntriesByRow.push(cumulativeEntries);
- }
- return cm;
-};
-
-function createSquareMatrix(width: number, defaultValue = false): boolean[][] {
- const matrix = [];
- for (let i = 0; i < width; i++) {
- const row: boolean[] = [];
- for (let j = 0; j < width; j++) {
- row.push(defaultValue);
- }
- matrix.push(row);
- }
- return matrix;
-}
-
-//#endregion
-
-//#region graphlib wrapper
-
export interface Edge<
NodeId extends string,
EdgeName extends string | undefined
@@ -250,5 +134,3 @@ export class Multidigraph<
return graphlib.alg.topsort(this._graph) as NodeId[];
}
}
-
-//#endregion
diff --git a/packages/examples/src/registry.json b/packages/examples/src/registry.json
index 8f32ef7db9..734ce1dfe8 100644
--- a/packages/examples/src/registry.json
+++ b/packages/examples/src/registry.json
@@ -5,7 +5,7 @@
"substance": "tree",
"style": "venn",
"domain": "set-theory",
- "variation": ""
+ "variation": "CasalViper643"
},
{
"substance": "tree",
@@ -16,7 +16,7 @@
{
"substance": "continuousmap",
"style": "continuousmap",
- "domain": "set-theory",
+ "domain": "functions",
"variation": ""
},
{
@@ -103,6 +103,10 @@
"name": "Set Theory",
"URI": "set-theory-domain/setTheory.dsl"
},
+ "functions": {
+ "name": "Functions",
+ "URI": "set-theory-domain/functions.dsl"
+ },
"linear-algebra": {
"name": "Linear Algebra",
"URI": "linear-algebra-domain/linear-algebra.dsl"
diff --git a/packages/examples/src/set-theory-domain/functions.dsl b/packages/examples/src/set-theory-domain/functions.dsl
new file mode 100644
index 0000000000..c40ebb7e9f
--- /dev/null
+++ b/packages/examples/src/set-theory-domain/functions.dsl
@@ -0,0 +1,32 @@
+type Set
+type Point
+type Map
+
+constructor Singleton(Point p) -> Set
+
+function Intersection(Set a, Set b) -> Set
+function Union(Set a, Set b) -> Set
+function Subtraction(Set a, Set b) -> Set
+function CartesianProduct(Set a, Set b) -> Set
+function Difference(Set a, Set b) -> Set
+function Subset(Set a, Set b) -> Set
+function AddPoint(Point p, Set s1) -> Set
+
+predicate Not(Prop p1)
+predicate From(Map f, Set domain, Set codomain)
+predicate Empty(Set s)
+predicate Intersecting(Set s1, Set s2)
+predicate IsSubset(Set s1, Set s2)
+predicate Equal(Set s1, Set s2)
+predicate PointIn(Set s, Point p)
+predicate In(Point p, Set s)
+predicate Injection(Map m)
+predicate Surjection(Map m)
+predicate Bijection(Map m)
+predicate PairIn(Point, Point, Map)
+
+notation "A ⊂ B" ~ "IsSubset(A, B)"
+notation "p ∈ A" ~ "PointIn(A, p)"
+notation "p ∉ A" ~ "PointNotIn(A, p)"
+notation "A ∩ B = ∅" ~ "Not(Intersecting(A, B))"
+notation "f: A -> B" ~ "Map f; From(f, A, B)"
diff --git a/packages/examples/src/set-theory-domain/setTheory.dsl b/packages/examples/src/set-theory-domain/setTheory.dsl
index c40ebb7e9f..309f5ca535 100644
--- a/packages/examples/src/set-theory-domain/setTheory.dsl
+++ b/packages/examples/src/set-theory-domain/setTheory.dsl
@@ -1,32 +1,5 @@
type Set
-type Point
-type Map
-
-constructor Singleton(Point p) -> Set
-
-function Intersection(Set a, Set b) -> Set
-function Union(Set a, Set b) -> Set
-function Subtraction(Set a, Set b) -> Set
-function CartesianProduct(Set a, Set b) -> Set
-function Difference(Set a, Set b) -> Set
-function Subset(Set a, Set b) -> Set
-function AddPoint(Point p, Set s1) -> Set
predicate Not(Prop p1)
-predicate From(Map f, Set domain, Set codomain)
-predicate Empty(Set s)
predicate Intersecting(Set s1, Set s2)
predicate IsSubset(Set s1, Set s2)
-predicate Equal(Set s1, Set s2)
-predicate PointIn(Set s, Point p)
-predicate In(Point p, Set s)
-predicate Injection(Map m)
-predicate Surjection(Map m)
-predicate Bijection(Map m)
-predicate PairIn(Point, Point, Map)
-
-notation "A ⊂ B" ~ "IsSubset(A, B)"
-notation "p ∈ A" ~ "PointIn(A, p)"
-notation "p ∉ A" ~ "PointNotIn(A, p)"
-notation "A ∩ B = ∅" ~ "Not(Intersecting(A, B))"
-notation "f: A -> B" ~ "Map f; From(f, A, B)"
diff --git a/packages/examples/src/set-theory-domain/venn.sty b/packages/examples/src/set-theory-domain/venn.sty
index 85fba75380..81368e321b 100644
--- a/packages/examples/src/set-theory-domain/venn.sty
+++ b/packages/examples/src/set-theory-domain/venn.sty
@@ -4,74 +4,36 @@ canvas {
}
forall Set x {
- x.icon = Circle {
- strokeWidth : 0.0
- }
+ x.icon = Circle {
+ strokeWidth : 0
+ }
- x.text = Equation {
- string : x.label
- fontSize: "25px"
- }
+ x.text = Equation {
+ string : x.label
+ fontSize : "25px"
+ }
- ensure contains(x.icon, x.text)
- encourage sameCenter(x.text, x.icon)
- x.textLayering = x.text above x.icon
+ ensure contains(x.icon, x.text)
+ encourage sameCenter(x.text, x.icon)
+ x.textLayering = x.text above x.icon
}
forall Set x; Set y
where IsSubset(x, y) {
-
- ensure smallerThan(x.icon, y.icon)
- ensure disjoint(y.text, x.icon, 10.0)
- ensure contains(y.icon, x.icon, 5.0)
- x.icon above y.icon
+ ensure smallerThan(x.icon, y.icon)
+ ensure disjoint(y.text, x.icon, 10)
+ ensure contains(y.icon, x.icon, 5)
+ x.icon above y.icon
}
--- TODO: Fix that the resample hack breaks on switching examples since it saves the cached functions...
--- TOOD: Also breaks if you resample without generating the function on first sample. Clearly this should be part of the state
-
----
-
forall Set x; Set y
where Not(Intersecting(x, y)) {
- ensure disjoint(x.icon, y.icon)
+ ensure disjoint(x.icon, y.icon)
}
--- --------- NEW
-
-
forall Set x; Set y
where Intersecting(x, y) {
- ensure overlapping(x.icon, y.icon)
- ensure disjoint(y.text, x.icon)
- ensure disjoint(x.text, y.icon)
-}
-
-forall Point p {
- p.offset = 20.0
- p.icon = Circle {
- strokeWidth : 0.0
- fillColor : rgba(0.0, 0.0, 0.0, 1.0)
- r : 3.0
- }
-
- p.text = Equation {
- string : p.label
- center : p.icon.center + (p.offset, p.offset)
- }
-
- p.textLayering = p.text above p.icon
-}
-
-Point p
-with Set A
-where PointIn(A, p) {
- ensure contains(A.icon, p.icon, 0.3 * A.icon.r)
- p.layering = p.icon above A.icon
-}
-
-Point p
-with Set A
-where Not(PointIn(A, p)) {
- ensure disjoint(A.icon, p.icon)
+ ensure overlapping(x.icon, y.icon)
+ ensure disjoint(y.text, x.icon)
+ ensure disjoint(x.text, y.icon)
}