2014-03-26 41 views
1

所以基本上我使用此代碼檢查字符串:如何使用Prolog檢查某些strA是strB的子字符串?

substring(X,S) :- append(_,T,S), append(X,_,T), X \= []. 

和我的輸入是這樣的:

但是當我使用SWI-Prolog的跟蹤這段代碼,我發現這一點:

substring([99, 109, 112], cmp(eax, 4)) 

,顯然它失敗...

所以任何人都可以給米有些幫助嗎?

+0

您的代碼爲我工作。嘗試'substring(「cmp」,「cmp(eax,4)」)。問題是你實例化Ins的地方是「cmp(eax,4)」。 –

+3

停在那裏並更改您的數據表示。將彙編指令表示爲字符串並使用substring/2進行分析是嚴重不適當的。 – jschimpf

回答

0

SWI-Prolog將recently changed傳統的字符串文字視爲「代碼列表」,以更高效的內存表示(從版本7開始)。

因此(除其他外更難以解釋),append/3不再適用於您的任務,除非您明確地將其轉換爲代碼列表。

根據上下文,很多內建的相繼出臺,像sub_string/5:例如,嘗試

?- sub_string("cmp(eax, 4)", Start,Len,Stop, "eax"). 
Start = Stop, Stop = 4, 
Len = 3 
+0

從問題中的追蹤 - 「cmp」變成[99,109,112],因此它是主題啓動器系統上的代碼列表。 –

+0

我知道,這個問題有點模糊......也許之前回答我應該查詢版本等... – CapelliC

0

使該字符串形式cmp(eax, 4)的一個術語。在此,在Prolog的行話來說,您有:

  • 術語cmp(eax, 4)
  • 用算符cmp/2
  • 與第一參數中的原子eax
  • 和第二參數中的整數4

現在您已經有了一個術語,您可以在謂詞(統一)的頭部使用模式匹配來編寫謂詞,如:

apply_instruction(cmp(Reg, Operand) /*, other arguments as needed */) :- 
    /* do the comparison of the contents of _Reg_ and the values in _Operand_ */ 
apply_instruction(add(Reg, Addend) /*, other arguments */) :- 
    /* add _Addend_ to _Reg_ */ 
% and so on 

如何從您的輸入中創建一個術語:有許多方法,最簡單的方法是閱讀完整的一行(取決於您使用的Prolog實現,在SWI-Prolog中,假設您有輸入流在):

read_line_to_codes(In, Line). 

,然後使用DCG解析它。一個DCG看起來可能像:

instruction(cmp(Op1, Op2)) --> 
    "cmp", 
    ops(Op1, Op2). 

instruction(add(Op1, Op2) --> 
    "add", 
    ops(Op1, Op2). 

ops(Op1, Op2) --> 
    space, 
    op1(Op1), optional_space, 
    ",", optional_space, 
    op2(Op2), 
    space_to_eol. 

% and so on 

然後可以使用phrase/2的DCG適用於您已經閱讀行:

phrase(instruction(Instr), Line). 
相關問題