Loading files
This 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 Nil = True ;
null (Cons x xs) = False ;
head (Cons x xs) = x ;
tail (Cons x xs) = xs ;
append Nil ys = ys ;
append (Cons x xs) ys = Cons x (append xs ys) ;
map f Nil = Nil ;
map f (Cons x xs) = Cons (f x) (map f xs) ;
concatMap f Nil = Nil ;
concatMap f (Cons x xs) = append (f x) (concatMap f xs) ;
elemBy e x Nil = 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 Nil = Nil ;
filter p (Cons x xs) = case p x of {
True -> Cons x (filter p xs) ;
False -> filter p xs ;
} ;
foldr f z Nil = z ;
foldr f z (Cons x xs) = f x (foldr f z xs) ;
zipWith f Nil Nil = Nil ;
zipWith f Nil (Cons y ys) = Nil ;
zipWith f (Cons x xs) Nil = Nil ;
zipWith f (Cons x xs) (Cons y ys) = Cons (f x y) (zipWith f xs ys) ;
zip = zipWith Pair ;
unlines Nil = "" ;
unlines (Cons s ss) = append s (Cons '\n' (unlines ss)) ;
emitStr Nil k = k ;
emitStr (Cons c cs) k = (+) c (emitStr cs k) ;
length Nil = 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 -> Nil ;
} ;
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 Nil = Nil ;
intersperse i (Cons x Nil) = Cons x Nil ;
intersperse i (Cons x (Cons y ys)) = Cons x (Cons i (intersperse i (Cons y ys))) ;
nubBy e xs = nubBySans Nil e xs ;
nubBySans ss e Nil = Nil ;
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 Nil = Nothing ;
lookUpBy e x (Cons (Pair y v) yvs) = case e x y of {
True -> Just v ;
False -> lookUpBy e x yvs ;
} ;
equalStrings Nil Nil = True ;
equalStrings Nil (Cons y ys) = False ;
equalStrings (Cons x xs) Nil = 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) Nil))) ;
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)) Nil )) ;
eqns = Cons (Pair (Fun "+" (Cons (Fun "0" Nil) (Cons (Var "X") Nil)))
(Var "X")) (
Cons (Pair (Fun "+" (Cons (Fun "-" (Cons (Var "X") Nil))
(Cons (Var "X") Nil) ))
(Fun "0" Nil)) (
Cons (Pair (Fun "+" (Cons (Fun "+" (Cons (Var "X")
(Cons (Var "Y") Nil)))
(Cons (Var "Z") Nil) ))
(Fun "+" (Cons (Var "X")
(Cons (Fun "+" (Cons (Var "Y")
(Cons (Var "Z") Nil))) Nil) )))
Nil )) ;
} 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 Nil Nil = Pair Nil Nil ;
zipWithRemRight f Nil (Cons y ys) = Pair Nil (Cons y ys) ;
zipWithRemRight f (Cons x xs) Nil = Pair Nil Nil ;
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 Nil = Pair Nil 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 Nil ;
completionLoop sig vs n Nil 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 { rs = Cons newRule rules ;
cps = getCriticalPairs rs newRule ; }
in completionWith2 (simplifyRules sig newRule rules)
sig rs rest cps
(completionLoop sig vs n);
completionWith2 (Pair eqs rls) sig rs rest cps k =
k (simplifyEquations sig
rs
(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 Nil = Pair Nil Nil ;
reduceSplit sig rule (Cons (Pair l r) rs) =
let { reducedl = reduce (Cons rule Nil) l ; } in
case reduceSplit sig rule rs of {
Pair eqns rules ->
case dis (null reducedl)
(reducible (Cons (Pair l r) Nil) (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 -> Nil ;
False -> case unify t l2 of {
Nothing -> Nil ;
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 -> Nil ;
False -> Cons (Pair cpl cpr) Nil ;
} ;
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 Nil) 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 Nil ;
Fun f ts -> Nil ;
} ;
tally k Nil = Nil ;
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 Nil Nil = False ;
orderLex f Nil (Cons y ys) = False ;
orderLex f (Cons x xs) Nil = 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 Nil) (Cons t2 Nil) Nil ;
unifyWith Nil Nil 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) Nil) 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 Nil) (Cons t2 Nil) Nil ;
matchWith Nil Nil 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 Nil ;
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 -> Nil ;
False -> concatMap (reduceAtWith t p) trs ;
} ;
reduceAtWith t p (Pair l r) =
case match l (subterm t p) of {
Nothing -> Nil ;
Just sub -> Cons (placeAt (subst sub r) p t) Nil ;
} ;
isVar (Var v) = True ;
isVar (Fun f ts) = False ;
subst s (Var v) = case s of {
Nil -> 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 Nil = t ;
subterm t (Cons p1 pRest) = case t of {
Fun f ts -> subterm (elemAt ts (dec p1)) pRest ;
} ;
placeAt t Nil 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 Nil ;
vars (Fun f ts) = foldr (unionBy equalStrings) Nil (map vars ts) ;
positions (Var v) = Cons Nil Nil ;
positions (Fun f ts) = Cons Nil (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" ;
}
e9b051238This file is pinned to the selected release. Download the original to open it in your design tool.