2016-02-05 8 views
3

Я играю с формализацией сертифицированного регулярного выражения в Idris (я считаю, что та же проблема сохраняется в любом из методов теории доказательств, таких как Agda and Coq) m зациклился на том, как определить семантику операции дополнения. У меня есть следующий тип данных для представления семантики регулярных выражений:Формализация регулярных выражений с операцией дополнения

data InRegExp : List Char -> RegExp -> Type where 
InEps : InRegExp [] Eps 
InChr : InRegExp [ a ] (Chr a) 
InCat : InRegExp xs l -> 
     InRegExp ys r -> 
     zs = xs ++ ys -> 
     InRegExp zs (Cat l r) 
InAltL : InRegExp xs l -> 
      InRegExp xs (Alt l r) 
InAltR : InRegExp xs r -> 
      InRegExp xs (Alt l r) 
InStar : InRegExp xs (Alt Eps (Cat e (Star e))) -> 
      InRegExp xs (Star e) 
InComp : Not (InRegExp xs e) -> InRegExp xs (Comp e) 

Моя проблема заключается в представлении тип НЕВЫП конструктора, так как он имеет не строго положительное возникновение InRegExp в связи с использованием Not. Так как такие типы данных могут использоваться для определения функций без конца, они отбрасываются с помощью проверки завершения. Я хотел бы определить такую ​​семантику так, чтобы она была принята с помощью проверки окончания Idris.

Есть ли способ, которым я мог бы представить семантику операции дополнения без отрицательных вхождений InRegExp?

ответ

5

Вы можете взаимно определить NotInRegExp, что объясняет, что значит не распознавать регулярное выражение (я не проверял, является ли это допустимым синтаксисом).

data NotInRegExp : List Char -> RegExp -> Type where 
NotInEps : Not (xs = []) -> NotInRegExp xs Eps 
NotInChr : Not (xs = [ a ]) -> NotInRegExp xs (Chr a) 
NotInCat : (forall xs ys, zs = xs ++ ys -> 
      NotInRegExp xs l 
      + InRegExp xs l * NotInRegExp ys r) -> 
      NotInRegExp zs (Cat l r) 
etc... 

Затем вы должны быть в состоянии определить хорошую процедуру принятия решения:

check : (xs : List Char) (e : RegExp) -> Either (InRegexp xs e) (NotInRegexp xs e) 
+0

Спасибо. Вы абсолютно правы! Это простое и элегантное решение. –

+0

@RodrigoRibeiro FYI, я исправил ошибку в определении конструктора 'NotInCat', который я определил. – gallais

3

Вы также могли бы определить этот тип рекурсией по RegExp плюс некоторые индуктивного типа данных для семантики Star.

Я предполагаю, что он не будет взаимодействовать так же хорошо со встроенным шаблоном, но он будет иметь тот же принцип индукции.

+0

Извините, я не придерживаюсь вашей идеи. Вы говорите, что я должен определить «InRegExp» как функцию типа «RegEx -> Type» и определить индуктивный тип для звезды Kleene? –

+0

Функция типа «Список Char -> RegExp -> Type», но да – Saizan

+0

К сожалению ... Я имею в виду 'List Char -> RegExp -> Type' ... :) Спасибо за предложение. –

6

Вы можете определить InRegex путем рекурсии на Regex. В этом случае строгая положительность не проблема, но мы должны рекурсию структурно:

import Data.List.Quantifiers 

data Regex : Type where 
    Chr : Char -> Regex 
    Eps : Regex 
    Cat : Regex -> Regex -> Regex 
    Alt : Regex -> Regex -> Regex 
    Star : Regex -> Regex 
    Comp : Regex -> Regex 

InRegex : List Char -> Regex -> Type 
InRegex xs (Chr x)  = xs = x :: [] 
InRegex xs Eps   = xs = [] 
InRegex xs (Cat r1 r2) = (ys ** (zs ** (xs = ys ++ zs, InRegex ys r1, InRegex zs r2))) 
InRegex xs (Alt r1 r2) = Either (InRegex xs r1) (InRegex xs r2) 
InRegex xs (Star r) = (yss ** (All (\ys => InRegex ys r) yss, xs = concat yss)) 
InRegex xs (Comp r) = Not (InRegex xs r) 

Мы должны индуктивного типа для Star случае, если мы хотим использовать наше старое определение. Далее, очевидно, не работает:

InRegex xs (Star r) = InRegex (Alt Eps (Cat r (Star r))) 

Однако, мы можем просто изменить определение и сделать конечность явно:

InRegex xs (Star r) = (yss ** (All (\ys => InRegex ys r) yss, xs = concat yss)) 

Это имеет значение, а я не вижу никаких недостатков в Это.

+0

С помощью вашего определения '(a | b) *' интерпретируется как '(a *) | (b *)' (это потому, что 'xs = concat (replicate n ys)' требует, чтобы все подвыборки были идентичными) , – gallais

+0

К сожалению, спасибо. Ред. –

+2

Проблема с этим решением заключается в том, что 'All (flip InRegex r) yss' не принимается с помощью проверки завершения Idris. Есть ли способ обойти эту проблему, используя аналогичное решение? –

 Смежные вопросы

  • Нет связанных вопросов^_^