Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete lexsis #94

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions l4/r34_classes.l4
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# class AllConditionsOfSecondScheduleSatisfied
# {LExSIS: {encoding: "conditions_of_second_schedule_satisfied"}}

class Service {
is_Legal_Service: Boolean
is_Law_Related_Service: Boolean
is_Listed_In_Fourth_Schedule: Boolean
}

class Business {
Detracts_From_Dignity_Of_Legal_Profession: Boolean
Incompatible_With_Dignity_Of_Legal_Profession: Boolean
Derogates_From_Dignity_Of_Legal_Profession: Boolean
Likely_To_Unfairly_Attract_Business_in_Practice_of_Law: Boolean
Set_Out_In_First_Schedule: Boolean
Prohibited_Business: Boolean
is_Trade: Boolean
is_Calling: Boolean
is_ForProfit: Boolean
is_in_Singapore: Boolean
}


class Organization {
Carries_On: Business -> Boolean
Provides: Service -> Boolean

Listed_In_Third_Schedule: Boolean
has_Position: Position -> Boolean

is_Company: Boolean
is_Corporation: Boolean
is_Partnership: Boolean
is_LLP: Boolean
is_Sole_Proprietorship: Boolean
is_Business_Trust: Boolean

Beneficial_Owner_of: Person -> Boolean
Legal_Owner_of: Person -> Boolean
has_Partner: Person -> Boolean
has_SoleProprietor: Person -> Boolean
has_Director: Person -> Boolean
}

class Position {
Accepted_As_Representative_Of_Parent_Practice: Boolean
Associated_With: Business -> Boolean
Entitles_Holder_As_Executive: Boolean
Independent_Director: Boolean
Non_Executive_Director: Boolean
Materially_Interferes_with_Practicing_For: Person -> Boolean # ???
Materially_Interferes_with_Availability_For: Person -> Boolean # ???
Materially_Interferes_with_Representation_For: Person -> Boolean # ???
}


class LegalPractitioner extends Person {
Locum_Solicitor: Boolean
Primary_Occupation: Boolean # This is supposed to be an enum
}

class Legal_Practice {
Joint_Law_Venture: Boolean
Formal_Law_Alliance: Boolean
Foreign_Law_Practice: Boolean
Jurisdiction: Boolean # this is supposed to be an enum in lexsis
Legal_Practitioner: LegalPractitioner -> Boolean
hasPosition: Position -> Boolean
}

class Person
# {LExSIS: {encoding: ""}}



decl Singapore: Jurisdiction
decl Other: Jurisdiction
211 changes: 136 additions & 75 deletions src/ToDA2.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,109 +19,177 @@ createDSyaml :: Program Tp -> IO ()
createDSyaml p = putDoc $ showDS p


-- Perhaps instead of using Maybe, an Either would be better.
-- Perhaps instead of using Maybe, an Either would be better.
-- With Left :: Doc ann = PP.emptyDoc, and right :: WithProgram (Doc ann) = concretized
data DSBlock t = DSBlock { blkName :: String
, blkType :: Either String Tp
, blkCard :: Maybe Int -- cardinality
, blkEncodings :: String
, blkAttrs :: [Maybe (DSBlock t)]
, blkUI :: [Maybe t] -- ask, tell, any, another
, blkSource :: Maybe String
data DSBlock t = DSBlock { blkName :: String -- block name
, blkType :: String --
, blkCard :: Maybe String -- cardinality, everything is assumed to be a list
, blkEncodings :: String -- associated sCASP encoding
, blkAttrs :: [Maybe (DSBlock t)] --
, blkUI :: [Maybe t] -- ask, tell, any, another
, blkSource :: Maybe String -- only appears if block is a child attribute, with an "Object type"
}


instance (Show t) => DSYaml (DSBlock t) where
showDS DSBlock { blkName, blkType, blkCard, blkEncodings, blkAttrs, blkUI, blkSource} =
hang 2 $ "-" <+> vsep [ "name:" <+> pretty blkName
, "type:" <+> either pretty showDS blkType
, "minimum: 0 # Change cardinality accordingly" --cardinality goes here
-- , "ask/tell/any/other:" -- ui goes here
, "encodings:" , indent 2 $ "-" <+> pretty blkEncodings -- TODO : add functionality for list-encoding
, putSource blkSource <> putAttrs blkAttrs <> PP.line
, "type:" <+> pretty blkType
, putCard blkCard <> "encodings:" , indent 2 $ "-" <+> pretty blkEncodings -- TODO : add functionality for list-encoding
, putSource blkSource <> putAttrs blkAttrs
]
where putAttrs ba = case ba of
[Nothing] -> PP.emptyDoc
[Nothing] -> PP.emptyDoc
_ -> "attributes:" <> PP.line <> indent 2 (showDSlist $ catMaybes ba) -- attributes here (one-level only)
putSource (Just x) = "source:" <+> pretty x
putSource (Just x) = "source:" <+> pretty x <> PP.line
putSource Nothing = PP.emptyDoc


-- ClassDecl {
-- annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Sign"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Sign"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "beat"
-- , tpOfFieldDecl = FunT
-- ( ClassT ( ClsNm "Sign" ) ) BoolT }]} }
--
-- ClassDecl { annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Player"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Player"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "throw"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Sign" ) ) BoolT } ] } }

-- ClassDecl { annotOfClassDecl = _
-- , nameOfClassDecl = ClsNm "Game"
-- , defOfClassDecl = ClassDef { supersOfClassDef = [ ClsNm "Game"
-- , ClsNm "Class"
-- , ClsNm "Object" ]
-- , fieldsOfClassDef = [ FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "participate_in"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Player" ) ) BoolT
-- }
-- , FieldDecl { annotOfFieldDecl = _
-- , nameOfFieldDecl = FldNm "win"
-- , tpOfFieldDecl = FunT ( ClassT ( ClsNm "Player" ) ) BoolT
-- }
-- ] } } ]

