การอนุมานประเภท + การบรรทุกเกินพิกัด


9

ฉันกำลังมองหาอัลกอริทึมการอนุมานแบบสำหรับภาษาที่ฉันกำลังพัฒนา แต่ฉันไม่พบสิ่งที่ตรงกับความต้องการของฉันเพราะพวกเขามักจะเป็น:

  • à la Haskell ด้วยความหลากหลาย แต่ไม่มีโฆษณามากเกินไป
  • à la C ++ (อัตโนมัติ) ที่คุณมีการโหลดมากเกินไปแบบ ad-hoc แต่ฟังก์ชั่นเป็น monomorphic

โดยเฉพาะอย่างยิ่งระบบพิมพ์ของฉันคือ (ลดความซับซ้อน) (ฉันใช้ไวยากรณ์ Haskellish แต่นี่คือภาษาที่ไม่เชื่อเรื่องพระเจ้า):

data Type = Int | Double | Matrix Type | Function Type Type

และฉันมีโอเปอเรเตอร์ * ซึ่งมีโอเวอร์โหลดค่อนข้างมาก

Int -> Int -> Int
(Function Int Int) -> Int -> Int
Int -> (Function Int Int) -> (Function Int Int)
(Function Int Int) -> (Function Int Int) -> (Function Int Int)
Int -> Matrix Int -> Matrix Int
Matrix Int -> Matrix Int -> Matrix Int
(Function (Matrix Int) (Matrix Int)) -> Matrix Int -> Matrix Int

ฯลฯ ...

และฉันต้องการสรุปประเภทที่เป็นไปได้สำหรับ

(2*(x => 2*x))*6
(2*(x => 2*x))*{{1,2},{3,4}}

ครั้งแรกเป็นที่สองIntMatrix Int

ตัวอย่าง (ที่ใช้งานไม่ได้):

{-# LANGUAGE OverlappingInstances, MultiParamTypeClasses,
  FunctionalDependencies, FlexibleContexts,
  FlexibleInstances, UndecidableInstances #-}

import qualified Prelude
import Prelude hiding ((+), (*))
import qualified Prelude

newtype WInt = WInt { unwrap :: Int }

liftW f a b = WInt $ f (unwrap a) (unwrap b)

class Times a b c | a b -> c where
(*) :: a -> b -> c

instance Times WInt WInt WInt where
(*) = liftW (Prelude.*)

instance (Times a b c) => Times a (r -> b) (r -> c) where
x * g = \v -> x * g v

instance Times (a -> b) a b where
f * y = f y

two = WInt 2
six = WInt 6

test :: WInt
test = (two*(\x -> two*x))*six

main = undefined

3
สิ่งนี้ไม่ตรงกับเกณฑ์สำหรับ CS Theory Stack Exchange แต่ดูเหมือนว่าคุณกำลังมองหาคำตอบทางคณิตศาสตร์หรือทฤษฎีเพิ่มเติม ฉันคิดว่าวิทยาศาสตร์คอมพิวเตอร์อาจเหมาะกับสิ่งนี้ เนื่องจากคุณขอให้มีการเคลื่อนไหวเพื่อรับคำตอบที่ดีกว่าฉันจะส่งไปยังที่ที่ได้รับการตอบรับดี
Thomas Owens

คำตอบ:


9

ฉันอยากจะแนะนำให้ดูที่วิทยานิพนธ์ของ Geoffrey Seward Smith

ดังที่คุณอาจทราบแล้วว่าวิธีการทำงานของการอนุมานประเภททั่วไปคือพวกมันสำรวจแผนผังต้นไม้และทุก ๆ subexpression ที่สร้างข้อ จำกัด ประเภท จากนั้นพวกเขาจะใช้ข้อ จำกัด นี้เชื่อมโยงระหว่างพวกเขาและแก้ปัญหาพวกเขา (มักจะมองหาวิธีการแก้ปัญหาทั่วไปที่สุด)

เมื่อคุณมีการรับน้ำหนักมากเกินไปเมื่อทำการวิเคราะห์โอเปอเรเตอร์ที่มีการโอเวอร์โหลดคุณจะสร้างข้อ จำกัด หลายประเภทแทนที่จะเป็นหนึ่งตัว เพราะคุณบอกว่าโอเปอเรเตอร์สามารถมี `` อย่างนี้หรือนี่หรือแบบนั้นก็ได้ 'ถ้ามันไม่ จำกัด เราจำเป็นต้องหันไปหาปริมาณสากลเช่นเดียวกับชนิด polymorphic แต่มีข้อ จำกัด เพิ่มเติมที่ จำกัด จริง ประเภทการบรรทุกเกินพิกัดกระดาษที่ฉันอ้างอิงครอบคลุมหัวข้อเหล่านี้ในเชิงลึกมากขึ้น


ขอบคุณมากนี่คือคำตอบที่ฉันกำลังมองหา
miniBill

7

ผิดปกติพอ Haskell ตัวเองเป็นดีที่สุดที่ เกือบมีความสามารถในตัวอย่างของคุณ; Hindley-Milner นั้นใช้ได้ดีกับการบรรทุกเกินพิกัดตราบใดที่มีขอบเขต จำกัด :

{-# LANGUAGE OverlappingInstances, MultiParamTypeClasses,
             FunctionalDependencies, FlexibleContexts,
             FlexibleInstances #-}
import Prelude hiding ((*))

class Times a b c | a b -> c where
    (*) :: a -> b -> c

instance Times Int Int Int where
    (*) = (Prelude.*)

instance Times Double Double Double where
    (*) = (Prelude.*)

instance (Times a b c) => Times (r -> a) (r -> b) (r -> c) where
    f * g = \v -> f v * g v

instance (Times a b c) => Times a (r -> b) (r -> c) where
    x * g = \v -> x * g v

instance (Times a b c) => Times (r -> a) b (r -> c) where
    f * y = \v -> f v * y

type Matrix a = (Int, Int) -> a

คุณทำเสร็จแล้ว! ดียกเว้นว่าคุณต้องการเริ่มต้น หากภาษาของคุณอนุญาตให้เริ่มต้นTimesคลาสเป็นInt(และจากนั้นDouble) ตัวอย่างของคุณจะทำงานตรงตามที่ระบุไว้ วิธีอื่น ๆ ที่จะแก้ไขได้แน่นอนคือการไม่ส่งเสริมโดยอัตโนมัติIntไปDoubleหรือเพียงทำมันเมื่อมีความจำเป็นในทันทีและจะใช้Intตัวอักษรเป็นIntเพียง (อีกครั้งส่งเสริมเฉพาะเมื่อจำเป็นทันที); วิธีนี้จะใช้งานได้


2
ขอบคุณมาก! (แม้ว่าจำนวนส่วนขยายจะมากกว่า 9k)
miniBill

1
ไม่ทำงานideone.com/s9rSi7
miniBill

1
ไม่ใช่ปัญหาการเริ่มต้น: ideone.com/LrfEjX
miniBill

1
โอ้ขอโทษฉันเข้าใจคุณผิดแล้ว ดีฉันไม่ต้องการเริ่มต้น (ฉันคิดว่า) ..
miniBill

2
คุณลองสร้างตัวอย่างที่รวบรวมได้ไหม
miniBill
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.