开源代码见:
pilcom为Polygon zkEVM的PIL(Polynomial Identity Language)编译器。
以test/examples
下的arrays.pil
代码为例:
namespace Arrays2(2**16);
pol constant d[2];
pol commit c;
d[0]+d[1] = c*d[0]; //第6行
namespace Arrays1(2**16);
pol commit a, b[3], c;
a*b[0] = 1; //第11行
b[1]*b[1] = b[2]*Arrays2.d[1]; //第12行
b[1] {b[0], a} in Arrays2.d[0] { Arrays2.c, Arrays2.d[1]}; //第14行
$ node src/pil.js test/examples/arrays.pil -o zyd.json
Debugger attached.
Input Pol Commitmets: 6
Q Pol Commitmets: 0
Constant Pols: 2
Im Pols: 0
plookupIdentities: 1
permutationIdentities: 0
connectionIdentities: 0
polIdentities: 3
Waiting for the debugger to disconnect...
pil.js
代码本质为调用compile
将pil代码编译为JSON格式。
const out = await compile(F, fullFileName, null, config);
console.log("Input Pol Commitmets: " + out.nCommitments); // 以`pol commit`表示的多项式总数
console.log("Q Pol Commitmets: " + out.nQ); // 以多项式本身为粒度,若degree为2,则nQ++,如`pol next = l1*l1 + l2*l2;`,需nQ++。
console.log("Constant Pols: " + out.nConstants); // 以`pol constant`表示的多项式总数
console.log("Im Pols: " + out.nIm); // 仅以`pol`,而非`pol constant`或`pol commit`表示的多项式总数
console.log("plookupIdentities: " + out.plookupIdentities.length); // 即pil中的`in`表示的约束总数
console.log("permutationIdentities: " + out.permutationIdentities.length); // 即pil中的`is`表示的约束总数
console.log("connectionIdentities: " + out.connectionIdentities.length); // 即pil中的`connect`表示的约束总数
console.log("polIdentities: " + out.polIdentities.length); // 即pil中的`=`表示的约束总数
await fs.promises.writeFile(outputFile.trim(), JSON.stringify(out, null, 1) + "\n", "utf8");
相应的json文件输出为:
pol constant
;pol commit
;"polIdentities": [
{
"e": 0,
"fileName": "arrays.pil",
"line": 6
},
{
"e": 1,
"fileName": "arrays.pil",
"line": 11
},
{
"e": 2,
"fileName": "arrays.pil",
"line": 12
}
]
{
"op": "number",
"deg": 0,
"value": "1"
}
b[1] {b[0], a} in Arrays2.d[0] { Arrays2.c, Arrays2.d[1]};
,对应在“expressions”中的JSON表示为:【规则为先in
的左侧,再右侧。】{ # b[0]。在expressions数组的index为3。
"op": "cm",
"deg": 1,
"id": 2,
"next": false
},
{ # a。在expressions数组的index为4。
"op": "cm",
"deg": 1,
"id": 1,
"next": false
},
{ # b[1]。在expressions数组的index为5。
"op": "cm",
"deg": 1,
"id": 3,
"next": false
},
{ # c。在expressions数组的index为6。
"op": "cm",
"deg": 1,
"id": 0,
"next": false
},
{ # d[1]。在expressions数组的index为7。
"op": "const",
"deg": 1,
"id": 1,
"next": false
},
{ # d[0]。在expressions数组的index为8。
"op": "const",
"deg": 1,
"id": 0,
"next": false
}
"plookupIdentities": [
{
"f": [
3,
4
],
"t": [
6,
7
],
"selF": 5,
"selT": 8,
"fileName": "arrays.pil",
"line": 14
}
]
{
"nCommitments": 6,
"nQ": 0,
"nIm": 0,
"nConstants": 2,
"publics": [],
"references": {
"Arrays2.d": { # namespace.polyName
"type": "constP",
"id": 0,
"polDeg": 65536,
"isArray": true,
"len": 2
},
"Arrays2.c": {
"type": "cmP",
"id": 0,
"polDeg": 65536,
"isArray": false
},
"Arrays1.a": {
"type": "cmP",
"id": 1,
"polDeg": 65536,
"isArray": false
},
"Arrays1.b": {
"type": "cmP",
"id": 2,
"polDeg": 65536,
"isArray": true,
"len": 3
},
"Arrays1.c": {
"type": "cmP",
"id": 5,
"polDeg": 65536,
"isArray": false
}
},
"expressions": [
{ # 对应约束为:d[0]+d[1]-d[0]*c=0
"op": "sub",
"deg": 2,
"values": [
{
"op": "add",
"deg": 1,
"values": [
{
"op": "const",
"deg": 1,
"id": 0,
"next": false
},
{
"op": "const",
"deg": 1,
"id": 1,
"next": false
}
]
},
{
"op": "mul",
"deg": 2,
"values": [
{
"op": "cm",
"deg": 1,
"id": 0,
"next": false
},
{
"op": "const",
"deg": 1,
"id": 0,
"next": false
}
]
}
]
},
{ # 对应约束为: a*b[0]-1=0
"op": "sub",
"deg": 2,
"values": [
{
"op": "mul",
"deg": 2,
"values": [
{
"op": "cm",
"deg": 1,
"id": 1,
"next": false
},
{
"op": "cm",
"deg": 1,
"id": 2,
"next": false
}
]
},
{
"op": "number",
"deg": 0,
"value": "1"
}
]
},
{ # 对应约束为:b[1]*b[1]-b[2]*d[1]=0
"op": "sub",
"deg": 2,
"values": [
{
"op": "mul",
"deg": 2,
"values": [
{
"op": "cm",
"deg": 1,
"id": 3,
"next": false
},
{
"op": "cm",
"deg": 1,
"id": 3,
"next": false
}
]
},
{
"op": "mul",
"deg": 2,
"values": [
{
"op": "cm",
"deg": 1,
"id": 4,
"next": false
},
{
"op": "const",
"deg": 1,
"id": 1,
"next": false
}
]
}
]
},
{ # b[0]
"op": "cm",
"deg": 1,
"id": 2,
"next": false
},
{ # a
"op": "cm",
"deg": 1,
"id": 1,
"next": false
},
{ # b[1]
"op": "cm",
"deg": 1,
"id": 3,
"next": false
},
{ # c
"op": "cm",
"deg": 1,
"id": 0,
"next": false
},
{ # d[1]
"op": "const",
"deg": 1,
"id": 1,
"next": false
},
{ # d[0]
"op": "const",
"deg": 1,
"id": 0,
"next": false
}
],
"polIdentities": [
{
"e": 0,
"fileName": "arrays.pil",
"line": 6
},
{
"e": 1,
"fileName": "arrays.pil",
"line": 11
},
{
"e": 2,
"fileName": "arrays.pil",
"line": 12
}
],
"plookupIdentities": [
{
"f": [
3,
4
],
"t": [
6,
7
],
"selF": 5,
"selT": 8,
"fileName": "arrays.pil",
"line": 14
}
],
"permutationIdentities": [],
"connectionIdentities": []
}