Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
6494ad439This file is pinned to the selected release. Download the original to open it in your design tool.
{
inc i = (+) i 1 ;
dec i = (-) i 1 ;
dis True q = True ;
dis False q = q ;
con True q = q ;
con False q = False ;
not True = False ;
not False = True ;
non f x = not (f x) ;
isNothing Nothing = True ;
isNothing (Just x) = False ;
isJust Nothing = False ;
isJust (Just x) = True ;
fromJust (Just x) = x ;
maybe n j Nothing = n ;
maybe n j (Just x) = j x ;
fst (Pair x y) = x ;
snd (Pair x y) = y ;
id x = x ;
curry f x y = f (Pair x y) ;
uncurry f (Pair x y) = f x y ;
flip f x y = f y x ;
cross f g (Pair x y) = Pair (f x) (g y) ;
both p (Pair x y) = con (p x) (p y) ;
null [] = True ;
null (Cons x xs) = False ;
head (Cons x xs) = x ;
tail (Cons x xs) = xs ;
append [] ys = ys ;
append (Cons x xs) ys = Cons x (append xs ys) ;
map f [] = [] ;
map f (Cons x xs) = Cons (f x) (map f xs) ;
concatMap f [] = [] ;
concatMap f (Cons x xs) = append (f x) (concatMap f xs) ;
elemBy e x [] = False ;
elemBy e x (Cons y ys) = case e x y of { True -> True ; False -> elemBy e x ys ; } ;
elemAt (Cons x xs) n = case (==) n 0 of {
True -> x ;
False -> elemAt xs (dec n) ;
} ;
filter p [] = [] ;
filter p (Cons x xs) = case p x of {
True -> Cons x (filter p xs) ;
False -> filter p xs ;
} ;
foldr f z [] = z ;
foldr f z (Cons x xs) = f x (foldr f z xs) ;
zipWith f [] [] = [] ;
zipWith f [] (Cons y ys) = [] ;
zipWith f (Cons x xs) [] = [] ;
zipWith f (Cons x xs) (Cons y ys) = Cons (f x y) (zipWith f xs ys) ;
zip = zipWith Pair ;
unlines [] = "" ;
unlines (Cons s ss) = append s (Cons '\n' (unlines ss)) ;
emitStr [] k = k ;
emitStr (Cons c cs) k = emit c (emitStr cs k) ;
length [] = 0 ;
length (Cons x xs) = inc (length xs) ;
repeat x = Cons x (repeat x) ;
last (Cons x xs) = case null xs of {
True -> x ;
False -> last xs ;
} ;
enumFromTo m n = case (<=) m n of {
True -> Cons m (enumFromTo (inc m) n) ;
False -> [] ;
} ;
plus a b = (+) a b;
sum xs = foldr plus 0 xs ;
concatStrings ss = foldr append "" ss ;
and xs = foldr con True xs ;
all p xs = and (map p xs) ;
unionBy e xs ys = foldr (insBy e) xs ys ;
insBy e x ys = case elemBy e x ys of { True -> ys ; False -> Cons x ys ; } ;
intersperse i [] = [] ;
intersperse i (Cons x []) = Cons x [] ;
intersperse i (Cons x (Cons y ys)) = Cons x (Cons i (intersperse i (Cons y ys))) ;
nubBy e xs = nubBySans [] e xs ;
nubBySans ss e [] = [] ;
nubBySans ss e (Cons x xs) = case elemBy e x ss of {
True -> nubBySans ss e xs ;
False -> Cons x (nubBySans (Cons x ss) e xs) ;
} ;
lookUpBy e x [] = Nothing ;
lookUpBy e x (Cons (Pair y v) yvs) = case e x y of {
True -> Just v ;
False -> lookUpBy e x yvs ;
} ;
equalStrings [] [] = True ;
equalStrings [] (Cons y ys) = False ;
equalStrings (Cons x xs) [] = False ;
equalStrings (Cons x xs) (Cons y ys) = con ((==) x y) (equalStrings xs ys) ;
showResult (Just trs) sig = append "\nSuccess\n" (showRules sig (map rn trs)) ;
showResult Nothing sig = "\nFailure\n" ;
varWeight (Weights vw fws) = vw ;
funWeight (Weights vw fws) f = fromJust (lookUpBy equalStrings f fws) ;
funSequence (Weights vw fws) = map fst fws ;
weights = Weights 1 (Cons (Pair "0" 1) (Cons (Pair "+" 0) (Cons (Pair "-" 0) []))) ;
order = kbGreaterThan weights ;
arity sig f = maybe ((-) 0 1) fst (lookUpBy equalStrings f sig) ;
isInfix sig f = maybe False snd (lookUpBy equalStrings f sig) ;
main =
let {
sig = Cons (Pair "+" (Pair 2 True)) (
Cons (Pair "-" (Pair 1 False)) (
Cons (Pair "0" (Pair 0 False)) [] )) ;
eqns = Cons (Pair (Fun "+" (Cons (Fun "0" []) (Cons (Var "X") [])))
(Var "X")) (
Cons (Pair (Fun "+" (Cons (Fun "-" (Cons (Var "X") []))
(Cons (Var "X") []) ))
(Fun "0" [])) (
Cons (Pair (Fun "+" (Cons (Fun "+" (Cons (Var "X")
(Cons (Var "Y") [])))
(Cons (Var "Z") []) ))
(Fun "+" (Cons (Var "X")
(Cons (Fun "+" (Cons (Var "Y")
(Cons (Var "Z") []))) []) )))
[] )) ;
} in
case checkEquations eqns sig of {
True -> emitStr "Using equations:\n"
(emitStr (showEqns sig eqns)
(emitStr (showResult (complete sig eqns) sig) 0)) ;
False -> emitStr "Ill-formed equation\n" 0 ;
} ;
checkEquations es sig = all (both (checkTerm sig)) es ;
checkTerm sig (Var v) = True ;
checkTerm sig (Fun f ts) = con ((==) (length ts) (arity sig f))
(all (checkTerm sig) ts) ;
rn (Pair l r) = let { sub = zip (vars l) (map Var variables); }
in Pair (subst sub l) (subst sub r) ;
zipWithRemRight f [] [] = Pair [] [] ;
zipWithRemRight f [] (Cons y ys) = Pair [] (Cons y ys) ;
zipWithRemRight f (Cons x xs) [] = Pair [] [] ;
zipWithRemRight f (Cons x xs) (Cons y ys) =
case zipWithRemRight f xs ys of {
Pair rest rem -> Pair (Cons (f x y) rest) rem ;
} ;
renameNew vs (Pair l r) =
case zipWithRemRight (curry (cross id Var)) (vars l) vs of {
Pair sub rest -> Pair (Pair (subst sub l) (subst sub r)) rest ;
} ;
renameNewList vs [] = Pair [] vs ;
renameNewList vs (Cons r rs) =
case renameNew vs r of {
Pair renamedr remainingvs ->
case renameNewList remainingvs rs of {
Pair rest remainder -> Pair (Cons renamedr rest) remainder ;
} ;
} ;
complete sig trs = completionLoop sig variables 0 trs [] ;
completionLoop sig vs n [] rules = Just rules ;
completionLoop sig vs n (Cons p rest) rules =
case (==) n 1000 of {
True -> Nothing ;
False -> case renameNew vs p of {
Pair newEqn ws ->
case orient newEqn of {
Nothing -> Nothing ;
Just newRule ->
completionWith sig ws (inc n) rest newRule rules ;
} ;
} ;
} ;
completionWith sig vs n rest newRule rules =
let { cps = getCriticalPairs (Cons newRule rules) newRule ; }
in case simplifyRules sig newRule rules of {
Pair eqs rls -> completionLoop sig vs n
(simplifyEquations sig
(Cons newRule rules)
(append rest (append eqs cps)))
(uniqueRules rls) ;
} ;
orient (Pair t1 t2) = case order t1 t2 of {
True -> Just (Pair t1 t2) ;
False -> case order t2 t1 of {
True -> Just (Pair t2 t1) ;
False -> Nothing ;
} ;
} ;
getCriticalPairs trs r =
append (selfCriticalPairs trs r) (concatMap (duoCriticalPairs trs r) trs) ;
simplifyRules sig rule trs =
case reduceSplit sig rule trs of {
Pair newEqns remainingRules ->
Pair newEqns
(uniqueRules (map (normRhs (Cons rule remainingRules))
(Cons rule remainingRules) )) ;
} ;
normRhs trs (Pair l r) = Pair l (norm trs r) ;
simplifyEquations sig trs eqns =
filter (non (uncurry equalTerms))
(uniqueRules (map (normEqn trs) eqns)) ;
normEqn trs (Pair l r) = Pair (norm trs l) (norm trs r) ;
reduceSplit sig rule [] = Pair [] [] ;
reduceSplit sig rule (Cons (Pair l r) rs) =
let { reducedl = reduce (Cons rule []) l ; } in
case reduceSplit sig rule rs of {
Pair eqns rules ->
case dis (null reducedl)
(reducible (Cons (Pair l r) []) (left rule)) of {
True -> Pair eqns
(Cons (Pair l r) rules) ;
False -> Pair (Cons (Pair (head reducedl) r) eqns)
rules ;
} ;
} ;
selfCriticalPairs trs (Pair l1 r1) =
criticalPairs trs False (Pair l1 r1) (rename (Pair l1 r1)) ;
duoCriticalPairs trs (Pair l1 r1) (Pair l2 r2) =
append (criticalPairs trs True (Pair l1 r1) (Pair l2 r2))
(criticalPairs trs False (Pair l2 r2) (Pair l1 r1)) ;
criticalPairs trs allowRootPos (Pair l1 r1) (Pair l2 r2) =
let { ps = case allowRootPos of {
True -> positions l1 ;
False -> filter (non null) (positions l1) ;
} ;
}
in concatMap (criticalPairsAt trs (Pair l1 r1) (Pair l2 r2)) ps ;
criticalPairsAt trs (Pair l1 r1) (Pair l2 r2) p =
let { t = subterm l1 p ; }
in case isVar t of {
True -> [] ;
False -> case unify t l2 of {
Nothing -> [] ;
Just sub -> criticalPairsFrom
(norm trs (subst sub r1))
(norm trs (placeAt (subst sub r2) p (subst sub l1))) ;
} ;
} ;
criticalPairsFrom cpl cpr = case equalTerms cpl cpr of {
True -> [] ;
False -> Cons (Pair cpl cpr) [] ;
} ;
rename (Pair l r) =
let { oldVars = vars l ;
newVars = map Var (filter (non (flip (elemBy equalStrings) oldVars)) variables) ;
sub = zip oldVars newVars ; }
in Pair (subst sub l) (subst sub r) ;
leq a b = (<=) a b;
eq a b = (==) a b;
kbGreaterThan w t s =
let { vs = unionBy equalStrings (vars t) (vars s) ;
wt = termWeight w t ;
ws = termWeight w s ;
nt = map snd (varCounts t vs) ;
ns = map snd (varCounts s vs) ; }
in dis (con (not ((<=) wt ws)) (compareAll leq ns nt))
(con (con ((==) wt ws) (compareAll eq nt ns))
(dis (powerOf (last (funSequence w)) t s)
(funcAfter w t s) )) ;
termWeight w (Var v) = varWeight w ;
termWeight w (Fun f ts) = (+) (funWeight w f) (sum (map (termWeight w) ts)) ;
powerOf fn (Var v) u = False ;
powerOf fn (Fun f []) u = False ;
powerOf fn (Fun f (Cons x xs)) u = con (con (isVar u) (equalStrings f fn))
(con (null xs) (pow fn x)) ;
pow fn (Var v) = True ;
pow fn (Fun f (Cons z zs)) = con (equalStrings f fn)
(con (null zs) (pow fn z)) ;
funcAfter w (Var v) (Var x) = False ;
funcAfter w (Var v) (Fun g us) = False ;
funcAfter w (Fun f ts) (Var x) = False ;
funcAfter w (Fun f ts) (Fun g us) =
case equalStrings f g of {
True -> orderLex (kbGreaterThan w) ts us ;
False -> before (funSequence w) g f ;
} ;
compareAll f xs ys = and (zipWith f xs ys) ;
varCounts t vs = foldr tally (zip vs (repeat 0)) (concatMap (varAt t) (positions t)) ;
varAt t p = case subterm t p of {
Var v -> Cons v [] ;
Fun f ts -> [] ;
} ;
tally k [] = [] ;
tally k (Cons (Pair x nx) xs) = case equalStrings k x of {
True -> Cons (Pair x (inc nx)) xs ;
False -> Cons (Pair x nx) (tally k xs) ;
} ;
orderLex f [] [] = False ;
orderLex f [] (Cons y ys) = False ;
orderLex f (Cons x xs) [] = False ;
orderLex f (Cons x xs) (Cons y ys) = case equalTerms x y of {
True -> orderLex f xs ys ;
False -> f x y ;
} ;
before (Cons h t) x y = dis (equalStrings h x)
(con (not (equalStrings h y))
(before t x y)) ;
showTerm sig (Var v) = v ;
showTerm sig (Fun f ts) =
case isInfix sig f of {
True -> append "("
( append (showTerm sig (elemAt ts 0))
( append " " (append f (append " "
( append (showTerm sig (elemAt ts 1))
")" ))))) ;
False -> case null ts of {
True -> f ;
False -> append f
( append "("
( append (concatStrings (intersperse "," (map (showTerm sig) ts)))
")" )) ;
} ;
} ;
showEqn sig (Pair x y) = append (showTerm sig x) (append " = " (showTerm sig y)) ;
showEqns sig eqns = unlines (map (showEqn sig) eqns) ;
showRule sig (Pair x y) = append (showTerm sig x) (append " -> " (showTerm sig y)) ;
showRules sig rules = unlines (map (showRule sig) rules) ;
left = fst ;
right = snd ;
uniqueRules = nubBy equivPair ;
equivPair (Pair a b) (Pair c d) =
dis (con (equiv a c) (equiv b d)) (con (equiv a d) (equiv b c)) ;
unify t1 t2 = unifyWith (Cons t1 []) (Cons t2 []) [] ;
unifyWith [] [] sub = Just sub ;
unifyWith (Cons (Var v) ts1) (Cons t ts2) sub =
let { ti = subst sub t ;
vi = subst sub (Var v) ;
mgu = unify vi ti ; } in
case equalTerms t (Var v) of {
True -> unifyWith ts1 ts2 sub ;
False -> case equalTerms vi (Var v) of {
True -> case elemBy equalStrings v (vars ti) of {
True -> Nothing ;
False -> unifyWith ts1 ts2 (substAdd (Cons (Pair v ti) []) sub) ;
} ;
False -> case isJust mgu of {
True -> unifyWith ts1 ts2 (substAdd (fromJust mgu) sub) ;
False -> Nothing ;
} ;
} ;
} ;
unifyWith (Cons (Fun f ts) ts1) (Cons t ts2) sub =
case t of {
Var v -> unifyWith (Cons (Var v) ts2) (Cons (Fun f ts) ts1) sub ;
Fun g us -> case equalStrings f g of {
True -> unifyWith (append ts ts1) (append us ts2) sub ;
False -> Nothing ;
} ;
} ;
substAdd subNew subOld = append subNew (map (cross id (subst subNew)) subOld) ;
match t1 t2 = matchWith (Cons t1 []) (Cons t2 []) [] ;
matchWith [] [] sub = Just sub ;
matchWith (Cons (Var v) ts1) (Cons t ts2) sub =
case elemBy equalStrings v (map fst sub) of {
True -> case equalTerms t (subst sub (Var v)) of {
True -> matchWith ts1 ts2 sub ;
False -> Nothing ;
} ;
False -> matchWith ts1 ts2 (Cons (Pair v t) sub) ;
} ;
matchWith (Cons (Fun f ts) ts1) (Cons t ts2) sub =
case t of {
Var v -> Nothing ;
Fun g us -> case equalStrings f g of {
True -> matchWith (append ts ts1) (append us ts2) sub ;
False -> Nothing ;
} ;
} ;
normalForms trs t =
let { reduced = reduce trs t ; } in
case null reduced of {
True -> Cons t [] ;
False -> concatMap (normalForms trs) reduced ;
} ;
norm trs t = head (normalForms trs t) ;
reducible trs t = not (null (reduce trs t)) ;
reduce trs t = concatMap (reduceAt trs t) (positions t) ;
reduceAt trs t p =
case isVar (subterm t p) of {
True -> [] ;
False -> concatMap (reduceAtWith t p) trs ;
} ;
reduceAtWith t p (Pair l r) =
case match l (subterm t p) of {
Nothing -> [] ;
Just sub -> Cons (placeAt (subst sub r) p t) [] ;
} ;
isVar (Var v) = True ;
isVar (Fun f ts) = False ;
subst s (Var v) = case s of {
[] -> Var v ;
Cons (Pair w t) rest -> case equalStrings v w of {
True -> t ;
False -> subst rest (Var v) ;
} ;
} ;
subst s (Fun f ts) = Fun f (map (subst s) ts) ;
equalTerms (Var v) (Var w) = equalStrings v w ;
equalTerms (Var v) (Fun g us) = False ;
equalTerms (Fun f ts) (Var w) = False ;
equalTerms (Fun f ts) (Fun g us) = con (equalStrings f g)
(and (zipWith equalTerms ts us)) ;
applyToIndex f n (Cons x xs) = case (==) n 0 of {
True -> Cons (f x) xs ;
False -> Cons x (applyToIndex f (dec n) xs) ;
} ;
equiv t u = con (isJust (match t u)) (isJust (match u t)) ;
subterm t [] = t ;
subterm t (Cons p1 pRest) = case t of {
Fun f ts -> subterm (elemAt ts (dec p1)) pRest ;
} ;
placeAt t [] u = t ;
placeAt t (Cons p pRest) u = case u of {
Fun f ts ->
Fun f (applyToIndex (placeAt t pRest) (dec p) ts) ;
} ;
vars (Var v) = Cons v [] ;
vars (Fun f ts) = foldr (unionBy equalStrings) [] (map vars ts) ;
positions (Var v) = Cons [] [] ;
positions (Fun f ts) = Cons [] (concatMap (argPositions ts)
(enumFromTo 1 (length ts)) ) ;
argPositions ts n = map (Cons n) (positions (elemAt ts (dec n))) ;
variables = let { variety = Cons "" (concatMap variations variety) ; }
in tail variety ;
variations v = map (flip Cons v) "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
}