mangle - Mangle 是一种用于演绎数据库编程的编程语言。它是 Datalog 的扩展,具有聚合、函数调用和可选类型检查等各种扩展。

Created at: 2022-11-24 21:22:28
Language: Go
License: Apache-2.0

裂 伤

Mangle是一种用于演绎数据库编程的编程语言。它是Datalog的扩展,具有各种扩展,如聚合,函数调用和可选的类型检查。

演绎数据库对于将来自多个数据源的数据汇集在一起很有用,因为它使我们能够以统一的方式表示和查询该数据。它还可用于对领域知识进行建模,类似于机器可读的本体,但不限于二进制谓词。

Datalog 是一种类似于关系演算(想想 SQL 和关系视图)的表达性声明性语言。与关系演算不同,它还支持递归规则和程序结构。

Mangle包含数据日志作为片段,并添加扩展使其使用更实用。使用扩展时,一些良好的属性(如保证终止)会丢失。

Mangle作为一个开源项目的目标是以一种开发人员可以访问的方式传达概念,并适合于轻松的实验。该存储库包含 Mangle 作为 go 库的实现,可以轻松嵌入到应用程序中。

这不是官方支持的 Google 产品。

目录

例子

简单查询

想象一下,你被要求发现受 2021 年底发现的 log4j 漏洞影响的软件。我们要查找包含 log4j 的 Java 存档(jar 文件)的项目,该存档未更新到修补版本。

projects_with_vulnerable_log4j(P) :-
  projects(P),
  contains_jar(P, "log4j", Version),
  Version != "2.17.1",
  Version != "2.12.4",
  Version != "2.3.2".

这是一个 Mangle 规则:从概念上讲,实现检索变量的所有可能值,并使所有子目标都为真。

P
Version

像这样的简单 Mangle 规则对应于选择-项目-联接关系查询。SQL 中的相同查询如下所示:

SELECT projects.id as P
FROM projects JOIN contains_jar ON projects.id = contains_jar.project_id
WHERE contains_jar.version NOT IN ("2.17.1", "2.12.4", "2.3.2")

与 SQL 不同,我们的 Mangle 规则有一个名称,可以在其他查询中引用。

projects_with_vulnerable_log4j

(如果将非递归数据日志转换为SQL查询听起来很有趣,你应该查看Logica开源项目。

集合体

在实践中,查询很少足够,我们还需要分组和聚合。

count_projects_with_vulnerable_log4j(Num) :-
  projects_with_vulnerable_log4j(P) |> do fn:group_by(), let Num = fn:Count().

递归查询

该示例未指定什么功能。下面是一个可能的实现,用于遍历依赖关系图。这表明 Mangle 规则可以是递归的。

contains_jar
contains_jar

contains_jar(P, Name, Version) :-
  contains_jar_directly(P, Name, Version).

contains_jar(P, Name, Version) :-
  project_depends(P, Q),
  contains_jar(Q, Name, Version).

这两个规则对应于项目可以“包含”jar的两种情况:直接或通过某种依赖关系。

知识图谱、属性图谱

在工程需求时,通过域模型和受控词汇表对现实世界的一部分进行建模很有用。描述逻辑使用角色来描述概念的交互方式,但关系始终是二元的。Mangle可以表示二元谓词,也可以表示任意n元关系。

one_or_two_leg_trip(Codes, Start, Destination, Price) :-
  direct_conn(Code, Start, Destination, Price)
  |> let Codes = [Code].

one_or_two_leg_trip(Codes, Start, Destination, Price) :-
  direct_conn(FirstCode, Start, Connecting, FirstLegPrice).
  direct_conn(SecondCode, Connecting, Destination, SecondLegPrice)
  |> let Code = [FirstCode, SecondCode],
     let Price = fn:sum(FirstLegPrice, SecondLegPrice).

graph LR
    /zurich -->|/code/ZL <br /> 60 CHF| /lausanne
    /zurich -->|/code/ZB <br /> 30 CHF| /bern
    /bern -->|/code/ZL <br /> 30 CHF| /lausanne

建筑

如果要从源代码构建,则需要先设置 ANTLR,这需要 Java 运行时环境。

wget http://www.antlr.org/download/antlr-4.11.1-complete.jar
alias antlr='java -jar $PWD/antlr-4.11.1-complete.jar'

然后你可以生成解析器源

antlr -Dlanguage=Go -package gen -o ./ parse/gen/Mangle.g4 -visitor

...最后获取依赖项(参见 go.mod)并构建库:

go get ...
go build ...

贡献

Mangle维护者欢迎外部贡献规范,文档和此实现(见 CONTRIBUTING.md)以及其他实现。拉取请求将像处理 tensorflow 一样处理,以确保我们的内部使用和测试能够通过。