diff --git a/README.md b/README.md index dc1251a..1f5edb6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,54 @@ # Pandamonium Theorem Prover -This is the main repository for the Technical Software Project +This project contains several different modules for different parts of the system. + +* [persistence](persistence/README.md) +* [web-server](src/README.md) + +## Getting Started + +1. Clone the project. `git clone git@github.com:atusa17/tsp.git` +2. Open the `pandamonium-theorem-prover` folder with IntelliJ. Use auto-import for a Gradle project. +3. Individual Components have their own README. Continue there. + +## Running the Tests + +This project is unit tested with JUnit and Mockito. You can run the unit tests with IntelliJ or Gradle. To run them with IntelliJ, browse to any `*Test.java` file and use IntelliJ's built-in test runner to run or debug the test. To run all the unit tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew test``` + +* On a Windows machine: + + ```$ gradlew.bat test``` + +You can also test modules individually: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew persistence:test``` + +* On a Windows machine: + + ```$ gradlew.bat persistence:test``` + +## Integration Tests + +To run the integration tests with IntelliJ, browse to any `*Test.java` file residing in any module name `integrationTest` and use IntelliJ's built-in test runner to run or debug the test. To run all the integration tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew integrationTest``` + +* On a Windows machine + + ```$ gradlew.bat integrationTest``` + +## Built with + +* [Spring Boot](https://projects.spring.io/spring-boot/) - Web framework +* [Spring Web Flow](https://projects.spring.io/spring-webflow/) - MVC framework +* [Gradle](https://gradle.org/) - Dependency management +* [JUnit](http://junit.org/junit4/) - Unit tests +* [Mockito](http://site.mockito.org/) - Mock objects library +* [Lombok](https://projectlombok.org/) - Boilerplate Code Generator diff --git a/persistence/README.md b/persistence/README.md new file mode 100644 index 0000000..4258ce9 --- /dev/null +++ b/persistence/README.md @@ -0,0 +1,61 @@ +## PTP Persistence API + +The PTP Persistence API is the web API for accessing the theorems database. + + + +## Running from IntelliJ + +* Create a new run configuration in IntelliJ. + + ``` + Name: "PTP Persistence API Tomcat" + Application Server: Tomcat (8.5.12) + HTTP Port: 8090 + JMX Port: 1090 + Deployment tabe: Deploy persistence-api.war (exploded) + ``` +## Running the Tests + +This project is unit tested with JUnit and Mockito. You can run the unit tests with IntelliJ or Gradle. To run them with IntelliJ, browse to any `*Test.java` file and use IntelliJ's built-in test runner to run or debug the test. To run all the unit tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew test``` + +* On a Windows machine: + + ```$ gradlew.bat test``` + +You can also test modules individually: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew persistence:test``` + +* On a Windows machine: + + ```$ gradlew.bat persistence:test``` + +## Integration Tests + +To run the integration tests with IntelliJ, browse to any `*Test.java` file residing in any module name `integrationTest` and use IntelliJ's built-in test runner to run or debug the test. To run all the integration tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew integrationTest``` + +* On a Windows machine + + ```$ gradlew.bat integrationTest``` + +## Built with + +* [Spring Boot](https://projects.spring.io/spring-boot/) - Web framework +* [Spring Web Flow](https://projects.spring.io/spring-webflow/) - MVC framework +* [Spring Data](https://spring.io/projects/spring-data/) - Persistence framework +* [Gradle](https://gradle.org/) - Dependency management +* [JUnit](http://junit.org/junit4/) - Unit tests +* [Mockito](http://site.mockito.org/) - Mock objects library +* [Lombok](https://projectlombok.org/) - Boilerplate Code Generator +* [Hibernate ORM](http://hibernate.org/orm/) - Object/Relational Mapping diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java b/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java new file mode 100644 index 0000000..2b92dec --- /dev/null +++ b/services/src/main/java/edu/msudenver/tsp/services/parser/Node.java @@ -0,0 +1,43 @@ +package edu.msudenver.tsp.services.parser; + +import lombok.Getter; +import lombok.Setter; + +public class Node +{ + @Getter private final String statement; + @Getter @Setter private Node left; + @Getter @Setter private Node right; + @Getter @Setter private Node center; + @Getter private final Node parent; + @Getter private final int depth; + + public Node(final String statement, final Node parent) + { + this.statement = statement + "\n"; + left = null; + right = null; + center = null; + this.parent = parent; + if(parent != null) + { + depth = parent.depth + 1; + } + else + { + depth = 0; + } + } + + @Override + public String toString() + { + String returnVal = this.depth + ": " + this.statement; + + if(this.left != null) returnVal += "... " + this.left.toString(); + if(this.center != null) returnVal += "... " + this.center.toString(); + if(this.right != null) returnVal += "... " + this.right.toString(); + + return returnVal; + } +} \ No newline at end of file diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java deleted file mode 100644 index eb1c4f2..0000000 --- a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package edu.msudenver.tsp.services.parser; - -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ComponentScan -//@PropertySource("classpath:development.properties") -public class ParserConfig { - -} diff --git a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java index 747521d..0106b8b 100644 --- a/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java +++ b/services/src/main/java/edu/msudenver/tsp/services/parser/ParserService.java @@ -7,12 +7,16 @@ import edu.msudenver.tsp.persistence.controller.TheoremController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + @Service class ParserService { private final DefinitionController definitionController; private final TheoremController theoremController; private final NotationController notationController; private final ProofController proofController; + private Node root; @Autowired public ParserService(final DefinitionController definitionController, final TheoremController theoremController, @@ -23,4 +27,117 @@ class ParserService { this.proofController = proofController; } + public boolean parseUserInput(final String userInput) + { + try { + final Node tree = parseRawInput(userInput); + final List statements = retrieveStatements(tree); + + return true; + } catch(final Exception e) { + e.printStackTrace(); + } + return false; + } + + public Node parseRawInput(String input) + { + input = input.toLowerCase(); + + root = new Node(input, null); + + if(input.equals("")) + { + return root; + } + + recurse(root); + + return root; + } + + private void recurse(final Node current) + { + int startIndex; + int endIndex; + final String statement; + + if (current != null) { + statement = current.getStatement(); + } else { + return; + } + + String nextStatement; + + if(statement.contains("let")) + { + current.setLeft(new Node("let", current)); + + startIndex = statement.indexOf("let")+"let".length(); + + if(statement.contains("if")){ + endIndex = statement.indexOf("if"); + } else if(statement.contains("then")){ + endIndex = statement.indexOf("then"); + } else { + endIndex = statement.length(); + } + + nextStatement = statement.substring(startIndex, endIndex); + + current.getLeft().setCenter(new Node(nextStatement, current.getLeft())); + recurse(current.getLeft().getCenter()); + } + + + if(statement.contains("if")) + { + current.setCenter(new Node("if", current)); + + startIndex = statement.indexOf("if")+"if".length(); + endIndex = (statement.contains("then") ? statement.indexOf("then") : statement.length()); + nextStatement = statement.substring(startIndex, endIndex); + + current.getCenter().setCenter(new Node(nextStatement, current.getCenter())); + recurse(current.getCenter().getCenter()); + } + + + if(current.getStatement().contains("then")) + { + current.setRight(new Node("then", current)); + + startIndex = statement.indexOf("then")+"then".length(); + nextStatement = statement.substring(startIndex); + + current.getRight().setCenter(new Node(nextStatement, current.getRight())); + recurse(current.getRight().getCenter()); + } + } + + public List retrieveStatements(final Node parsedTree) + { + return populateStatementList(parsedTree, new ArrayList<>()); + } + + private ArrayList populateStatementList(final Node node, final ArrayList statementList) + { + if(node == null) + { + return statementList; + } + + final String statement = node.getStatement().trim(); + if(!(statement.contains("let") || statement.contains("if") || statement.contains("then"))) + { + statementList.add(statement); + } + + populateStatementList(node.getLeft(), statementList); + populateStatementList(node.getCenter(), statementList); + populateStatementList(node.getRight(), statementList); + + return statementList; + } } diff --git a/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java b/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java index 1ae6e5e..829a02a 100644 --- a/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java +++ b/services/src/test/java/edu/msudenver/tsp/services/parser/ParserServiceTest.java @@ -1,17 +1,143 @@ package edu.msudenver.tsp.services.parser; +import edu.msudenver.tsp.persistence.controller.DefinitionController; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.runners.MockitoJUnitRunner; +import java.util.ArrayList; +import java.util.List; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class ParserServiceTest { + private final DefinitionController definitionControllerMock = mock(DefinitionController.class); + private final ParserService mockParserService = mock(ParserService.class); + + @InjectMocks + private final ParserService parserService = new ParserService(definitionControllerMock, null, + null, null); + @Test - public void test() { - assertEquals(3,3); + public void testEmptyStringEqualsEmptyString() { + final String expected = "0: \n"; + final String actual = parserService.parseRawInput("").toString(); + + assertEquals(expected, actual); } + @Test + public void testUselessStringEqualsUselessString() { + final String expected = "0: cat\n"; + final String actual = parserService.parseRawInput("cat").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testSingleIfReturnsIfPlusEmptyString() { + final String expected = "0: if\n... 1: if\n... 2: \n\n"; + final String actual = parserService.parseRawInput("if").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testBaseCaseIfXIsEvenThenXSquaredIsEven() { + final String expected = "0: if x is even then x^2 is even\n" + + "... 1: if\n" + + "... 2: x is even \n" + + "... 1: then\n" + + "... 2: x^2 is even\n\n"; + + final String actual = parserService.parseRawInput("if x is even then x^2 is even").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetXBeEvenThenXSquaredIsEven() { + final String expected = "0: let x be even. then x^2 is even.\n" + + "... 1: let\n" + + "... 2: x be even. \n" + + "... 1: then\n" + + "... 2: x^2 is even.\n\n"; + + final String actual = parserService.parseRawInput("Let x be even. Then x^2 is even.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetIfThen() { + final String expected = "0: let a. if b, then c.\n" + + "... 1: let\n" + + "... 2: a. \n" + + "... 1: if\n" + + "... 2: b, \n" + + "... 1: then\n" + + "... 2: c.\n\n"; + + final String actual = parserService.parseRawInput("Let a. If b, then c.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testLetStatementWithoutAnyIfOrThenStatements() { + final String expected = "0: let a be equal to b.\n" + + "... 1: let\n" + + "... 2: a be equal to b.\n\n"; + + final String actual = parserService.parseRawInput("Let a be equal to b.").toString(); + + assertEquals(expected, actual); + } + + @Test + public void testEmptyStringReturnsEmptyList() { + final List expectedList = new ArrayList<>(); + expectedList.add(""); + + when(mockParserService.parseRawInput(anyString())).thenReturn(new Node("", null)); + final List actualList = parserService.retrieveStatements(mockParserService.parseRawInput("")); + + assertEquals(expectedList, actualList); + } + + @Test + public void testBaseCaseReturnsXIsEven() { + final List expectedList = new ArrayList<>(); + expectedList.add("x is even"); + expectedList.add("x^2 is even"); + + final Node testNode = new Node("if x is even then x^2 is even", null); + testNode.setCenter(new Node("if", testNode)); + testNode.getCenter().setCenter(new Node(" x is even ", testNode.getCenter())); + testNode.setRight(new Node("then", testNode)); + testNode.getRight().setCenter(new Node(" x^2 is even", testNode.getRight())); + + when(mockParserService.parseRawInput(anyString())).thenReturn(testNode); + final List actualList = parserService.retrieveStatements(mockParserService.parseRawInput("baseCase")); + + assertEquals(expectedList, actualList); + } + + @Test + public void testDriveParseUserInput() { + final Node testNode = new Node("", null); + when(mockParserService.parseRawInput(anyString())).thenReturn(testNode); + when(mockParserService.retrieveStatements(testNode)).thenReturn(new ArrayList<>()); + + final boolean successfulTestDrive = parserService.parseUserInput(""); + + assertTrue(successfulTestDrive); + } } \ No newline at end of file diff --git a/src/README.md b/src/README.md new file mode 100644 index 0000000..6ee4af6 --- /dev/null +++ b/src/README.md @@ -0,0 +1,58 @@ +## PTP Persistence API + +The PTP Persistence API is the web API for accessing the theorems database. + + + +## Running from IntelliJ + +* Create a new run configuration in IntelliJ. + + ``` + Name: "Pandamonium Theorem Prover Tomcat" + Application Server: Tomcat (8.5.12) + HTTP Port: 8080 + JMX Port: 1080 + Deployment tabe: Deploy pandamonium-theorem-prover.war (exploded) + ``` +## Running the Tests + +This project is unit tested with JUnit and Mockito. You can run the unit tests with IntelliJ or Gradle. To run them with IntelliJ, browse to any `*Test.java` file and use IntelliJ's built-in test runner to run or debug the test. To run all the unit tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew test``` + +* On a Windows machine: + + ```$ gradlew.bat test``` + +You can also test modules individually: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew persistence:test``` + +* On a Windows machine: + + ```$ gradlew.bat persistence:test``` + +## Integration Tests + +To run the integration tests with IntelliJ, browse to any `*Test.java` file residing in any module name `integrationTest` and use IntelliJ's built-in test runner to run or debug the test. To run all the integration tests with Gradle: + +* On a Linux or Macintosh machine: + + ```$ ./gradlew integrationTest``` + +* On a Windows machine + + ```$ gradlew.bat integrationTest``` + +## Built with + +* [Spring Boot](https://projects.spring.io/spring-boot/) - Web framework +* [Gradle](https://gradle.org/) - Dependency management +* [JUnit](http://junit.org/junit4/) - Unit tests +* [Mockito](http://site.mockito.org/) - Mock objects library +* [Lombok](https://projectlombok.org/) - Boilerplate Code Generator