歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

代碼分析平臺CodeQL學習手記(七)

來源:本站整理 作者:佚名 時間:2020-01-22 TAG: 我要投稿

在前面的文章中,我們通過一個抓縱火犯的例子來復習了謂詞的相關知識,并進一步學習類的定義和用法,以及如何覆蓋父類的成員謂詞。在本文中,我們將以尋找合法王位繼承人為例深入講解遞歸的概念與應用。
簡介
就在我們連續破獲了發生在村莊中的兩起案件后,村莊又恢復了往日的平靜。然而,就在我們離開村子前的最后一個夜晚,城堡中年老的國王——偉大的Basil國王——在睡夢中與世長辭,村莊再次陷入混亂之中!
為什么會再次陷入混亂呢?因為老國王既沒結過婚,也沒有自己的孩子,所以,沒有人知道應該由誰來繼承國王的城堡和財產。這時,許多村民都聲稱自己是國王家族的后裔,是合法的繼承人。為此,人們爭論不休,雞犬不寧。
最終,受村民之托,我們決定留在村子里平息這場爭論——找到真正的王位繼承人。
尋找國王的兄弟姐妹
既然許多村民都聲稱自己是王室家族的后裔,我們就需要弄清楚他們跟國王到底有沒有親緣關系。當然,這是一項非常艱巨的任務,不過,好在我們手頭上已經掌握了村民們許多的數據,同時,我們還獲得了一份名單,上面記錄了村里所有的父母及其子女之間的關系。
為了深入了解國王及其家世,我們開始進入城堡查找相應的線索,最終找到了一些古老的家譜。掌握這條重要的線索后,我們立刻查詢現有的數據庫中,看看國王家族中是否還有人健在。
為此,我們可以借助于一個謂詞:parentOf(Person p)。它的作用是,輸入一個表示村民的變量p,該謂詞就會返回該村民的父母。例如,通過它,我們可以將所有村民p與其父母一起列出:
from Person p
select parentOf(p) + " is a parent of " + p
運行結果如下所示:

如您所見,這里返回的信息太多了,如果通過人工方式進行搜索的話,那就太費時費力了。所以,我們打算編寫了一個QL查詢來查找國王的繼承人。
盡管國王膝下并沒有子女,但是,也許他還有兄弟姐妹健在。為此,我們可以編寫一個查詢,來查找國王的兄弟姐妹。很明顯,這里要查找的人,就是除了國王本人之外,跟國王同父同母的村民,具體代碼如下所示:
from Person p
    where parentOf(p) = parentOf("King Basil") and
    not p = "King Basil"
select p
上面的代碼的運行結果如下所示:

如您所見,確實是有兄弟姐妹的!不過,既然國王年事已高,他的同胞們肯定也不小了,所以,我們需要考察他們是否還健在。為了完成這項任務,我們可以編寫一個詞,即isDeceased(),讓它來判斷某人是否已經離世。
下面,我們就借助謂詞isDeceased()來考察國王的兄弟姐妹是否還健在,具體的代碼如下所示:
from Person p
where parentOf(p) = parentOf("King Basil") and
    not p = "King Basil"
    and not p.isDeceased()
select p
下面是上述代碼的運行結果:

不幸的是,Basil國王的兄弟姐妹都已經不在人世了——上面沒有返回任何結果。既然老國王同輩的親屬已經不在了,我們就需要進一步調查還有沒有晚輩的親屬。為此,我們可以定義一個謂詞childOf(),用來返回某人的子女。我們知道,當且僅當村民p是某人的父母時,某人才是村民p的子女。所以,在定義謂詞childOf()時,我們可以借助于前面介紹過的謂詞parentOf(),具體如下所示:
Person childOf(Person p) {
    p = parentOf(result)
}
對于上面的定義,我們可以這樣理解:遍歷所有村民,把符合p = parentOf(result)條件的村民作為返回值。當然,我們也可用result =
好了,下面我們利用謂詞childOf()來編寫一個查詢,看看國王的兄弟姐妹是否有后代:
from Person p
where parentOf(p) = parentOf("King Basil") and
    not p = "King Basil"
select childOf(p)
上面的代碼的運行結果如下所示:

如您所見,這里的查詢沒有返回任何結果,這表明國王的兄弟姐妹們并沒有后代。既然國王的近親沒有后代,那么接下來,我們要做的事情就是調查老國王遠親是否還健在,或者是否有后代。
尋找國王的遠親
到目前為止,事情好像變得越來越復雜了。為了找到國王的所有親戚,我們想要定義一個謂詞relativeOf(Person p),以便幫忙找出某人的所有親屬。
不過,在編寫這個謂詞之前,需要對親屬關系下一個精確地定義:如果兩個人有共同的祖先,他們就是親屬關系。
為此,我們又引入一個共同祖先的關系。這時,我們可以定義一個謂詞ancestorOf(Person p),用來找出某人p的所有祖先。當然,某人p的祖先可以是p的父輩,或者p的父輩的父輩,或者p的父輩的父輩的父輩,依此類推。不過,如果這樣做的話,我們就會得到一個無窮無盡的父輩名單。很明顯,我們必須尋找一個更可行的方法。
思考良久,我們終于想到,如果把問題重新表述一下,就能幫我們找到答案。也就是說,這里所說的祖先,要么是某人的父母,要么是已知為某人祖先的人的父母。好了,下面我們將上面的話翻譯成QL語言,具體如下所示:
Person ancestorOf(Person p) {
    result = parentOf(p) or

[1] [2] [3]  下一頁

【聲明】:黑吧安全網(http://www.650547.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        安徽快3自由的百科 海陆重工股票 股票分析软件手机版 广东快乐十分手机助手 辽宁快乐12开奖查询 吉林11选5怎么玩怎么看 极速赛车开奖网址 江西体彩多乐彩基本走势图 黑龙江体彩11选5预算号 2007上证指数 吉林快3开奖电视图