#include str.cam #include txt.cam #include int.cam #include ff.cam ;N ffs.cam - a CAMILA library for sets of finite mappings ;A J.N. Oliveira (jno@di.uminho.pt) ;D ; This library is concerned with the (A->B)-set functor. ; Such a 'set of mappings' data type is very expressive, as it can be regarded as modelling object populations, relational tables (with NULL values), feature bundles, etc. ; In the documentation below we will be referring to columns or attribute names (A), data values (B), rows or tuples (A->B) and relations or tables ((A->B)-set). ; Last Update: 1999.11.11 ;E FUNC ffsPLUS(s:(X->B)-seq):(X->B)-seq ; ; ffsPLUS(s) reduces set of mappings s via plus, ; which is associative and has [] as the unit element. ; RETURN if s=={} then [] else plus-orio([],s); FUNC ffsUNION(s:(A->B)-set):(A->B)-set ; ; ffsUNION(s) reduces set of mappings s via ffUnion ; (which is idempotent and commutative). ; All mappings in s must have pairwise disjoint domains. ; RETURN let (ffUnion=plus) in if s=={} then [] else ffUnion-orio([],s); FUNC ffsCount(a:A,v:B,r:(A->B)-set):NAT0 ; ; ffsCount(a,v,r) computes the number tuples in r in which data value v ; occurs in the a-column. ; RETURN card({ t | t <- r : a in dom(t) && t[a]==v }); FUNC ffsHistogr(a:A,r:(A->B)-set):B->NAT ; ; ffsHistogr(a,r) generates the histogram (multiset) of attribute a in r. ; RETURN [ v -> ffsCount(a,v,r) | v <- ffsPro(a,r) ]; FUNC ffsPro(a:A,r:(A->B)-set):B-set ; ; ffsPro(a,r) computes the a-column of r (projection). ; RETURN { t[a] | t <- r : a in dom(t) }; FUNC ffsAtts(r:(A->B)-set):A-set ; ; ffsAtts(r) the set of all attributes referred to in r. ; RETURN UNION({ dom(t) | t <- r }); FUNC ffsJoin(f:(A->B)-set,g:(A->B)-set): (A->B)-set ; ; ffsJoin(f,g) performs the relational join operation between f and g ; RETURN { tf + tg | tf <- f, tg <- g: tf / dom(tg) == tg / dom(tf) }; FUNC ffsRename(r:A->A,f:(A->B)-set): (A->B)-set ; ; ffsRename(r,f) renames the attribute names of f according to rename ; mapping r. Not every r is a good rename mapping (guess why). ; RETURN let (g=lambda(a). if a in dom(r) then r[a] else a) in (g->*)-set(f); ; BUG { t \ dom(r) + [ r[a] -> t[a] | a <- dom(t) * dom(r) ] | t <- f }; FUNC ffsColSUM(a:A,r:(A->B)-set): INT ; ; ffsColSUM(a,r) adds integer values of the a-column of r (if any). ; RETURN intSUM(< t[a] | t <- r : a in dom(t) && is-INT(t[a]) >); FUNC ffsColSUMseq(t:(A->B)-set,l:A-seq ):INT-seq ; ; ffsColSUMseq(t,l) extends ffsColSUM to a selection of columns. ; RETURN < ffsColSUM(a,t) | a <- l >; FUNC ffs2txt(s:(A->B)-set): txt ; ; ffs2txt(s) generates a tabular picture of s in txt format. ; RETURN if s=={} then < "No records found" > else let (r= ff2STRff-set(s), A=ffsAtts(r), x=[ a -> 2.+intMAX({strlen(v) | v <- {a} U ffsPro(a,r)}) | a <- A ], L= < a | a <- A >, hline= < strcat("+",strFill("-",x[a])) | a <- L >^<"+\n">, rl= < hline, < strcat("|",strCenter(a,x[a])) | a <- L >^<"|\n">, hline > ^ < < strcat("|", if ~(a in dom(t)) then strCenter("",x[a]) else if is-STR(t[a]) then strCenter(t[a],x[a]) else if is-INT(t[a]) then strRight(itoa(t[a]),x[a]) else strCenter("!",x[a]) ) | a <- L >^<"|\n"> | t <- r > ^ < hline >) in txtFlat(rl); FUNC ffs2TeXtxt(s:(A->B)-set): txt ; ; ffs2TeXtxt(s) is similar to ffs2txt(s) but it generates LaTeX ; tabular environments. ; RETURN if s=={} then < "No records found" > else let (r= ff2STRff-set(s), A=ffsAtts(r), L= < a | a <- A > ) in if L==<> then < "No attributes in table" > else let (h=head(L), t=tail(L)) in < "\\begin{tabular}{", strCAT(< "|c" | a <- L >^<"|}">), "\\hline\n" > ^ seqAddSep(< strcat("\\bf ",a) | a <- L >,"&") ^ < "\\\\\\hline\\hline\n" > ^ < seqAddSep(< if a in dom(t) then t[a] else "" | a <- L >,"&") ^<"\\\\\\hline\n"> | t <- r > ^ < "\\end{tabular}\n" >; FUNC ffs2HTMLtxtOld(s:(A->B)-set): txt ; ; ffs2HTMLtxtOld(s) is similar to ffs2txt(s) but it generates HTML (old version). ; RETURN if s=={} then < "No records found" > else let (r={ ff2STRff(t) | t <- s }, head=lambda(l). < "" > ^ < "" ++ a ++ "" | a <- l > ^ < "\n" >, row=lambda(l). < "" > ^ < "" ++ a ++ "" | a <- l > ^ < "\n" >, A=ffsAtts(r), L= < a | a <- A >, x= < < if a in dom(t) then t[a] else "" | a <- L > | t <- r >, rl= < "\n\nffs2HTMLtxt [ffs.cam] output\n\n", "\n" > ^ head(L) ^ row-seq(x) ^ < "
\n\n" >) in txtFlat(rl); FUNC ffs2HTMLtxt(s:(A->B)-set): txt ; ; ffs2HTMLtxt(s) is similar to ffs2txt(s) but it generates HTML. ; RETURN if s=={} then < "No records found" > else let (r={ ff2STRff(t) | t <- s }, even=lambda(a). rem(a,2)==0, th=lambda(a). < "", a , "" >, Td=lambda(a,c). < "", a, "\n" >, head=lambda(l). < "\n" > ^ < th(a) | a <- l > ^ < "\n\n" >, row=lambda(l,c). < "\n" > ^ < Td(a,c) | a <- l > ^ < "\n\n" >, A=ffsAtts(r), L= < a | a <- A >, x= < < if a in dom(t) then t[a] else "" | a <- L > | t <- r >, y=seq2ff(x), z=[ n -> row(y[n],if even(n) then "#FFFFFF" else "#FFFFD2") | n <- dom(y) ], rl= < "\n\nffs2HTMLtxt [ffs.cam] output\n\n", "\n", "
\n", "\n" > ^ head(L) ^ ff2seq(<>,z) ^ < "
\n
\n\n\n" >) in txtFlat(rl);