putCard (Just x) = pretty x <> PP.line
putCard Nothing = PP.emptyDoc


-- nameOfClassDecl = ClsNm { stringOfClassName = "Service" }
-- , defOfClassDecl = ClassDef
-- { supersOfClassDef =
-- [ ClsNm { stringOfClassName = "Service" }
-- , ClsNm { stringOfClassName = "Class" }
-- , ClsNm { stringOfClassName = "Object" }
-- ]
-- , fieldsOfClassDef =
-- [ FieldDecl
-- { annotOfFieldDecl = LocTypeAnnot
-- { locAnnot =
-- , typeAnnot = OkT
-- }
-- , nameOfFieldDecl = FldNm { stringOfFieldName = "isLegalService" }
-- , tpOfFieldDecl = ClassT
-- ( ClsNm { stringOfClassName = "Boolean" } )
-- }
-- , FieldDecl
-- { annotOfFieldDecl = LocTypeAnnot
-- { locAnnot =
-- , typeAnnot = OkT
-- }
-- , nameOfFieldDecl = FldNm { stringOfFieldName = "isLawRelatedService" }
-- , tpOfFieldDecl = ClassT
-- ( ClsNm { stringOfClassName = "Boolean" } )
-- }
-- , FieldDecl
-- { annotOfFieldDecl = LocTypeAnnot
-- { locAnnot =
-- , typeAnnot = OkT
-- }
-- , nameOfFieldDecl = FldNm { stringOfFieldName = "isListedInFourthSchedule" }
-- , tpOfFieldDecl = ClassT
-- ( ClsNm { stringOfClassName = "Boolean" } )
-- }
-- ]
-- }
-- }

-- nameOfClassDecl = ClsNm { stringOfClassName = "LegalPractitioner" }
-- , defOfClassDecl = ClassDef
-- { supersOfClassDef =
-- [ ClsNm { stringOfClassName = "LegalPractitioner" }
-- , ClsNm { stringOfClassName = "Person" } -- TODO: source for class decls that transpile to objects
-- , ClsNm { stringOfClassName = "Class" }
-- , ClsNm { stringOfClassName = "Object" }
-- ]
-- , fieldsOfClassDef =
-- [ FieldDecl
-- { annotOfFieldDecl = LocTypeAnnot
-- { locAnnot =
-- , typeAnnot = OkT
-- }
-- , nameOfFieldDecl = FldNm { stringOfFieldName = "Locum_Solicitor" }
-- , tpOfFieldDecl = ClassT
-- ( ClsNm { stringOfClassName = "Boolean" } )
-- }
-- , FieldDecl
-- { annotOfFieldDecl = LocTypeAnnot
-- { locAnnot =
-- , typeAnnot = OkT
-- }
-- , nameOfFieldDecl = FldNm { stringOfFieldName = "Primary_Occupation" }
-- , tpOfFieldDecl = ClassT
-- ( ClsNm { stringOfClassName = "Boolean" } )
-- }
-- ]
-- }
-- }


