diff options
author | pukkamustard <pukkamustard@posteo.net> | 2021-05-10 16:05:20 +0200 |
---|---|---|
committer | pukkamustard <pukkamustard@posteo.net> | 2021-05-20 10:45:33 +0200 |
commit | d9006ccd093f8890dc950fa7416b44c09d1350b7 (patch) | |
tree | eac1dd12cdcccce09926ffb1ff0d65d9d8b95497 /test | |
parent | ff6b06ec2295e35a9f2e6e029a06fdea927ed883 (diff) |
Rdf_datalog.Parser: Parser for Datalog
This allows the Datalog engine to be used without constructing
complicated OCaml terms. Clauses can now simply be written in usual
Datalog syntax.
See test/datalog/main.ml for an example.
Diffstat (limited to 'test')
-rw-r--r-- | test/datalog/dune | 13 | ||||
-rw-r--r-- | test/datalog/main.ml | 36 | ||||
-rw-r--r-- | test/datalog/parser.ml | 116 |
3 files changed, 165 insertions, 0 deletions
diff --git a/test/datalog/dune b/test/datalog/dune new file mode 100644 index 0000000..1ca70ed --- /dev/null +++ b/test/datalog/dune @@ -0,0 +1,13 @@ +(executables + (names parser main) + (libraries rdf_datalog + rdf_alcotest + angstrom alcotest)) + +(rule + (alias runtest) + (action (run ./main.exe))) + +(rule + (alias runtest) + (action (run ./parser.exe))) diff --git a/test/datalog/main.ml b/test/datalog/main.ml new file mode 100644 index 0000000..ad6e295 --- /dev/null +++ b/test/datalog/main.ml @@ -0,0 +1,36 @@ +(* + * SPDX-FileCopyrightText: 2021 petites singularités <ps-dream@lesoiseaux.io> + * SPDX-FileCopyrightText: 2021 pukkamustard <pukkamustard@posteo.netq> + * + * SPDX-License-Identifier: AGPL-3.0-or-later + *) + +module Parser = Rdf_datalog.Parser +module Term = Rdf_datalog.Term +module Literal = Rdf_datalog.Literal +module Clause = Rdf_datalog.Clause +module Theory = Rdf_datalog.Theory + +let example = + {example| + + edge("a", "b"). + edge("b", "c"). + edge("c", "d"). + + path(?a,?b) :- edge(?a,?b). + path(?a,?c) :- edge(?a,?b), path(?b,?c). +|example} + +let parse p string = + Angstrom.parse_string + ~consume:Angstrom.Consume.All + p string + |> Result.get_ok + +let parse_theory = parse Parser.theory +let parse_query = parse Parser.query + +let () = + Format.printf "%a" (Fmt.list Literal.pp) @@ + Theory.prove (parse_theory example) (parse_query {q|path(?a,?b)?|q}) diff --git a/test/datalog/parser.ml b/test/datalog/parser.ml new file mode 100644 index 0000000..7c100dc --- /dev/null +++ b/test/datalog/parser.ml @@ -0,0 +1,116 @@ +(* + * SPDX-FileCopyrightText: 2021 petites singularités <ps-dream@lesoiseaux.io> + * SPDX-FileCopyrightText: 2021 pukkamustard <pukkamustard@posteo.netq> + * + * SPDX-License-Identifier: AGPL-3.0-or-later + *) + +module Parser = Rdf_datalog.Parser +module Term = Rdf_datalog.Term +module Literal = Rdf_datalog.Literal +module Clause = Rdf_datalog.Clause + +open Alcotest + +let parse p = + Angstrom.parse_string + ~consume:Angstrom.Consume.All + p + +let xsd_string_test_case = + test_case "xsd_string" `Quick + (fun () -> + check (result Rdf_alcotest.literal string) + "can parse" + (parse Parser.xsd_string "\"Hello World\"") + (Result.ok @@ Rdf.Literal.make "Hello World" @@ Rdf.Namespace.xsd "string") + ) + +let iri_test_case = + test_case "iri" `Quick + (fun () -> + check (result Rdf_alcotest.iri string) + "can parse" + (parse Parser.iri "<http://example.com>") + (Result.ok @@ Rdf.Iri.of_string "http://example.com") + ) + +let variable_test_case = + test_case "variable" `Quick + (fun () -> check (result string string) + "can parse" + (parse Parser.variable "?abc") + (Result.ok @@ "abc")) + +let term_testable = + testable Term.pp Term.equal + +let term_test_case = + let cases = + ["?abc", Term.variable "abc"; + "?a", Term.variable "a"; + "<http://example.com>", "http://example.com" |> Rdf.Iri.of_string |> Rdf.Term.of_iri |> Term.constant; + "\"blups\"", Rdf.Literal.make "blups" (Rdf.Namespace.xsd "string") |> Rdf.Term.of_literal |> Term.constant; + ] in + + test_case "term" `Quick + (fun () -> + List.iter + (fun (enc, v) -> + check (result term_testable string) + "can parse" + (parse Parser.term enc) + (Result.ok v)) + cases) + +let literal_testable = + testable Literal.pp Literal.equal + +let literal_test_case = + let cases = [ + "p(?a,?b)", Literal.make "p" [Term.variable "a"; Term.variable "b"]; + "graph(?a,<http://example.com>)", Literal.make "graph" [Term.variable "a"; + "http://example.com" |> Rdf.Iri.of_string |> Rdf.Term.of_iri |> Term.constant] + ] in + test_case "literal" `Quick + (fun () -> + List.iter + (fun (enc, v) -> + check (result literal_testable string) + "can parse" + (parse Parser.literal enc) + (Result.ok v)) + cases) + +let clause_testable = + testable Clause.pp Clause.equal + +let clause_test_case = + let cases = [ + "p(?a, ?b).", Literal.make "p" [Term.variable "a"; Term.variable "b"] |> Clause.fact; + "p(?a, ?b) :- q(?a,?b).", Clause.make + (Literal.make "p" [Term.variable "a"; Term.variable "b"]) + [(Literal.make "q" [Term.variable "a"; Term.variable "b"])] ; + ] in + test_case "clause" `Quick + (fun () -> + List.iter + (fun (enc, v) -> + check (result clause_testable string) + "can parse" + (parse Parser.clause enc) + (Result.ok v)) + cases) + +let () = + Alcotest.run "Rdf_datalog.Parser" + [ + "Basic parsers", [ + xsd_string_test_case; + iri_test_case; + variable_test_case; + term_test_case; + literal_test_case; + clause_test_case; + ] + ] |