Neo4j and other graph database software out there for one don't support subgraph isomorphism search out-of-the-box which is what I need and I'd also like full expressivity of a CFG on label matchings and checking if a variable substitution can be made so that the graphs do match exactly.
This way, only a single isolated graph node with a single one-letter variable label (for instance) ("$a$") will occur in the whole of the database (unless of course you add more labels to the node), because if the user creates a graph with a single node say ("$b$"), it will match the first graph and so the user cannot add it to the database. This keeps scaling of database more manageable.
Here is the grammar using pegged.d a PEG parser generator for the D language:
module MyGraphDatabase;
import std.stdio;
import pegged.grammar;
// Example useage:
/*
search for
} U {
.X1 f↪ .Y
g↶ i↖ h↶
.Z x↪ .W,
}
where:
i is mono
i matches labels {'\text{Hom}(x,y)', 'ξ \in'}
f is {'\..}
*/
//We need this grammar in order to put things in a standard form before searching
// For instance taking spaces out
mixin(grammar(`
CaterpillarQL:
LineOfObjects <- Map(ArrowLR) (:" " Arr
ArrowLeftRight < GeneralArrLeftRight / EpiArrLeftRight / MonoArrLeftRight /
IsomArrLeftRight / MapsToLeftRight / EqualityArrLeftRight /
ExistsArrRight
ArrowUpDownDiagonal <- GenArrUD / GeneralArrDiagonal /
EpiArrUpDown / MonoArrDown / MapsToArrUpDown / EqualityArrUpDown
ArrowLR <- EpiArrLR / MonoArrLR / GenArrLR / MapsToArrLR / IsoArrLR / EqArrLR
IsomMapLeftRight / MapsToLeftRight / EqualityMapLeftRight /
ExistsArrLR / InclArrLR
EpiArrLR <- Arr("↞") / Arr("↠")
EpiArrUD <- Arr("↟") / Arr("↡")
MonoArrLR <- Arr("↩") / Arr("↪")
MonoArrUD <- Arr("⮍") / Arr("⮏")
MonoArrDiag <- Arr("⤣") / Arr("⤤") / Arr("⤥") / Arr("⤦")
GenArrLR <- Arr("←") / Arr("→")
GenArrUD <- Arr("↑") / Arr("↓")
GenArrDiag <- Arr("↖") / Arr("↗") / Arr("↘") / Arr("↙")
MapsToArrLR <- Arr("↤") / Arr("↦")
MapsToArrUD <- Arr("↥") / Arr("↧")
IsoArrLR <- Arr("⭁") / Arr("⭇")
EqArrLR <- Arr("⇺") / Arr("⥱")
EqArrUD <- Arr("⇟") / Arr("⇞")
ExistsArrLR <- Arr("⬸") / Arr("⤑")
ExistsArrUD <- Arr("⇡") / Arr("⇣")
InclArrLR <- Arr("↢") / Arr("↣")
SelfMap < Arr("⟳") Obj
Map(arr) < Object :" " arr :" " Object
Arr(arr) <- UnicodeSub(LowerLatin) arr
Object <- "." UnicodeSub(UpperAlpha)
Scripted <- (Var / TextName / AlphaInt / Operator) ("\\limits" ((Sub? Sup?) / (Sup? Sub?)))?
Sub <- SimpleSub / ComplexSub
Sup <- SimpleSup / ComplexSup
SimpleSub <- :"_" AlphaInt
SimpleSup <- :"^" AlphaInt
ComplexSub <- :"_{" Expr :"}"
ComplexSup <- :"^{" Expr :"}"
Expr <- EnclosedExpr / list(Expr, ",") / Scripted
EnclosedExpr <- "(" Expr ")" / "{" Expr "}" / "[" Expr "]"
UnicodeSub(var) <- var IntUniSubs
IntUniSubs <~ ("-" / "+")? [₁₂₃₄₅₆₇₈₉]+ [₀₁₂₃₄₅₆₇₈₉]*
AlphaInt < Alpha / Int
Alpha <- UpperAlpha / LowerAlpha
UpperAlpha <- UpperGreek / UpperLatin
LowerAlpha <- LowerGreek / LowerLatin
UpperGreek <- "Γ" / "Δ" / "Θ" / "Ξ" / "Π" / "Σ" / "Φ" / "Ψ" / "Ω"
LowerGreek <- "α" / "β" / "γ" / "δ" / "ε" / "ζ" / "η" / "θ" / "ι" /
"κ" / "ξ" / "π" / "ρ" / "σ" / "ς" / "τ" / "υ" / "φ" / "ψ" / "χ" / "λ" / "μ"
LowerLatin <- [a-z]
UpperLatin <- [A-Z]
TextName < "\text{" (AlphaInt / "-")+ "}"
Int <~ ("-" / "+")? [1-9]+ [0-9]*
Var <- identifier
Operator <- "+"
`));
int main()
{
enum parseTree1 = CaterpillarQL(".X g↠ .Y");
writeln(parseTree1);
writeln("Hello D World!\n");
readln();
return 0;
}
Anyway, I'm at the point of choosing between "↪" for monomorphism and "↣" for inclusion (vs. the other way around).
MonoArrLR <- Arr("↩") / Arr("↪")
MonoArrUD <- Arr("⮍") / Arr("⮏")
MonoArrDiag <- Arr("⤣") / Arr("⤤") / Arr("⤥") / Arr("⤦")
InclArrLR <- Arr("↢") / Arr("↣")
I am getting my unicode arrow symbols from: this site which seems to have a more complete list than the official unicode listing.
So the answer is obvious, since "↢" has no up/down/diagonal counterparts, it should be used for inclusions indeed if inclusions in general occur less in diagrams relative to monomorphisms. So my question is do you see a monomorphism more often than an inclusion (when studying Category Theory / Homological Algebra / Algebraic Topology / Algebraic Number Theory) or is it the other way around?
On the one hand monomorphism is more general so will be seen in more categories, but concrete categories on the other hand are very common (categories in which you'd find inclusion).
I have never encountered any mathematician who distinguishes notationally between "inclusion" arrows and monomorphism arrows. In most natural situations, monomorphisms are the same thing as inclusions up to isomorphism anyways. So, I would strongly recommend that you simply not distinguish the two at all.