Drasil icon indicating copy to clipboard operation
Drasil copied to clipboard

Should we be explicitly building `ConceptChunk`s when making `UnitalChunk`s or letting the constructors do it implicitly?

Open samm82 opened this issue 3 years ago • 4 comments

This issue was migrated from #3199 and will be updated upon its completion. It makes #3074 obsolete.


We have constructors that build a UnitalChunk from a Concept c and constructors that build it from "a given 'UID', term, and definition". It definitely makes sense to have constructors of the first type (since some concepts are reused independently of their UnitalChunk versions, but I'm not sure if we should keep the constructors that implicitly build a Concept from its parts. It might be good to force the user to create the Concept explicitly to encourage reuse, support future change, and make code less cluttered, but it also means that information is more spread out. These implications are similar to those discussed in the wiki page for the DefinedQuantityDict chunk investigation. Since ucs (which builds from the parts of a Concept) is used in cuc', we would potentially need to tweak it as well.

https://github.com/JacquesCarette/Drasil/blob/09365d7d1f5dc9b54e84a8d64cb601184456ea0c/code/drasil-lang/lib/Language/Drasil/Chunk/Constrained.hs#L125-L130

Alternatively, we could also move one of these sets of constructors to drasil-utils.

samm82 avatar Jan 15 '23 00:01 samm82

As discussed at the meeting, this is part of a bigger design question. A Unital is really an instance of its underlying Concept; so the Concept should be "by reference" instead of being contained.

Can you please add (or point me to if it already exists) a list of all the calls to cuc' to see what they "really are"?

JacquesCarette avatar Jan 25 '23 19:01 JacquesCarette

Because I'm interested in the bigger design question as it relates to the theory lattice I'm interested in...

λ ~/Programming/MyDrasil/code/ master* rg "cuc' " -ths
drasil-lang/lib/Language/Drasil/Chunk/UncertainQuantity.hs
120:uqc nam trm desc sym un space cs val = uq (cuc' nam trm desc sym un space cs val)
125:uqcND nam trm sym un space cs val = uq (cuc' nam trm "" sym un space cs val)

drasil-lang/lib/Language/Drasil/Chunk/Constrained.hs
68:-- | Creates a constrained unitary chunk from a 'UID', term ('NP'), 'Symbol', 'Space', 'Constraint's, and a 'Maybe' 'Expr' (Similar to 'cuc' but no units).
126:cuc' :: (IsUnit u) => String -> NP -> String -> Symbol -> u
128:cuc' nam trm desc sym un space cs rv =

drasil-example/dblpendulum/lib/Drasil/DblPendulum/Unitals.hs
185:pendDisAngle = cuc' "pendDisAngle"

drasil-example/swhs/lib/Drasil/SWHS/Unitals.hs
415:tempW = cuc' "tempW"
422:tempPCM = cuc' "tempPCM"
429:watE = cuc' "watE" (nounPhraseSP "change in heat energy in the water")
435:pcmE = cuc' "pcmE" (nounPhraseSP "change in heat energy in the PCM")

https://github.com/JacquesCarette/Drasil/blob/e4b3354f1d8586ff25fec845ea9618af4bff25fe/code/drasil-lang/lib/Language/Drasil/Chunk/UncertainQuantity.hs#L116-L125

https://github.com/JacquesCarette/Drasil/blob/e4b3354f1d8586ff25fec845ea9618af4bff25fe/code/drasil-example/dblpendulum/lib/Drasil/DblPendulum/Unitals.hs#L184-L189

https://github.com/JacquesCarette/Drasil/blob/e4b3354f1d8586ff25fec845ea9618af4bff25fe/code/drasil-example/swhs/lib/Drasil/SWHS/Unitals.hs#L414-L438

Aside: it's also funny: I've had a nagging feeling since #3134 that "smart constructors" might hide a lot of information. Here, I think they hide information from the chunk database, but I think it might also be related to the "conflicting UIDs" bubble (#2911 ?) because this, while it is an extension of the underlying Concept, it is also an instance. So, here, should they even be sharing the same UID?

balacij avatar Feb 01 '23 03:02 balacij

Returning to this: Brilliant find, @samm82 !

I need to return to this soon. For now, some notes:

We recently discussed stateful chunk smart constructors that only create chunks relative to a chunk database. If we have this, we might be able to erase all manually written UIDs in favour of ones randomly assigned by the chunk database on registration.

Pseudocode:

type Chunk a = State ChunkDB a

unassignedUID :: UID
unassignedUID = error "A chunk was used before insertion into the ChunkDB!"

insert :: HasUID a => a -> Chunk a
insert chunkWithInvalidUID = do
  nextUID <- generateUID
  let brandedChunk = chunkWithInvalidUID & uid .~ nextUID
  modify $ \db -> ... (do the necessary stuff here to add the chunk to the ChunkDB) ...
  return brandedChunk
...

data MyChunk = MC { _uid :: UID, _title :: String }

myChunk :: String -> Chunk MyChunk
myChunk = insert . MyChunk unassignedUID

twoOfMyChunks :: String -> String -> Chunk (MyChunk, MyChunk) -- this would be more neat for `UnitalChunk`, where we could have `Chunk (ConceptChunk, UnitalChunk)` that creates both at the same time -- I will write the body as if this were the case...
twoOfMyChunks cc uc = do
  insertedCC <- insert $ ConceptChunk unassignedUID cc
  insertedUC <- insert $ UnitalChunk unassignedUID (insertedCC ^. uid) uc
  return (insertedCC, insertedUC)

balacij avatar May 24 '25 04:05 balacij

I would be fine with system-assigned UIDs. That would prevent people from abusing them.

We should still have UIDs give us more information though - I'm thinking type-like information here. The UID field should likely carry some information from which we can recover the 'chunk kind' from.

JacquesCarette avatar May 26 '25 17:05 JacquesCarette