1
0
forked from GitHub/gf-core

embedded haskelle example: query

This commit is contained in:
aarne
2006-04-21 09:14:05 +00:00
parent fd70db2c9f
commit fa32f755d6
6 changed files with 224 additions and 3 deletions

View File

@@ -0,0 +1,45 @@
-- abstract syntax of a small arithmetic query language
abstract Database = {
cat
Query ; S ; Q ; NP ; CN ; PN ; A1 ; A2 ;
fun
QueryS : S -> Query ;
QueryQ : Q -> Query ;
PredA1 : NP -> A1 -> S ;
WhichA1 : CN -> A1 -> Q ;
WhichA2 : CN -> NP -> A2 -> Q ;
ComplA2 : A2 -> NP -> A1 ;
UseInt : Int -> NP ;
Every : CN -> NP ;
Some : CN -> NP ;
-- lexicon
Number : CN ;
Even,Odd,Prime : A1 ;
Equal,Greater,Smaller,Divisible : A2 ;
-- replies
cat Answer ; ListInt ;
fun
Yes,No : Answer ;
None : Answer ;
List : ListInt -> Answer ;
One : Int -> ListInt ;
Cons : Int -> ListInt -> ListInt ;
-- general moves
fun
Quit : Query ;
Bye : Answer ;
}

View File

@@ -0,0 +1,52 @@
--# -path=.:prelude
concrete DatabaseEng of Database = open Prelude in {
-- english query language
flags lexer=literals ; unlexer=text ;
-- concrete syntax; greatly simplified - just for test purposes
lin
QueryS s = s ;
QueryQ q = q ;
PredA1 np a = prefixSS "is" (cc2 np a) ;
WhichA1 n a = ss ("which" ++ n.s ++ "are" ++ a.s) ;
WhichA2 n q a = ss ("which" ++ n.s ++ "are" ++ q.s ++ a.s) ;
ComplA2 = cc2 ;
Every A = ss ("every" ++ A.s) ;
Some A = ss ("some" ++ A.s) ;
UseInt n = n ;
Number = ss "numbers" ;
Even = ss "even" ;
Odd = ss "odd" ;
Prime = ss "prime" ;
Equal = ss ("equal" ++ "to") ;
Greater = ss ("greater" ++ "than") ;
Smaller = ss ("smaller" ++ "than") ;
Divisible = ss ("divisible" ++ "by") ;
-- replies
lin
Yes = ss "yes" ;
No = ss "no" ;
None = ss "none" ;
List xs = xs ;
One n = n ;
Cons = cc2 ;
-- general moves
lin
Quit = ss "quit" ;
Bye = ss "bye" ;
}

15
examples/query/Makefile Normal file
View File

@@ -0,0 +1,15 @@
#GF=/users/mdstud/ltec06/GF
GF=/home/aarne/GF
all:
make gf ; make ghc
ghc:
ghc -fglasgow-exts --make UseDatabase.hs -o query ; strip query
gf:
echo "pg -printer=haskell | wf GSyntax.hs ;; pm | wf database.gfcm" | gf DatabaseEng.gf
link:
ln -s $(GF)/src/GF
ln -s $(GF)/src/Transfer
# export GF_LIB_PATH=$(GF)/lib
clean:
rm *.hi *.o

22
examples/query/README Normal file
View File

@@ -0,0 +1,22 @@
Aarne Ranta 6/5/2004; revised 10/5/2005 for GF 2.2, 21/4/2006 for GF 2.5.
An example of database query system for Lab 2 of language technology course.
To compile:
Create a link to GF sources, by
make link
Create the file GSyntax.hs and the executable query
make
To run:
./query
Examples:
is 4567 prime
which numbers are prime

View File

@@ -0,0 +1,85 @@
module Main where
import GSyntax
import GF.Embed.EmbedAPI
import GF.Infra.UseIO
-- to compile: make
main :: IO ()
main = do
gr <- file2grammar "database.gfcm"
loop gr
loop :: MultiGrammar -> IO ()
loop gr = do
putStrFlush "> "
s <- getLine
let ts = parse gr "DatabaseEng" "Query" s
case ts of
[t] -> case fg t of
GQuit -> putStrLnFlush (linearize gr "DatabaseEng" (gf GBye)) >> return ()
t' -> case reply t' of
Left r -> (putStrLnFlush $ linearize gr "DatabaseEng" $ gf r) >> loop gr
Right xs -> print xs >> loop gr
[] -> putStrLnFlush "no parse" >> loop gr
_ -> do
putStrLnFlush "ambiguous parse:"
---- mapM_ (putStrLn . prGFTree) ts
loop gr
-- the question-answer relation
reply :: GQuery -> Either GAnswer [Ent]
reply (GQueryS s) = Left $ if (iS s) then GYes else GNo
reply (GQueryQ q) = case iQ q of
[] -> Left GNone
xs -> Right xs
{- much less efficient:
xs -> GList $ list xs
where
list [x] = GOne (GInt (show x))
list (x:xs) = GCons (GInt (show x)) (list xs)
-}
-- denotational semantics
type Ent = Integer
type Prop = Bool
domain :: [Ent]
domain = [0..10000] ---
primes = sieve (drop 2 domain) where
sieve (p:x) = p : sieve [ n | n <- x, n `mod` p > 0 ]
sieve [] = []
iS :: GS -> Prop
iS (GPredA1 np ap) = iNP np (iA1 ap)
iQ :: GQ -> [Ent]
iQ (GWhichA1 cn a) = [e | e <- iCN cn, iA1 a e]
iQ (GWhichA2 cn np a) = [e | e <- iCN cn, iNP np (\x -> iA2 a x e)]
iA1 :: GA1 -> Ent -> Prop
iA1 (GComplA2 f q) = iNP q . iA2 f
iA1 GEven = even
iA1 GOdd = odd
iA1 GPrime = flip elem primes
iA2 :: GA2 -> Ent -> Ent -> Prop
iA2 GEqual = (==)
iA2 GGreater = (>)
iA2 GSmaller = (<)
iA2 GDivisible = \x y -> y /= 0 && mod x y == 0
iCN :: GCN -> [Ent]
iCN GNumber = domain
iNP :: GNP -> (Ent -> Prop) -> Prop
iNP (GEvery cn) p = all p (iCN cn)
iNP (GSome cn) p = any p (iCN cn)
iNP (GUseInt (GInt n)) p = p n

View File

@@ -50,9 +50,11 @@ haskPreamble =
"class Gf a where gf :: a -> Trm",
"class Fg a where fg :: Trm -> a",
"",
predefInst "String" "K s",
predefInst "GString" "String" "K s",
"",
predefInst "Int" "EInt s",
predefInst "GInt" "Integer" "EInt s",
"",
predefInst "GFloat" "Double" "EFloat s",
"",
"----------------------------------------------------",
"-- below this line machine-generated",
@@ -60,7 +62,7 @@ haskPreamble =
""
]
predefInst typ patt = let gtyp = gId typ in
predefInst gtyp typ patt =
"newtype" +++ gtyp +++ "=" +++ gtyp +++ typ +++ " deriving Show" +++++
"instance Gf" +++ gtyp +++ "where" ++++
" gf (" ++ gtyp +++ "s) =" +++ patt +++++