Person getAChildOf(Person p) { p = getAParentOf(result) # result的parent是p, 即p的child是result}
多返回值谓词
string getFunc(string action) {action="rce"and result ="popen"oraction="rce"and result ="system"oraction="ssrf"and result ="file_get_contents"oraction="ssrf"and result ="curl_exec"}
getFunc("rce")返回两个结果popen、system
getFunc("csrf")不返回结果
递归谓词
string getANeighbor(string country) { country ="France"and result ="Belgium"or country ="France"and result ="Germany"or country ="Germany"and result ="Austria"or country ="Germany"and result ="Belgium"or country = getANeighbor(result)}
int getSuccessor(int i) { //1. Non-member predicate result = i +1and i in [1 .. 9]}class FavoriteNumbers extends int { FavoriteNumbers() { //2. Characteristic predicate this =1or this =4or this =9 } string getName() { //3. Member predicatefor the class `FavoriteNumbers` this =1and result ="one"or this =4and result ="four"or this =9and result ="nine" }}
集合绑定
上面说到谓词的参数和返回结果的值域都要是有限的tuple,即谓词只能包含有限数量的元组
如下的谓词编译时就会报错。
/* Compilation errors: ERROR: "i" is not bound to a value. ERROR: "result" is not bound to a value. ERROR: expression "i * 4" is not bound to a value.*/int multiplyBy4(int i) { result = i *4}/* Compilation errors: ERROR: "str" is not bound to a value. ERROR: expression "str.length()" is not bound to a value.*/predicate shortString(string str) { str.length() <10}
可以通过在谓词上使用bindingset标志,其声明了该谓词的输入绑定到了有限的数据集合
bindingset[x] bindingset[y]predicate plusOne(int x, int y) { x +1= y}fromint x, int ywhere y =42and plusOne(x, y)select x, y
bindingset[x] bindingset[y]是or关系,即x或y是有限的
而bindingset[x, y]是and关系,即x和y必须是有限的
bindingset[str, len]string truncate(string str, int len) {if str.length() > lenthen result = str.prefix(len)else result = str}