diff --git a/lib/haskell/natural4/src/LS/BasicTypes.hs b/lib/haskell/natural4/src/LS/BasicTypes.hs index a07b8554c..b9c86a150 100644 --- a/lib/haskell/natural4/src/LS/BasicTypes.hs +++ b/lib/haskell/natural4/src/LS/BasicTypes.hs @@ -80,7 +80,7 @@ data MyToken = Every | Party | TokAll | Empty | EOL | RuleMarker Int Text.Text | Expect | ScenarioTok - | TokLT | TokLTE | TokGT | TokGTE | TokIn | TokNotIn | TokEQ | TokAnd | TokOr | TokSum | TokProduct + | TokLT | TokLTE | TokGT | TokGTE | TokIn | TokNotIn | TokEQ | TokAnd | TokOr | TokSum | TokProduct | TokMin | TokMax | Notwithstanding | Despite | SubjectTo | Otherwise | SOF | EOF @@ -243,11 +243,11 @@ toToken "§§§§§§" = pure $ RuleMarker 6 "§" toToken "SCENARIO" = pure ScenarioTok toToken "EXPECT" = pure Expect toToken "<" = pure TokLT -toToken "MIN" = pure TokLT; toToken "MIN OF" = pure TokLT +toToken "MIN" = pure TokMin; toToken "MIN OF" = pure TokMin toToken "=<" = pure TokLTE toToken "<=" = pure TokLTE toToken ">" = pure TokGT -toToken "MAX" = pure TokGT; toToken "MAX OF" = pure TokGT +toToken "MAX" = pure TokMax; toToken "MAX OF" = pure TokMax toToken ">=" = pure TokGTE toToken "=" = pure TokEQ toToken "&&" = pure TokAnd @@ -416,6 +416,8 @@ renderToken (RuleMarker n txt) = concat $ replicate n (Text.unpack txt) renderToken Semicolon = ";;" renderToken SubjectTo = "SUBJECT TO" +renderToken TokMin = "MIN" +renderToken TokMax = "MAX" renderToken TokSum = "SUM" renderToken TokProduct = "PRODUCT" renderToken FMap = "MAP" diff --git a/lib/haskell/natural4/src/LS/Interpreter.hs b/lib/haskell/natural4/src/LS/Interpreter.hs index 8d8db7853..dc4327464 100644 --- a/lib/haskell/natural4/src/LS/Interpreter.hs +++ b/lib/haskell/natural4/src/LS/Interpreter.hs @@ -325,6 +325,7 @@ getAttrTypesIn ct classname = -- | structure the rules as a graph. -- in the simple case, the graph is one or more trees, each rooted at a "top-level" rule which is not "used" by any another rule. + -- if we walk the roots, we will sooner or later encounter all the decision elements relevant to each root. -- in a less simple case, the graph is cyclic! everything depends on everything else! but we can recognize that as an error condition. -- diff --git a/lib/haskell/natural4/src/LS/RelationalPredicates.hs b/lib/haskell/natural4/src/LS/RelationalPredicates.hs index 356c2ec57..db363e314 100644 --- a/lib/haskell/natural4/src/LS/RelationalPredicates.hs +++ b/lib/haskell/natural4/src/LS/RelationalPredicates.hs @@ -238,6 +238,8 @@ tok2rel = choice , RPor <$ pToken TokOr , RPsum <$ pToken TokSum , RPproduct <$ pToken TokProduct + , RPmin <$ pToken TokMin + , RPmax <$ pToken TokMax , RPlt <$ pToken TokLT -- serves double duty as MinOflist when in RPnary position , RPlte <$ pToken TokLTE , RPgt <$ pToken TokGT -- serves double duty as MaxOflist when in RPnary position diff --git a/lib/haskell/natural4/src/LS/Types.hs b/lib/haskell/natural4/src/LS/Types.hs index 22dc06440..5adb6396f 100644 --- a/lib/haskell/natural4/src/LS/Types.hs +++ b/lib/haskell/natural4/src/LS/Types.hs @@ -51,6 +51,7 @@ type BoolStructR = AA.OptionallyLabeledBoolStruct RelationalPredicate -- | the relations in a RelationalPredicate data RPRel = RPis | RPhas | RPeq | RPlt | RPlte | RPgt | RPgte | RPelem | RPnotElem | RPnot | RPand | RPor | RPsum | RPproduct | RPsubjectTo + | RPmin | RPmax | RPmap | RPTC TComparison -- ^ temporal constraint as part of a relational predicate; note there is a separate `TemporalConstraint` type. deriving (Eq, Ord, Show, Generic, ToJSON) @@ -276,6 +277,7 @@ mkRpmt a = RPMT (MTT <$> a) mkRpmtLeaf :: [Text.Text] -> BoolStructR mkRpmtLeaf a = mkLeaf (mkRpmt a) +-- | [TODO] figure out why there are two very similar functions, this and `rel2op` rel2txt :: RPRel -> Text.Text rel2txt RPis = "IS" rel2txt RPhas = "HAS" -- "relHas" @@ -290,6 +292,8 @@ rel2txt RPnot = "NOT" -- "relNot" rel2txt RPand = "&&" -- "relAnd" rel2txt RPor = "||" -- "relOr" rel2txt RPmap = "MAP" +rel2txt RPmin = "MIN" +rel2txt RPmax = "MAX" rel2txt RPsum = "SUM" rel2txt RPproduct = "PRODUCT" rel2txt (RPTC TBefore) = "BEFORE" @@ -298,6 +302,7 @@ rel2txt (RPTC TBy ) = "BY" rel2txt (RPTC TOn) = "ON" rel2txt (RPTC TVague) = "ABOUT" +-- | [TODO] figure out why there are two very similar functions, this and `rel2txt` rel2op :: RPRel -> Text.Text rel2op RPis = "IS" rel2op RPhas = ".?" @@ -311,14 +316,7 @@ rel2op RPnotElem = "NOT IN" rel2op RPnot = "NOT" rel2op RPand = "&&" rel2op RPor = "||" -rel2op RPmap = "MAP" -rel2op RPsum = "SUM" -rel2op RPproduct = "PRODUCT" -rel2op (RPTC TBefore) = "BEFORE" -rel2op (RPTC TAfter ) = "AFTER" -rel2op (RPTC TBy ) = "BY" -rel2op (RPTC TOn) = "ON" -rel2op (RPTC TVague) = "ABOUT" +rel2op x = rel2txt x rp2mt :: RelationalPredicate -> MultiTerm rp2mt (RPParamText pt) = pt2multiterm pt