classDeclToBlock :: ClassDecl ct -> DSBlock ct
classDeclToBlock ClassDecl { nameOfClassDecl, defOfClassDecl } =
let clnm = getClassname nameOfClassDecl
super = getSuper $ supersOfClassDef defOfClassDecl
in
DSBlock { blkName = lowercase clnm
, blkType = Left "String" -- This needs to show "boolean" for types that are supported
, blkCard = Nothing
, blkEncodings = lowercase clnm ++ "(X)"
, blkAttrs = mapAttrs $ fieldsOfClassDef defOfClassDecl
, blkType = superToBlocktype super
, blkCard = superToBlockcard super
, blkEncodings = lowercase clnm ++ "(X)" -- TODO: Arity of parent encodings
, blkAttrs = mapAttrs $ fieldsOfClassDef defOfClassDecl
, blkUI = undefined
, blkSource = Nothing
, blkSource = superToBlocksource super
}
where clnm = (\(ClsNm name) -> name) nameOfClassDecl
mapAttrs x = case x of
where getClassname (ClsNm name)= name
mapAttrs x = case x of
[] -> [Nothing]
_ -> map (Just . fieldDeclToBlock) x
getSuper (x1:x2:xs) = getClassname x2
superToBlockcard x = case x of
"Class" -> Just "minimum: 0"
_ -> Nothing
superToBlocktype x = case x of
"Class" -> "String"
_ -> "Object"
superToBlocksource x = case x of
"Class" -> Nothing
x -> Just $ lowercase x

fieldDeclToBlock :: FieldDecl ct -> DSBlock ct
fieldDeclToBlock (FieldDecl _ (FldNm fldnm) fieldtype) =
DSBlock { blkName = lowercase fldnm
, blkType = eitherTp "Object" fieldtype fieldtype -- This needs to show the "boolean" for types that are supported
, blkCard = Nothing
, blkEncodings = (lowercase fldnm ++) $ either id id $ eitherTp "(X,Y)" "(Y)" fieldtype
let blockArity = getArity fieldtype
blockType = getBlocktype fieldtype
outname = lowercase fldnm
in
DSBlock { blkName = outname
, blkType = blockType
, blkCard = getCard blockType
, blkEncodings = showEncoding outname blockArity
, blkAttrs = [Nothing]
, blkUI = undefined
, blkSource = showFTname fieldtype -- for supported types, there is no source block
}
where getCard x = case x of
"Object" -> Just "minimum: 0"
_ -> Nothing

eitherTp :: String -> a -> Tp -> Either String a
eitherTp x1 x2 tp = if elem tp [BoolT, IntT] then Right x2 else Left x1

showFTname :: Tp -> Maybe String
showFTname tp = case tp of
(FunT x BoolT) -> showFTname x
getBlocktype :: Tp -> String
getBlocktype tp = case tp of
(FunT x y) -> "Object"
(ClassT (ClsNm "Boolean")) -> "Boolean"

showFTname :: Tp -> Maybe String
showFTname tp = case tp of
(FunT x y) -> showFTname x
(ClassT (ClsNm "Boolean")) -> Nothing
(ClassT (ClsNm name)) -> Just $ lowercase name
_ -> Nothing

getArity :: Tp -> Int
getArity (FunT x y) = 1 + getArity y
getArity (ClassT x) = 1

showEncoding :: String -> Int -> String
showEncoding x 1 = x <> "(X)"
showEncoding x 2 = x <> "(X,Y)"

lowercase :: String -> String
lowercase = map toLower

-- type WithProgram = Reader (Program Tp)

class DSYaml x where
showDS :: x -> Doc ann
Expand All @@ -133,14 +201,7 @@ instance DSYaml (Program Tp) where
showDS Program { lexiconOfProgram,classDeclsOfProgram,globalsOfProgram,rulesOfProgram,assertionsOfProgram} = do
vsep [ "rules: "
, "query: "
, "data:" , hang 2 $ showDSlist $ map classDeclToBlock $ reverse $ drop 7 classDeclsOfProgram
, "data:" , indent 2 $ showDSlist $ map classDeclToBlock $ reverse $ drop 7 classDeclsOfProgram -- TODO: Refactor to a more concrete method of handling base classes
, "terms: "
, "options: " <> PP.line
]


instance DSYaml Tp where
showDS tp = case tp of
BoolT -> "Boolean"
IntT -> "Number"
_ -> "Unsupported Type"