Module:Formula
From MaRDI portal
Documentation for this module may be created at Module:Formula/doc
-- Required modules for SPARQL queries and HTML table generation
-- Module for executing SPARQL queries
local sparql = require('SPARQL')
-- MediaWiki library for logging and utilities
local mw = require('mw')
local json = require("mw.text")
-- Main table to hold all functions
local p = {}
-- function to check whether the item has the MathModDB community tag
function p.hasMathModDB(frame)
local entityId = frame.args[1] or mw.wikibase.getEntityIdForCurrentPage()
if not entityId then
-- "" equivalent to false
return ""
end
local entity = mw.wikibase.getEntity(entityId)
if not entity or not entity.claims or not entity.claims.P1495 then
-- "" equivalent to false
return ""
end
for _, claim in pairs(entity.claims.P1495) do
local value = claim.mainsnak and claim.mainsnak.datavalue and claim.mainsnak.datavalue.value
if value and value.id == "Q6534265" then
-- non empty ("") equivalent to true
return true
end
end
-- "" equivalent to false
return ""
end
-- Function to get defining formulation with Quantities
function p.extractDefiningFormulationWithQuantities(frame)
local equation = mw.wikibase.getEntity()
local equationID = entity and entity.id or nil
-- Table to store formulations
local formulations = {}
-- Table to store quantity symbol and name id
local quantitySymbolNameIdPairs = {}
-- P989 refers to property defining formula
local definingFormula = equation:getBestStatements('P989')
if definingFormula and #definingFormula > 0 then
local value = definingFormula[1].mainsnak.datavalue.value
mathTag = frame:extensionTag{
name = "math",
content = value
}
table.insert(formulations, "| Defining Formula: " .. mathTag)
end
quantitySymbolNameIdPairs = p.extractQuantities(equationID)
if type(quantitySymbolNameIdPairs) == "table" then
-- Accessing the stored pairs
for i, pair in ipairs(quantitySymbolNameIdPairs) do
local pairFirstValue = pair[1]
local pairFirstValue = mw.text.decode(pairFirstValue or "")
local quantitySymbolMathTag = frame:extensionTag{
name = "math",
content = pairFirstValue
}
-- Construct the Portal URL
local quantityId = pair[3]
local numericId = quantityId:sub(2) -- remove "Q" to get "6674540"
local quantity = mw.wikibase.getEntity(quantityId)
-- P31 referes to property instance of
local quantityStatement = quantity:getBestStatements('P31')[1] -- Get the first (and only) statement
local instanceId = quantityStatement.mainsnak.datavalue.value.id
local urlRendered
if instanceId == 'Q6481152' then
urlRendered = "https://portal.mardi4nfdi.de/wiki/Formula:" .. numericId
elseif instanceId == 'Q6534237' or instanceId == 'Q6534245' then
urlRendered = "https://portal.mardi4nfdi.de/wiki/Quantity:" .. numericId
end
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(pair[2]))
table.insert(formulations, "| " .. quantitySymbolMathTag .. " represents " .. labelWithUrl)
end
table.insert(formulations, "| " .. " " )
else
-- Error: extractQuantities did not return a table"
end
-- Construct the Wikitext table
local wikitextTable = [[
{| class="wikitable" style="table-layout: auto;"
]] .. table.concat(formulations, "\n|-\n") .. "\n|}"
return wikitextTable
end
function p.extractQuantities(qid)
-- Property ID for in defining formula
local pidInDefiningFormula = "P983"
-- Property ID for the (qualifier) symbol represents
local pidSymbolRepresents = "P984"
-- Attempt to retrieve entity data
local entity = mw.wikibase.getEntity(qid)
if not entity or not entity.claims[pidInDefiningFormula] then
return "No formulation found"
end
local inDefiningFormulaClaims = entity.claims[pidInDefiningFormula]
local count = 0
-- Table to store pairs of quantity symbol and quantity name
local quantitySymbolNameIdPairs = {}
for _ in pairs(inDefiningFormulaClaims or {}) do
count = count + 1
-- Get the quantity symbol
local quantitySymbol = inDefiningFormulaClaims[count].mainsnak.datavalue.value
if not quantitySymbol then
return "No valid symbol found"
end
quantity = inDefiningFormulaClaims[count].qualifiers[pidSymbolRepresents][1].datavalue.value.text
quantityId = inDefiningFormulaClaims[count].qualifiers[pidSymbolRepresents][1].datavalue.value.id
local quantityName = mw.wikibase.label(quantityId)
-- Insert pair into the table
table.insert(quantitySymbolNameIdPairs, {quantitySymbol, quantityName, quantityId})
end
return quantitySymbolNameIdPairs
end
-- Function to get specialized Research Problems
function p.getSpecializedFormulas(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return "Error: No entity ID provided"
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P1684: specialized by property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?URL ?Label
WHERE {
entityId: wdt:P1684 ?URL.
?URL rdfs:label ?Label
FILTER(LANG(?Label) = "en")
}
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return "No specialized research fields found"
end
local specializedFormulas = {}
-- Get the number of specialized research fields
local totalFormulas = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalFormulas do
local item = jsonResults.results.bindings[index]
if not item.Label.value then
return "Error: Missing item.Label.value"
elseif not item.URL.value then
return "Error: Missing item.URL.value"
else
local label = item.Label.value
local url = item.URL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Formula:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label))
table.insert(specializedFormulas, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(specializedFormulas, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get formula discretizations
function p.getDiscretizations(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return " "
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P1656: discretized property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?DiscretizedURL ?DiscretizedLabel
WHERE {
entityId: p:P1656 ?statement.
?statement ps:P1656 ?DiscretizedURL.
?DiscretizedURL rdfs:label ?DiscretizedLabel.
FILTER(LANG(?DiscretizedLabel) = "en")
}
ORDER BY ?DiscretizedLabel
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return " "
end
local discretizations = {}
-- Get the number of discretizations
local totalDiscretizations = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalDiscretizations do
local item = jsonResults.results.bindings[index]
if not item.DiscretizedLabel.value then
return "Error: Missing item.Label.value"
elseif not item.DiscretizedURL.value then
return "Error: Missing item.URL.value"
else
local label = item.DiscretizedLabel.value
local url = item.DiscretizedURL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Formula:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label))
table.insert(discretizations, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(discretizations, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get formula approximations
function p.getApproximations(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return " "
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P1655: approximated by property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?ApproximatedURL ?ApproximatedLabel
WHERE {
entityId: p:P1655 ?statement.
?statement ps:P1655 ?ApproximatedURL.
?ApproximatedURL rdfs:label ?ApproximatedLabel.
FILTER(LANG(?ApproximatedLabel) = "en")
}
ORDER BY ?ApproximatedLabel
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return " "
end
local approximations = {}
-- Get the number of discretizations
local totalApproximations = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalApproximations do
local item = jsonResults.results.bindings[index]
if not item.ApproximatedLabel.value then
return "Error: Missing item.Label.value"
elseif not item.ApproximatedURL.value then
return "Error: Missing item.URL.value"
else
local label = item.ApproximatedLabel.value
local url = item.ApproximatedURL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Formula:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label))
table.insert(approximations, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(approximations, "\n|-\n") .. "\n|}"
return wikitextTable
end
-- Function to get similar formulas
function p.getSimilar(frame)
local entityId = frame.args[1]
-- Validate input parameter
if not entityId or entityId == '' then
return " "
end
-- Constructing the SPARQL query with dynamic entity entityId
-- P1691: approximated by property id
local sparqlQuery = [[
PREFIX entityId: <https://portal.mardi4nfdi.de/entity/]] .. entityId .. [[>
SELECT ?SimilarURL ?SimilarLabel
WHERE {
entityId: p:P1691 ?statement.
?statement ps:P1691 ?SimilarURL.
?SimilarURL rdfs:label ?SimilarLabel.
FILTER(LANG(?SimilarLabel) = "en")
}
ORDER BY ?SimilarLabel
]]
-- Executing the SPARQL query and retrieving results in JSON format
local jsonResults = sparql.runQuery(sparqlQuery)
-- Validate results
if not jsonResults or not jsonResults.results or not jsonResults.results.bindings then
return " "
end
local similar = {}
-- Get the number of similar expressions
local totalSimilar = #jsonResults.results.bindings
-- Loop through the bindings
for index = 0, totalSimilar do
local item = jsonResults.results.bindings[index]
if not item.SimilarLabel.value then
return "Error: Missing item.Label.value"
elseif not item.SimilarURL.value then
return "Error: Missing item.URL.value"
else
local label = item.SimilarLabel.value
local url = item.SimilarURL.value
local numericId = url:match("Q(%d+)")
local urlRendered = "https://portal.mardi4nfdi.de/wiki/Formula:" .. numericId
local labelWithUrl = string.format('[%s %s]', tostring(urlRendered), tostring(label))
table.insert(similar, "| " .. labelWithUrl)
end
end
-- Construct the Wikitext table
local wikitextTable = "{| class='wikitable'\n" .. table.concat(similar, "\n|-\n") .. "\n|}"
return wikitextTable
end
return p