From 7a46dd920a60b18fca08c55ae1af2f320d300f50 Mon Sep 17 00:00:00 2001 From: Hans-Peter Deifel <hans-peter.deifel@fau.de> Date: Tue, 4 Apr 2017 09:43:27 +0200 Subject: [PATCH] Begin to implement LaTeX syntax parsing --- src/lib/CoAlgFormula.ml | 11 ++++ src/lib/CoAlgFormula.mli | 2 + src/lib/Latex.ml | 123 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 136 insertions(+) create mode 100644 src/lib/Latex.ml diff --git a/src/lib/CoAlgFormula.ml b/src/lib/CoAlgFormula.ml index 6472add..7d0c3b5 100644 --- a/src/lib/CoAlgFormula.ml +++ b/src/lib/CoAlgFormula.ml @@ -1925,6 +1925,17 @@ let const_choice f1 f2 = CHC (f1, f2) *) let const_fusion first f1 = FUS (first, f1) +(** Constructs a MU formula. + @param var The bound variable + @param f The formula + @returns [mu var. f]*) +let const_mu var f = MU (var, f) + +(** Constructs a NU formula. + @param var The bound variable + @param f The formula + @returns [nu var. f]*) +let const_nu var f = NU (var, f) (** Hash-consed formulae, which are in negation normal form, such that structural and physical equality coincide. diff --git a/src/lib/CoAlgFormula.mli b/src/lib/CoAlgFormula.mli index 3fb17ed..0a687b4 100644 --- a/src/lib/CoAlgFormula.mli +++ b/src/lib/CoAlgFormula.mli @@ -136,6 +136,8 @@ val const_enforces : int list -> formula -> formula val const_allows : int list -> formula -> formula val const_choice : formula -> formula -> formula val const_fusion : bool -> formula -> formula +val const_mu : string -> formula -> formula +val const_nu : string -> formula -> formula type hcFormula = (hcFormula_node, formula) HashConsing.hash_consed and hcFormula_node = diff --git a/src/lib/Latex.ml b/src/lib/Latex.ml new file mode 100644 index 0000000..7749df1 --- /dev/null +++ b/src/lib/Latex.ml @@ -0,0 +1,123 @@ +open MParser +open CoAlgFormula + +let (<*) = (<<<) +let ( *> ) = (>>>) + +let lexeme p = p <* spaces + +let varchar = alphanum <|> char '_' + +let skip_symbol str = + lexeme (string str >> not_followed_by varchar "superfluous character") + +let parens p = between (lexeme (char '(')) (lexeme (char ')')) p + +let infix sym f assoc = Infix (skip_symbol sym >> return f, assoc) +let prefix sym f = Prefix (skip_symbol sym >> return f) + +let ptrue = skip_symbol "\\true" >> return TRUE +let pfalse = skip_symbol "\\false" >> return FALSE + +let pname = + letter >>= fun start -> + many_chars varchar >>= fun rest -> + spaces >> + return (Char.escaped start ^ rest) + +let psym = pname |>> const_ap + +let maybe_brace_str = + (char '{' *> many1_chars varchar <* char '}') + <|> (varchar |>> Char.escaped) + +let pnominal = + let add_tick s = ("'" ^ s) in + lexeme (char '\'' >> many_chars varchar |>> add_tick |>> const_nom) + +let pat = string "@_" *> maybe_brace_str |>> const_at + +let pmu = + skip_symbol "\\mu" >> + pname >>= fun var -> + lexeme (char '.') >>$ const_mu var + +let k_modality constructor name = + string name >> ( + (char '_' *> lexeme (maybe_brace_str |>> constructor)) + <|> return (constructor "")) + +let diamond = lexeme (k_modality const_ex "\\Diamond") +let box = lexeme (k_modality const_ax "\\Box") + +let operators = + [ + [ prefix "\\neg" const_not ]; + [ Prefix pat ]; + [ Prefix diamond ]; + [ Prefix box ]; + [ infix "\\wedge" const_and Assoc_left ]; + [ infix "\\vee" const_or Assoc_left ]; + [ infix "\\implies" const_imp Assoc_right ]; + [ infix "\\equiv" const_imp Assoc_right ]; + [ Prefix pmu ]; + ] + +let rec term s = (parens expr <|> ptrue <|> pfalse <|> pnominal <|> psym) s +and expr s = expression operators term s + +let recurse_formula func formula = + match formula with + (* 0-ary constructors *) + | TRUE | FALSE | AP _ | VAR _ -> formula + | CONST _ + | CONSTN _ -> formula + (* unary *) + | NOT a -> NOT (func a) + | AT (s,a) -> AT (s,func a) + (* binary *) + | OR (a,b) -> OR (func a, func b) + | AND (a,b) -> AND (func a, func b) + | EQU (a,b) -> EQU (func a, func b) + | IMP (a,b) -> IMP (func a, func b) + | EX (s,a) -> EX (s,func a) + | AX (s,a) -> AX (s,func a) + | ENFORCES (s,a) -> ENFORCES (s,func a) + | ALLOWS (s,a) -> ALLOWS (s,func a) + | MIN (n,s,a) -> MIN (n,s,func a) + | MAX (n,s,a) -> MAX (n,s,func a) + | ATLEASTPROB (p,a) -> ATLEASTPROB (p, func a) + | LESSPROBFAIL (p,a) -> LESSPROBFAIL (p, func a) + | MORETHAN (n,s,a) -> MORETHAN (n,s,func a) + | MAXEXCEPT (n,s,a) -> MAXEXCEPT (n,s,func a) + | ID(a) -> ID (func a) + | NORM(a, b) -> NORM(func a, func b) + | NORMN(a, b) -> NORMN(func a, func b) + | CHC (a,b) -> CHC (func a, func b) + | FUS (s,a) -> FUS (s, func a) + | MU (n, f1) -> MU (n, func f1) + | NU (n, f1) -> NU (n, func f1) + | AF f1 -> AF (func f1) + | EF f1 -> EF (func f1) + | AG f1 -> AG (func f1) + | EG f1 -> EG (func f1) + | AU (f1, f2) -> AU (func f1, func f2) + | EU (f1, f2) -> EU (func f1, func f2) + | AR (f1, f2) -> AR (func f1, func f2) + | ER (f1, f2) -> ER (func f1, func f2) + | AB (f1, f2) -> AB (func f1, func f2) + | EB (f1, f2) -> EB (func f1, func f2) + +let bound_check formula = + let rec replace_bound symtab formula = + match formula with + | AP name -> if List.mem name symtab then VAR name else AP name + | MU (var, _) | NU (var, _) -> recurse_formula (replace_bound (var::symtab)) formula + | _ -> recurse_formula (replace_bound symtab) formula + in + replace_bound [] formula + +let eval s = + match parse_string (expr <* eof) s () with + | Success x -> Some (bound_check x) + | Failed (msg,_) -> None -- GitLab