Skip to content

Commit 12342f9

Browse files
adding tuProlog (#6766)
1 parent fc5b6d9 commit 12342f9

File tree

13 files changed

+382
-1
lines changed

13 files changed

+382
-1
lines changed

frameworks/Prolog/SWI-Prolog/app/server.pl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
server(Port) :-
1515
odbc_set_option(connection_pooling(true)),
1616
current_prolog_flag(cpu_count, Cores),
17-
Workers is 256 * Cores,
17+
Workers is 64 * Cores,
1818
http_server(http_dispatch, [workers(Workers), port(Port), timeout(30)]).
1919

2020

frameworks/Prolog/tuProlog/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/.idea
2+
/target
3+
tuprolog.iml
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:- web_resource(plaintext/1, content_type(text/plain)).
2+
plaintext('Hello, World!').
3+
4+
:- web_resource(json/1).
5+
json([message('Hello, World!')]).
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"framework": "tuprolog",
3+
"tests": [{
4+
"default": {
5+
"json_url": "/json",
6+
"plaintext_url": "/plaintext",
7+
"port": 8080,
8+
"approach": "Realistic",
9+
"classification": "None",
10+
"database": "None",
11+
"framework": "tuprolog",
12+
"language": "Prolog",
13+
"orm": "Raw",
14+
"platform": "None",
15+
"webserver": "Vert.x",
16+
"os": "Linux",
17+
"database_os": "Linux",
18+
"display_name": "tuProlog",
19+
"notes": "",
20+
"versus": "",
21+
"tags": []
22+
}
23+
}]
24+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[framework]
2+
name = "tuprolog"
3+
4+
[main]
5+
urls.plaintext = "/plaintext"
6+
urls.json = "/json"
7+
approach = "Realistic"
8+
classification = "None"
9+
database = "None"
10+
database_os = "Linux"
11+
os = "Linux"
12+
orm = "Raw"
13+
platform = "None"
14+
webserver = "Vert.x"
15+
versus = ""

frameworks/Prolog/tuProlog/pom.xml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.kartashov.fb</groupId>
8+
<artifactId>tuprolog-web-runner</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>16</maven.compiler.source>
13+
<maven.compiler.target>16</maven.compiler.target>
14+
<tuprolog.version>0.18.2</tuprolog.version>
15+
<vertx.version>4.1.2</vertx.version>
16+
<jackson.version>2.12.3</jackson.version>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>it.unibo.tuprolog</groupId>
22+
<artifactId>io-lib-jvm</artifactId>
23+
<version>${tuprolog.version}</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>it.unibo.tuprolog</groupId>
27+
<artifactId>solve-classic-jvm</artifactId>
28+
<version>${tuprolog.version}</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>io.vertx</groupId>
32+
<artifactId>vertx-web</artifactId>
33+
<version>${vertx.version}</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>com.fasterxml.jackson.core</groupId>
37+
<artifactId>jackson-databind</artifactId>
38+
<version>${jackson.version}</version>
39+
</dependency>
40+
</dependencies>
41+
42+
<build>
43+
<plugins>
44+
<plugin>
45+
<artifactId>maven-assembly-plugin</artifactId>
46+
<configuration>
47+
<archive>
48+
<manifest>
49+
<mainClass>com.kartashov.fb.tuprolog.Runner</mainClass>
50+
</manifest>
51+
</archive>
52+
<descriptorRefs>
53+
<descriptorRef>jar-with-dependencies</descriptorRef>
54+
</descriptorRefs>
55+
</configuration>
56+
<executions>
57+
<execution>
58+
<id>make-assembly</id>
59+
<phase>package</phase>
60+
<goals>
61+
<goal>single</goal>
62+
</goals>
63+
</execution>
64+
</executions>
65+
</plugin>
66+
</plugins>
67+
</build>
68+
69+
</project>
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.kartashov.fb.tuprolog;
2+
3+
import com.kartashov.fb.tuprolog.processors.DirectiveProcessor;
4+
import com.kartashov.fb.tuprolog.processors.WebResourceDirectiveProcessor;
5+
import io.vertx.core.http.HttpServerRequest;
6+
import it.unibo.tuprolog.core.Struct;
7+
import it.unibo.tuprolog.core.Var;
8+
import it.unibo.tuprolog.solve.MutableSolver;
9+
import it.unibo.tuprolog.solve.Solver;
10+
import it.unibo.tuprolog.theory.Theory;
11+
import it.unibo.tuprolog.theory.parsing.ClausesReader;
12+
13+
import java.io.FileInputStream;
14+
import java.io.FileNotFoundException;
15+
import java.nio.file.Paths;
16+
import java.util.HashMap;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
public class Engine {
21+
22+
private final Map<String, Resource> resources = new HashMap<>();
23+
private final MutableSolver solver = Solver.getClassic().mutableSolverWithDefaultBuiltins();
24+
25+
public Engine(String... paths) {
26+
Theory theory = Theory.empty();
27+
ClausesReader reader = ClausesReader.getWithDefaultOperators();
28+
for (var path : paths) {
29+
try {
30+
var stream = new FileInputStream(Paths.get(path).toFile());
31+
var subTheory = reader.readTheory(stream);
32+
for (var processor : processors()) {
33+
subTheory = processor.apply(subTheory, this);
34+
}
35+
theory = theory.plus(subTheory);
36+
} catch (FileNotFoundException e) {
37+
throw new RuntimeException("Cannot load file", e);
38+
}
39+
}
40+
solver.loadStaticKb(theory);
41+
}
42+
43+
public void addResource(String path, Resource resource) {
44+
resources.put(path, resource);
45+
}
46+
47+
public void resolve(HttpServerRequest request) {
48+
var resource = resources.get(request.path());
49+
if (resource == null) {
50+
request.response().setStatusCode(404).end();
51+
return;
52+
}
53+
var goalTerm = Struct.of(resource.predicate(), Var.of("Response"));
54+
var solution = solver.solveOnce(goalTerm);
55+
if (solution.isYes()) {
56+
var responseTerm = solution.getSubstitution().getByName("Response");
57+
if (responseTerm == null) {
58+
request.response().setStatusCode(503).end();
59+
} else {
60+
resource.writer().write(request.response(), responseTerm);
61+
}
62+
} else {
63+
request.response().setStatusCode(404).end();
64+
}
65+
}
66+
67+
private List<DirectiveProcessor> processors() {
68+
return List.of(
69+
new WebResourceDirectiveProcessor()
70+
);
71+
}
72+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.kartashov.fb.tuprolog;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.kartashov.fb.tuprolog.visitors.TermToJavaObjectConverterVisitor;
6+
import io.vertx.core.http.HttpServerResponse;
7+
import it.unibo.tuprolog.core.Term;
8+
9+
import java.time.ZonedDateTime;
10+
import java.time.format.DateTimeFormatter;
11+
import java.util.Objects;
12+
13+
public record Resource(String predicate, Writer writer) {
14+
public record Writer(String contentType) {
15+
public void write(HttpServerResponse response, Term term) {
16+
response.putHeader("Server", "tuProlog");
17+
response.putHeader("Date", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.now()));
18+
response.putHeader("Content-Type", contentType);
19+
switch (contentType) {
20+
case "application/json" -> {
21+
var visitor = new TermToJavaObjectConverterVisitor();
22+
var value = term.accept(visitor);
23+
var mapper = new ObjectMapper();
24+
try {
25+
response.end(mapper.writeValueAsString(value));
26+
} catch (JsonProcessingException e) {
27+
throw new RuntimeException(e);
28+
}
29+
}
30+
case "text/plain" -> response.end(Objects.requireNonNull(term.asAtom()).getValue());
31+
}
32+
}
33+
}
34+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.kartashov.fb.tuprolog;
2+
3+
import io.vertx.core.Vertx;
4+
5+
public class Runner {
6+
public static void main(String... args) {
7+
var engine = new Engine(args);
8+
var server = Vertx.vertx().createHttpServer();
9+
server.requestHandler(engine::resolve);
10+
server.listen(8080);
11+
}
12+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.kartashov.fb.tuprolog.processors;
2+
3+
import com.kartashov.fb.tuprolog.Engine;
4+
import it.unibo.tuprolog.core.Struct;
5+
import it.unibo.tuprolog.core.Term;
6+
import it.unibo.tuprolog.theory.Theory;
7+
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
import java.util.Objects;
11+
12+
public abstract class DirectiveProcessor {
13+
14+
abstract String functor();
15+
16+
protected Theory apply(Struct target, Map<String, Term> properties, Theory theory, Engine engine) {
17+
return theory;
18+
}
19+
20+
final public Theory apply(Theory theory, Engine engine) {
21+
for (var directive: theory.getDirectives()) {
22+
var body = directive.getBody().asStruct();
23+
if (body == null || !body.getFunctor().equals(functor())) {
24+
continue;
25+
}
26+
Struct target = null;
27+
var properties = new HashMap<String, Term>();
28+
var i = 0;
29+
for (var arg: body.getArgs()) {
30+
Struct argStruct = Objects.requireNonNull(arg.asStruct());
31+
if (i++ == 0) {
32+
target = argStruct;
33+
} else {
34+
properties.put(argStruct.getFunctor(), argStruct.getArgAt(0));
35+
}
36+
}
37+
theory = apply(target, properties, theory, engine);
38+
}
39+
return theory;
40+
}
41+
}
42+

0 commit comments

Comments
 (0)