2014-09-28 12 views
5

Tôi đã viết một số mã trong Haskell để mô hình hóa logic mệnh đềMở rộng logic mệnh đề để modal logic trong Haskell

data Formula = Prop {propName :: String} 
      | Neg Formula 
      | Conj Formula Formula 
      | Disj Formula Formula 
      | Impl Formula Formula 
      | BiImpl Formula Formula 
    deriving (Eq,Ord) 

Tuy nhiên, không có cách nào tự nhiên để mở rộng này để phương thức logic, vì kiểu dữ liệu được đóng lại. Vì vậy, tôi nghĩ tôi nên sử dụng các lớp học thay thế. Bằng cách đó, tôi có thể dễ dàng thêm các tính năng ngôn ngữ mới trong các mô-đun khác nhau sau này. Vấn đề là tôi không biết chính xác cách viết nó. Tôi muốn một cái gì đó như sau

type PropValue = (String,Bool) -- for example ("p",True) states that proposition p is true 
type Valuation = [PropValue]  

class Formula a where 
    evaluate :: a -> Valuation -> Bool 

data Proposition = Prop String 

instance Formula Proposition where 
    evaluate (Prop s) val = (s,True) `elem` val 

data Conjunction = Conj Formula Formula -- illegal syntax 

instance Formula Conjunction where 
    evaluate (Conj φ ψ) v = evaluate φ v && evaluate ψ v 

Sai lầm là tất nhiên trong định nghĩa của Liên từ. Tuy nhiên, không rõ ràng với tôi làm thế nào tôi có thể viết lại nó để nó hoạt động.

+3

Nếu bạn thích đọc sách, bạn có thể tìm thấy [này] (http://okmij.org/ftp/tagless-final/course/lecture .pdf) hữu ích. – user2407038

Trả lời

5

này nên làm việc:

data Conjunction f = Conj f f 

instance Formula f => Formula (Conjunction f) where 
    evaluate (Conj φ ψ) v = evaluate φ v && evaluate ψ v 

Tuy nhiên, tôi không phải các lớp học kiểu chắc chắn là công cụ phù hợp với những gì bạn đang cố gắng để đạt được.


Có lẽ bạn có thể cung cấp một whirl để sử dụng functors cấp loại rõ ràng và định kỳ qua chúng:

-- functor for plain formulae 
data FormulaF f = Prop {propName :: String} 
      | Neg f 
      | Conj f f 
      | Disj f f 
      | Impl f f 
      | BiImpl f f 

-- plain formula 
newtype Formula = F {unF :: FormulaF Formula} 

-- functor adding a modality 
data ModalF f = Plain f 
      | MyModality f 
-- modal formula 
newtype Modal = M {unM :: ModalF Modal} 

Vâng, đây không phải là terribly tiện lợi vì nhà xây dựng như F,M,Plain có được đôi khi trong đường đi. Tuy nhiên, không giống như các loại lớp, bạn có thể sử dụng mẫu khớp tại đây.


Như một tùy chọn, sử dụng một GADT:

data Plain 
data Mod 
data Formula t where 
    Prop {propName :: String} :: Formula t 
    Neg :: Formula t -> Formula t 
    Conj :: Formula t -> Formula t -> Formula t 
    Disj :: Formula t -> Formula t -> Formula t 
    Impl :: Formula t -> Formula t -> Formula t 
    BiImpl :: Formula t -> Formula t -> Formula t 
    MyModality :: Formula Mod -> Formula Mod 

type PlainFormula = Formula Plain 
type ModalFormula = Formula Mod 
+0

Cảm ơn bạn, giải pháp đầu tiên của bạn dường như hoạt động. Tuy nhiên, tôi cũng sẽ xem xét các giải pháp khác của bạn vì tôi tin rằng bối cảnh loại dữ liệu sẽ không còn được dùng nữa trong tương lai gần, xem https://stackoverflow.com/questions/7438600/datatypecontexts-deprecated-in-latest-ghc- tại sao. GADT dường như không phải là giải pháp tôi cần, vì tôi muốn có thể xác định các toán tử khác nhau trong các mô-đun khác nhau. Ví dụ, toán tử Conj và Disj trong PropLogic.hs, toán tử Box trong ModalLogic.hs và định lượng ForAll trong PredLogic.hs. – Jetze

+3

@Anonymous kiểu dữ liệu bối cảnh thực sự là tránh được, nhưng tôi đã không sử dụng chúng (cũng không phải bạn đã làm). Các ngữ cảnh này là những ngữ cảnh như trong 'dữ liệu (Ord a) => Set a = ...'. Các ngữ cảnh xuất hiện trong 'class' hoặc' instance' không phải là ngữ cảnh kiểu dữ liệu và sẽ không biến mất. – chi