diff options
23 files changed, 757 insertions, 0 deletions
@@ -1,2 +1,3 @@ *~ *.profraw +.idea diff --git a/java/.gitignore b/java/.gitignore new file mode 100644 index 0000000..af515ad --- /dev/null +++ b/java/.gitignore @@ -0,0 +1,2 @@ +.idea +target/ diff --git a/java/Abs.java b/java/Abs.java new file mode 100644 index 0000000..9d1c146 --- /dev/null +++ b/java/Abs.java @@ -0,0 +1,26 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +import static org.lambdanantes.lcgoji.ast.Var.var; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class Abs implements Term { + + public static final Abs IDENTITY = λ("x", var("x")); + + public String arg; + public Term body; + + public static Abs λ(String arg, Term body) { + return new Abs(arg, body); + } + + @Override + public String toString() { + return "λ" + arg + "." + body; + } +}
\ No newline at end of file diff --git a/java/App.java b/java/App.java new file mode 100644 index 0000000..2f3e04d --- /dev/null +++ b/java/App.java @@ -0,0 +1,22 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class App implements Term { + + public Term left; + public Term right; + + public static App apply(Term left, Term right) { + return new App(left, right); + } + + @Override + public String toString() { + return "(" + left + ") " + right; + } +}
\ No newline at end of file diff --git a/java/LCEvaluator.java b/java/LCEvaluator.java new file mode 100644 index 0000000..b0fe69b --- /dev/null +++ b/java/LCEvaluator.java @@ -0,0 +1,59 @@ +package org.lambdanantes.lcgoji; + +import org.lambdanantes.lcgoji.ast.Abs; +import org.lambdanantes.lcgoji.ast.App; +import org.lambdanantes.lcgoji.ast.Term; +import org.lambdanantes.lcgoji.ast.Var; + +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; + +public class LCEvaluator { + + public static Term evaluate(Term term) { + switch (term) { + case Var var -> { + return var; + } + case Abs abs -> { + return abs; + } + case App app -> { + switch (app.left) { + case Abs abs -> { + return substitute(abs.body, abs.arg, app.right); + } + case App _app -> { + return app; + } + case Var _var -> { + return app; + } + } + } + } + } + + private static Term substitute(Term body, String arg, Term val) { + switch (body) { + case Var var -> { + if (var.name.equals(arg)) { + return val; + } else { + return body; + } + } + case App app -> { + return apply(substitute(app.left, arg, val), substitute(app.right, arg, val)); + } + case Abs abs -> { + if (abs.arg.equals(arg)) { + // Pas de substitution des variables redéfinies + return abs; + } else { + return λ(abs.arg, substitute(abs.body, arg, val)); + } + } + } + } +}
\ No newline at end of file diff --git a/java/LCEvaluatorTest.java b/java/LCEvaluatorTest.java new file mode 100644 index 0000000..ec2f027 --- /dev/null +++ b/java/LCEvaluatorTest.java @@ -0,0 +1,74 @@ +package org.lambdanantes.lcgoji; + +import org.junit.Test; +import org.lambdanantes.lcgoji.ast.Term; +import org.lambdanantes.lcgoji.ast.Var; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.lambdanantes.lcgoji.LCEvaluator.evaluate; +import static org.lambdanantes.lcgoji.ast.Abs.IDENTITY; +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; +import static org.lambdanantes.lcgoji.ast.Var.var; + +public class LCEvaluatorTest { + + Var x = var("x"); + Var y = var("y"); + Var z = var("z"); + + @Test + public void l_evaluation_d_une_variable_rend_la_meme_variable() { + // evaluate(x) == x + assertEvalTo(x, x); + } + + @Test + public void l_evaluation_d_une_abstraction_rend_la_meme_abstraction() { + // evaluate(λx.x) == λx.x + assertEvalTo(IDENTITY, IDENTITY); + } + + @Test + public void l_evaluation_de_l_application_de_deux_vars_rend_la_meme_application() { + // evaluate(x y) == x y + assertEvalTo(apply(x, y), apply(x, y)); + } + + @Test + public void l_evaluation_de_l_application_de_l_identite_sur_un_argument_rend_l_argument() { + // evaluate((λx.x) y) == y + assertEvalTo(apply(IDENTITY, y), y); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_substitue_son_argument() { + // evaluate((λx.x x) y ) == y y + assertEvalTo(apply(λ("x", apply(x, x)), y), apply(y, y)); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_d_abstraction_substitue_recursivement_son_argument() { + // evaluate((λx.λy.x) z) == λy.z + assertEvalTo(apply(λ("x", λ("y", x)), z), λ("y", z)); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_ne_substitue_pas_ses_variables_libres() { + // evaluate((λx.y) z) == y + assertEvalTo(apply(λ("x", y), z), y); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_d_abstraction_ne_substitue_pas_les_variables_redefinies() { + // evaluate((λx.λx.x) z) == λx.x + assertEvalTo(apply(λ("x", λ("x", x)), z), λ("x", x)); + } + + ///// + + private static void assertEvalTo(Term termToEvaluate, Term result) { + assertThat(evaluate(termToEvaluate), is(result)); + } +} diff --git a/java/Main.java b/java/Main.java new file mode 100644 index 0000000..76cb839 --- /dev/null +++ b/java/Main.java @@ -0,0 +1,49 @@ +package org.lambdanantes.lcgoji; + +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.fluent.Request; +import org.apache.http.client.fluent.Response; +import org.apache.http.entity.StringEntity; + +import static spark.Spark.*; + +@Slf4j +public class Main { + + public static final String TEAM_NAME = "LCGOJI"; + public static final int SELF_PORT = 8888; + public static final String SELF_URL = "http://127.0.0.1:" + SELF_PORT; + public static final String TESTER_URL = "http://127.0.0.1:8080"; + + public static void main(String[] args) throws Exception { + port(SELF_PORT); + + before((request, response) -> log.info("Requête entrante : " + request.requestMethod() + " " + request.pathInfo() + ", query params : " + request.queryString())); + + // API pour l'évaluation de λ-term + // Le body est une S-expression sous sa forme textuelle + post("/eval", (request, response) -> { + String body = request.body(); + log.info("Demande d'évaluation de l'expression : " + body); + + // TODO Parser, contruire l'AST, l'évaluer + String result = body; // Renvoie la s-expression à l'identique pour le moment + + log.info("Réponse envoyée : " + body); + + return result.getBytes(); + }); + + init(); + + // Enregistrement de notre API auprès du tester d'API + String jsonBody = "{\"url\":\"" + SELF_URL + "/eval\", \"name\": \"" + TEAM_NAME + "\"}"; + Response response = Request.Post(TESTER_URL + "/register") + .addHeader("Content-type", "application/json") + .body(new StringEntity(jsonBody)) + .execute(); + + log.info("Résultat de l'enregistrement : "+response.returnContent().toString()); + } + +}
\ No newline at end of file diff --git a/java/Term.java b/java/Term.java new file mode 100644 index 0000000..2dcc9fe --- /dev/null +++ b/java/Term.java @@ -0,0 +1,5 @@ +package org.lambdanantes.lcgoji.ast; + +public sealed interface Term permits Var, Abs, App { + +}
\ No newline at end of file diff --git a/java/TermTest.java b/java/TermTest.java new file mode 100644 index 0000000..f11ca77 --- /dev/null +++ b/java/TermTest.java @@ -0,0 +1,38 @@ +package org.lambdanantes.lcgoji.ast; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; +import static org.lambdanantes.lcgoji.ast.Var.var; + +public class TermTest { + + @Test + public void les_equals_des_termes_sont_corrects() { + // x == x + assertThat(var("x"), is(var("x"))); + // x != y + assertThat(var("x"), is(not(var("y")))); + // λx.x == λx.x + assertThat(λ("x", var("x")), is(λ("x", var("x")))); + // λx.x != λy.x + assertThat(λ("x", var("x")), is(not(λ("y", var("x"))))); + // x y == x y + assertThat(apply(var("x"), var("y")), is(apply(var("x"), var("y")))); + // x x != x y + assertThat(apply(var("x"), var("x")), is(not(apply(var("x"), var("y"))))); + } + + @Test + public void les_toString_des_termes_utilisent_la_notation_consacree() { + assertThat(var("x").toString(), is("x")); + assertThat(λ("x", var("x")).toString(), is("λx.x")); + assertThat(apply(λ("x", var("x")), var("x")).toString(), is("(λx.x) x")); + assertThat(apply(λ("x", λ("x", var("x"))), var("y")).toString(), is("(λx.λx.x) y")); + } + +}
\ No newline at end of file diff --git a/java/Var.java b/java/Var.java new file mode 100644 index 0000000..ed710b6 --- /dev/null +++ b/java/Var.java @@ -0,0 +1,21 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class Var implements Term{ + + public String name; + + public static Var var(String name) { + return new Var(name); + } + + @Override + public String toString() { + return name; + } +}
\ No newline at end of file diff --git a/java/lcgoji/.gitignore b/java/lcgoji/.gitignore new file mode 100644 index 0000000..af515ad --- /dev/null +++ b/java/lcgoji/.gitignore @@ -0,0 +1,2 @@ +.idea +target/ diff --git a/java/lcgoji/pom.xml b/java/lcgoji/pom.xml new file mode 100644 index 0000000..f4a4f30 --- /dev/null +++ b/java/lcgoji/pom.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.lambdanantes</groupId> + <artifactId>lcgoji</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <lombok.version>1.18.30</lombok.version> + <log4j.version>2.16.0</log4j.version> + + <jetty-util.version>9.4.31.v20200723</jetty-util.version> + <spark-core.version>2.9.3</spark-core.version> + <httpclient.version>4.3.1</httpclient.version> + + <junit.version>4.10</junit.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <version>${log4j.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>${log4j.version}</version> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>${jetty-util.version}</version> + </dependency> + <dependency> + <groupId>com.sparkjava</groupId> + <artifactId>spark-core</artifactId> + <version>${spark-core.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>fluent-hc</artifactId> + <version>${httpclient.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/LCEvaluator.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/LCEvaluator.java new file mode 100644 index 0000000..b0fe69b --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/LCEvaluator.java @@ -0,0 +1,59 @@ +package org.lambdanantes.lcgoji; + +import org.lambdanantes.lcgoji.ast.Abs; +import org.lambdanantes.lcgoji.ast.App; +import org.lambdanantes.lcgoji.ast.Term; +import org.lambdanantes.lcgoji.ast.Var; + +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; + +public class LCEvaluator { + + public static Term evaluate(Term term) { + switch (term) { + case Var var -> { + return var; + } + case Abs abs -> { + return abs; + } + case App app -> { + switch (app.left) { + case Abs abs -> { + return substitute(abs.body, abs.arg, app.right); + } + case App _app -> { + return app; + } + case Var _var -> { + return app; + } + } + } + } + } + + private static Term substitute(Term body, String arg, Term val) { + switch (body) { + case Var var -> { + if (var.name.equals(arg)) { + return val; + } else { + return body; + } + } + case App app -> { + return apply(substitute(app.left, arg, val), substitute(app.right, arg, val)); + } + case Abs abs -> { + if (abs.arg.equals(arg)) { + // Pas de substitution des variables redéfinies + return abs; + } else { + return λ(abs.arg, substitute(abs.body, arg, val)); + } + } + } + } +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/Main.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/Main.java new file mode 100644 index 0000000..76cb839 --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/Main.java @@ -0,0 +1,49 @@ +package org.lambdanantes.lcgoji; + +import lombok.extern.slf4j.Slf4j; +import org.apache.http.client.fluent.Request; +import org.apache.http.client.fluent.Response; +import org.apache.http.entity.StringEntity; + +import static spark.Spark.*; + +@Slf4j +public class Main { + + public static final String TEAM_NAME = "LCGOJI"; + public static final int SELF_PORT = 8888; + public static final String SELF_URL = "http://127.0.0.1:" + SELF_PORT; + public static final String TESTER_URL = "http://127.0.0.1:8080"; + + public static void main(String[] args) throws Exception { + port(SELF_PORT); + + before((request, response) -> log.info("Requête entrante : " + request.requestMethod() + " " + request.pathInfo() + ", query params : " + request.queryString())); + + // API pour l'évaluation de λ-term + // Le body est une S-expression sous sa forme textuelle + post("/eval", (request, response) -> { + String body = request.body(); + log.info("Demande d'évaluation de l'expression : " + body); + + // TODO Parser, contruire l'AST, l'évaluer + String result = body; // Renvoie la s-expression à l'identique pour le moment + + log.info("Réponse envoyée : " + body); + + return result.getBytes(); + }); + + init(); + + // Enregistrement de notre API auprès du tester d'API + String jsonBody = "{\"url\":\"" + SELF_URL + "/eval\", \"name\": \"" + TEAM_NAME + "\"}"; + Response response = Request.Post(TESTER_URL + "/register") + .addHeader("Content-type", "application/json") + .body(new StringEntity(jsonBody)) + .execute(); + + log.info("Résultat de l'enregistrement : "+response.returnContent().toString()); + } + +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Abs.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Abs.java new file mode 100644 index 0000000..9d1c146 --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Abs.java @@ -0,0 +1,26 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +import static org.lambdanantes.lcgoji.ast.Var.var; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class Abs implements Term { + + public static final Abs IDENTITY = λ("x", var("x")); + + public String arg; + public Term body; + + public static Abs λ(String arg, Term body) { + return new Abs(arg, body); + } + + @Override + public String toString() { + return "λ" + arg + "." + body; + } +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/App.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/App.java new file mode 100644 index 0000000..2f3e04d --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/App.java @@ -0,0 +1,22 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class App implements Term { + + public Term left; + public Term right; + + public static App apply(Term left, Term right) { + return new App(left, right); + } + + @Override + public String toString() { + return "(" + left + ") " + right; + } +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Term.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Term.java new file mode 100644 index 0000000..2dcc9fe --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Term.java @@ -0,0 +1,5 @@ +package org.lambdanantes.lcgoji.ast; + +public sealed interface Term permits Var, Abs, App { + +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Var.java b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Var.java new file mode 100644 index 0000000..ed710b6 --- /dev/null +++ b/java/lcgoji/src/main/java/org/lambdanantes/lcgoji/ast/Var.java @@ -0,0 +1,21 @@ +package org.lambdanantes.lcgoji.ast; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; + +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@EqualsAndHashCode +public final class Var implements Term{ + + public String name; + + public static Var var(String name) { + return new Var(name); + } + + @Override + public String toString() { + return name; + } +}
\ No newline at end of file diff --git a/java/lcgoji/src/main/resources/log4j2.xml b/java/lcgoji/src/main/resources/log4j2.xml new file mode 100644 index 0000000..f938085 --- /dev/null +++ b/java/lcgoji/src/main/resources/log4j2.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration monitorInterval="60"> + <appenders> + <console name="console" target="SYSTEM_OUT"> + <patternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> + </console> + </appenders> + + <loggers> + <root level="debug"> + <appender-ref ref="console"/> + </root> + <logger name="org.eclipse.jetty" level="warn"/> + <logger name="spark" level="info"/> + </loggers> +</configuration> + diff --git a/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/LCEvaluatorTest.java b/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/LCEvaluatorTest.java new file mode 100644 index 0000000..ec2f027 --- /dev/null +++ b/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/LCEvaluatorTest.java @@ -0,0 +1,74 @@ +package org.lambdanantes.lcgoji; + +import org.junit.Test; +import org.lambdanantes.lcgoji.ast.Term; +import org.lambdanantes.lcgoji.ast.Var; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.lambdanantes.lcgoji.LCEvaluator.evaluate; +import static org.lambdanantes.lcgoji.ast.Abs.IDENTITY; +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; +import static org.lambdanantes.lcgoji.ast.Var.var; + +public class LCEvaluatorTest { + + Var x = var("x"); + Var y = var("y"); + Var z = var("z"); + + @Test + public void l_evaluation_d_une_variable_rend_la_meme_variable() { + // evaluate(x) == x + assertEvalTo(x, x); + } + + @Test + public void l_evaluation_d_une_abstraction_rend_la_meme_abstraction() { + // evaluate(λx.x) == λx.x + assertEvalTo(IDENTITY, IDENTITY); + } + + @Test + public void l_evaluation_de_l_application_de_deux_vars_rend_la_meme_application() { + // evaluate(x y) == x y + assertEvalTo(apply(x, y), apply(x, y)); + } + + @Test + public void l_evaluation_de_l_application_de_l_identite_sur_un_argument_rend_l_argument() { + // evaluate((λx.x) y) == y + assertEvalTo(apply(IDENTITY, y), y); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_substitue_son_argument() { + // evaluate((λx.x x) y ) == y y + assertEvalTo(apply(λ("x", apply(x, x)), y), apply(y, y)); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_d_abstraction_substitue_recursivement_son_argument() { + // evaluate((λx.λy.x) z) == λy.z + assertEvalTo(apply(λ("x", λ("y", x)), z), λ("y", z)); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_ne_substitue_pas_ses_variables_libres() { + // evaluate((λx.y) z) == y + assertEvalTo(apply(λ("x", y), z), y); + } + + @Test + public void l_evaluation_de_l_application_d_une_abstraction_d_abstraction_ne_substitue_pas_les_variables_redefinies() { + // evaluate((λx.λx.x) z) == λx.x + assertEvalTo(apply(λ("x", λ("x", x)), z), λ("x", x)); + } + + ///// + + private static void assertEvalTo(Term termToEvaluate, Term result) { + assertThat(evaluate(termToEvaluate), is(result)); + } +} diff --git a/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/ast/TermTest.java b/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/ast/TermTest.java new file mode 100644 index 0000000..f11ca77 --- /dev/null +++ b/java/lcgoji/src/test/java/org/lambdanantes/lcgoji/ast/TermTest.java @@ -0,0 +1,38 @@ +package org.lambdanantes.lcgoji.ast; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; +import static org.lambdanantes.lcgoji.ast.Abs.λ; +import static org.lambdanantes.lcgoji.ast.App.apply; +import static org.lambdanantes.lcgoji.ast.Var.var; + +public class TermTest { + + @Test + public void les_equals_des_termes_sont_corrects() { + // x == x + assertThat(var("x"), is(var("x"))); + // x != y + assertThat(var("x"), is(not(var("y")))); + // λx.x == λx.x + assertThat(λ("x", var("x")), is(λ("x", var("x")))); + // λx.x != λy.x + assertThat(λ("x", var("x")), is(not(λ("y", var("x"))))); + // x y == x y + assertThat(apply(var("x"), var("y")), is(apply(var("x"), var("y")))); + // x x != x y + assertThat(apply(var("x"), var("x")), is(not(apply(var("x"), var("y"))))); + } + + @Test + public void les_toString_des_termes_utilisent_la_notation_consacree() { + assertThat(var("x").toString(), is("x")); + assertThat(λ("x", var("x")).toString(), is("λx.x")); + assertThat(apply(λ("x", var("x")), var("x")).toString(), is("(λx.x) x")); + assertThat(apply(λ("x", λ("x", var("x"))), var("y")).toString(), is("(λx.λx.x) y")); + } + +}
\ No newline at end of file diff --git a/java/log4j2.xml b/java/log4j2.xml new file mode 100644 index 0000000..f938085 --- /dev/null +++ b/java/log4j2.xml @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration monitorInterval="60"> + <appenders> + <console name="console" target="SYSTEM_OUT"> + <patternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/> + </console> + </appenders> + + <loggers> + <root level="debug"> + <appender-ref ref="console"/> + </root> + <logger name="org.eclipse.jetty" level="warn"/> + <logger name="spark" level="info"/> + </loggers> +</configuration> + diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 0000000..f4a4f30 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.lambdanantes</groupId> + <artifactId>lcgoji</artifactId> + <version>1.0-SNAPSHOT</version> + + <properties> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <lombok.version>1.18.30</lombok.version> + <log4j.version>2.16.0</log4j.version> + + <jetty-util.version>9.4.31.v20200723</jetty-util.version> + <spark-core.version>2.9.3</spark-core.version> + <httpclient.version>4.3.1</httpclient.version> + + <junit.version>4.10</junit.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-slf4j-impl</artifactId> + <version>${log4j.version}</version> + </dependency> + <dependency> + <groupId>org.apache.logging.log4j</groupId> + <artifactId>log4j-core</artifactId> + <version>${log4j.version}</version> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-util</artifactId> + <version>${jetty-util.version}</version> + </dependency> + <dependency> + <groupId>com.sparkjava</groupId> + <artifactId>spark-core</artifactId> + <version>${spark-core.version}</version> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>fluent-hc</artifactId> + <version>${httpclient.version}</version> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + </dependency> + </dependencies> +</project>
\ No newline at end of file |
