法律中的遞歸現象
遞歸(Recursion),搞計算機的人熟悉無比,外人卻聽起來就覺得陌生詭異,弟子規?
但遞歸解釋起來很簡單,甚至可以用一句話說明:遞歸就是指在定義一個概念和過程時,又用到了本身。
很多人小時候聽過的這個無厘頭故事就有遞歸的風味:從前有座山,山上有座廟,廟裡有個老和尚對小和尚講故事:從前有座山,山上有座廟,廟裡有個老和尚對小和尚講故事:從前有座山……
對遞歸的直觀感覺是兩重的,第一是簡單,第二是荒謬。
簡單,一句話就能解釋清楚的東西。(可是計算機科學卻把它當成一個寶,還整個這麼彆扭的名字,弄的多麼高深似的,故弄玄虛,大氣功師太極拳啊?)
荒謬,用自己定義自己,那不成了同義反覆、循環定義了么,這在邏輯上都是有錯的啊!一個過程自己包含自己,這個過程若執行起來的話,那不沒完了么?
遞歸的妙用,恰恰就源自它看起來的荒謬之處。如果一個過程中又包含自身,那麼這個過程就可以無窮地展開,不會在有窮的步驟後停止。但是描述這個過程只需要有窮的指令。以有窮表現無窮。
同時,又有辦法控制這種似乎要停不下來的無窮過程。有效的遞歸過程中調用的自身,其實並不是完全相同的自身,而是一個「縮減版」的自身。多次遞歸反覆調用後,這個自身可以漸次縮減成一個 base condition 或者說 base case ,不再繼續遞歸,而返回一個確定的結果。這個「縮減」過程和 base condition 的不同設置,可以讓遞歸過程展現出千姿百態(這也是使用遞歸的最大有趣之處,更有趣的是,這種設置的隻言片語的改動能讓運行結果有天壤之別)。
如此處理,讓遞歸消除了看起來的荒謬之處,同時保留了「以有窮馭無窮」的巨大威力。難怪它會成為計算機科學中倍受喜愛的一個東東。 Alan Perlis 有言:
Recursion is the root of computation since it trades description for time.
遞歸的威力,實際上有更深刻的來源。
都知道計算機有一個理論模型——圖靈機。隨之而來的「圖靈機等價」的概念,讓人心智為之震撼。現在所有的計算設備,不管是強大的超級計算機還是玩具中幾毛錢的小小晶元,理論上都可以歸約為圖靈機,都是「圖靈機等價」的。它們本質上的計算能力都是一樣的,一個設備可以被另一個設備模擬,無非是算的快點慢點。計算機之外,分子生物學本質上就是計算機科學, DNA 控制生命體生成的過程類似圖靈機的運行,所以說,生命就是圖靈機(?)。神聖的人腦是不是也只是一個更複雜的圖靈機?很多人質疑,但也有很多人也相信是。有人甚至猜測,是不是萬物都是圖靈機?(有興趣的人可以看一下 Charles Petzold 的《Annotated Turing》,這本書後面有一章的標題就是 Is Everything a Turing Machine?)
有意思的是,還有兩個與圖靈機等價(甚至更優秀?)的計算機理論模型:lambda 演算;遞歸。。。函數(遞歸又出現了!)。這種等價性在上世紀三十年代得到了數學上的證明,是當時數學上的一個重要成就。這種等價性意味著,圖靈機具有的能力,遞歸函數也同樣有,前面說的圖靈機的種種,同樣適用於遞歸函數!
那麼,既然說圖靈機不局限於計算機,萬物都有可能是圖靈機,遞歸是不是也不局限於計算機,萬物中都有可能有遞歸現象?甚至,法律?
引子有點長,終於到達正題,下面說說兩個我見過的法律中的遞歸現象(可能還有更多)。
一、判斷公司股權是不是國有股
做中國境內公司法業務的律師都知道,這可是個十分重要的問題。公司股權一旦沾了國有色彩,與之有關的交易立刻籠罩著一種有毒的氛圍,讓參與者欲仙欲死。
但是長期以來,這個問題卻一直處於晦暗不明的狀態,有時讓一些有經驗的律師也拿不準。一些簡單的情況當然沒有任何疑問,比如三桶油各自總公司的股份,當然是國有股;但是一旦涉及到下層的子公司、孫公司、十八代孫公司,其中又混入了非國有投資,問題就變得不那麼 trivial 了。
我一直認為,這個問題讓人拿不準,除了因為法律法規的明文規定不夠清晰(在 2016 年的《企業國有資產交易監督管理辦法》出台後好多了),還在於判斷規則中有遞歸的影子,讓人們不太習慣。
判斷某股權是不是國有股,等同於判斷此股權的所有者是不是具有「國有資產所有者」的資格和屬性。那麼, 如何判斷某個主體是不是「國有資產所有者」呢?規則如下:
- 如果此主體本身就是國家(某級政府本身或者代表政府行權的行政部門等非企業單位),則是;
- 如果此主體的控股股東(所謂控股股東是指合計持股比例超過 50% 的一個或者多個股東,或者持股比例雖未超過 50% 但屬於第一大股東且可以實際支配此主體的股東)屬於按照本規則判斷的「國有資產所有者」,則是。
- 否則不是。
可以看到,規則第 2 步中調用了規則本身,屬於遞歸。
如果寫成python代碼,那就是:
def is_state_asset_owner(entity): if is_state_entity(entity): # 此主體是「國家單位」(政府或代其行權的非企業單位) return True else: # 是否有合計持股比例超過 50% 的股東都是按本函數確定的「國有資產所有者」 for shareholder_combination in shareholders_combinations_of(entity): if sum(share_percentage(shareholder, entity) for shareholder in shareholder_combination) > 50%: if all(is_state_asset_owner(shareholder) for shareholder in shareholder_combination): return True # 是否存在某一本身是國有資產所有者的股東,其持股比例雖未超過 50% 但屬於第一大股東,而且可以實際控制公司 for shareholder in all_shareholders_of(entity): if is_state_asset_owner(shareholder) and is_top_shareholder(shareholder, entity) and able_to_control(shareholder, entity): return True return False
這個函數中用到的大部分子函數都很平凡,顧名思義就好了,不具體實現了;但是 shareholders_combinations_of 這個函數特別,需要解釋一下。
為什麼要用它呢?因為規則里需要用到控股股東這個概念,同時規則允許控股股東可以是多個股東的集合。那麼就必須對全部股東進行各種可能的組合,對所有組合形成的股東集合作為可能的控股股東進行判斷(這麼說,這個演算法的複雜度還是 O(N!) 呢,N 為此主體的股東數量)。這個函數的 python 代碼如下:
import itertoolsdef shareholders_combinations_of(entity): combinations = [] all_shareholders = all_shareholders_of(entity) for combination_size in range(1, len(all_shareholders) + 1): combinations.extend(list(itertools.combinations(all_shareholders, combination_size))) return combinations
同時 is_top_shareholder 也實現一下:
def is_top_shareholder(shareholder, entity): all_shareholders = all_shareholders_of(entity) return share_percentage(shareholder, entity) >= max(all_shareholders, key=lambda x: share_percentage(x, entity))
以上規則和代碼並非我信口開河,立法者有法規條文為證:
《企業國有資產交易監督管理辦法》
第三條 本辦法所稱企業國有資產交易行為包括:
(一)履行出資人職責的機構、國有及國有控股企業、國有實際控制企業轉讓其對企業各種形式出資所形成權益的行為(以下稱企業產權轉讓);
(二)國有及國有控股企業、國有實際控制企業增加資本的行為(以下稱企業增資),政府以增加資本金方式對國家出資企業的投入除外;
(三)國有及國有控股企業、國有實際控制企業的重大資產轉讓行為(以下稱企業資產轉讓)。
第四條 本辦法所稱國有及國有控股企業、國有實際控制企業包括:
(一)政府部門、機構、事業單位出資設立的國有獨資企業(公司),以及上述單位、企業直接或間接合計持股為100%的國有全資企業;
(二)本條第(一)款所列單位、企業單獨或共同出資,合計擁有產(股)權比例超過50%,且其中之一為最大股東的企業;
(三)本條第(一)、(二)款所列企業對外出資,擁有股權比例超過50%的各級子企業;
(四)政府部門、機構、事業單位、單一國有及國有控股企業直接或間接持股比例未超過50%,但為第一大股東,並且通過股東協議、公司章程、董事會決議或者其他協議安排能夠對其實際支配的企業。
以上規則和代碼實際上翻譯了規定第四條的各項。不同的是,規定第四條的第(二)項與第(三)項實際可以合併,就合併處理了。
在頭腦里模擬運行一下上面的代碼,可以發現:對一個待判斷主體,會通過遞歸逐漸追溯到它的「根股東」。這實際上正是現實中律師做法律盡職調查時理清股權結構、進行股東溯源的過程。
二、判斷文物是不是可以合法交易的文物
即使不是律師或者潘家園古董販子或者馬親王伯庸,可能也會有點模糊的印象:文物是個特殊的東西,買賣受很多限制,很容易就成了違法交易。
但是說文物完全不能交易呢,好像也不是。那麼,什麼樣的文物可以合法交易?界限在哪裡?判斷規則是什麼?有意思的是,在這個判斷規則中,遞歸又出場了。
政府對文物交易的控制通過一定程度上的許可專營來實現,盡量把文物交易集中在經許可和監管的文物交易專門機構(文物商店或者拍賣行),在此之外的民間文物交易也不是完全禁止,但要求文物的來路必須正。
由此判斷一件文物是否可以合法交易的規則是:
- 國有和館藏的文物(即文物的所有者是國家或者文物收藏單位)不可交易。
- 文物交易專門機構(文物商店或者拍賣行)出售的文物視為可以合法交易的文物(當然前提是假設這些單位都守規矩)。
- 個人和其他單位的文物要合法交易,必須傳承有序有據。要麼是祖傳,要麼是從合法的前一手傳承(買賣、互換、受贈)而來(想通過先佔無主物原始取得文物所有權的人不用想了。就如同 49 年之後動物就不能成精一樣,49 年之後新發現的文物默認歸國家所有,不存在無主文物了,呵呵)。
那麼這裡就有一個問題:怎麼判斷是合法的前一手?也就是說怎麼判斷文物在前一手手中時是可以合法交易的?
仔細想想,那不就又回到了問題本身嗎?
解決的方法很簡單,就是調用這個規則本身!遞歸來拯救。
有人可能會問,這行嗎?這不是循環論證嗎?
並不是。
調用這個規則本身對前一手的合法性進行判斷,這個過程中可能又對前一手的前一手也觸發調用這個規則本身……似乎會無窮無盡。但是在這個鏈條的任何一個環節,如果能遇到 base condition(規則 1、規則 2 和規則 3 中的繼承情形),這個鏈條就會中止,直接得出一個是否合法的結果,這個結果逐級反饋到最外層的規則調用中,最終得到了對當前所有者的判斷結果。
所以,對循環論證的擔心是不必要的,這個方法是有效的。
再上 python 代碼:
def is_tradable_relic(relic, owner): if isinstance(owner, 文物收藏單位 or 國家): return False elif isinstance(owner, 文物商店 or 拍賣行): return True elif acquire_way(relic, owner) in legal_non_trading_ways: # 繼承等 return True else: prev_owner = previous_owner(relic, owner) return is_tradable_relic(relic, prev_owner)
同樣的有法規條文為證:
《文物保護法》
第五十條 文物收藏單位以外的公民、法人和其他組織可以收藏通過下列方式取得的文物:
(一)依法繼承或者接受贈與;
(二)從文物商店購買;
(三)從經營文物拍賣的拍賣企業購買;
(四)公民個人合法所有的文物相互交換或者依法轉讓;
(五)國家規定的其他合法方式。
文物收藏單位以外的公民、法人和其他組織收藏的前款文物可以依法流通。
第五十一條 公民、法人和其他組織不得買賣下列文物:
(一)國有文物,但是國家允許的除外;
(二)非國有館藏珍貴文物;
(三)國有不可移動文物中的壁畫、雕塑、建築構件等,但是依法拆除的國有不可移動文物中的壁畫、雕塑、建築構件等不屬於本法第二十條第四款規定的應由文物收藏單位收藏的除外;
(四)來源不符合本法第五十條規定的文物。
三、其他
待各位讀者發現並報告。。。
我發現,通過對這些規則的總結提煉和代碼化,自己對這些法律規定的理解也更加精確深入了,這也再次應了 Alan Perlis 的這句話:
You think you know when you learn, are more sure when you can write, even more when you can teach, but certain when you can program.
推薦閱讀:
※英國:臨床人工智慧數字革命一觸即發?
※阿里 A.I. Labs 三項重磅發布:開放語音後又開放 AR,還發了款路由器
※「可視化音樂」登場!讓你開始用眼睛「聽」音樂
※2017年科技行業最值得記憶的十大事件盤點
※如何看待「十年後手機會消失」這種言論?