Module:Wikidata/Analyse transitive
Révision datée du 22 août 2015 à 07:14 par Zolo (discussion)
La documentation pour ce module peut être créée à Module:Wikidata/Analyse transitive/doc
-- Helpers for queries using transitive properties local p = {} local wd = require "Module:Wikidata" local function getids(item, query) query.excludespecial = true query.displayformat = 'raw' query.entity = item return wd.stringTable(query) end local function alreadyHere(searchset, val) for i, j in pairs(searchset) do if val == j then return true end end return false end -- add new items to a list, avoiding duplicates local function addnewvalues(olditems, newitems) if not newitems then return olditems end for _, qid in pairs(newitems) do if not alreadyHere(olditems, qid) then table.insert(olditems, qid) end end return olditems end -- recursively adds a list of qid to an existing list, based on the results of a query local function continuevals(origlist, query, maxdepth, maxnodes) maxdepth = maxdepth or 10 maxnodes = maxnodes or 100 if (maxdepth < 0) then return origlist end local list = {} for i, j in pairs(origlist) do -- seul moyen de copier une liste table.insert(list, j) end for i, item in pairs(origlist) do local candidates = getids(item, query) list = addnewvalues(list, candidates) if #list >= maxnodes then return list end end if (#list == #origlist) then return list end return continuevals(list, query, maxdepth - 1, maxnodes) end -- returns a list of items transitively matching a query function p.transitiveVals(item, query, maxdepth, maxnodes) local vals = getids(item, query) if not vals then return nil end return continuevals(vals, query, maxdepth - 1, maxnodes) end -- returns true if an item is the value of a query, transitively function p.inTransitiveVals(searchedval, sourceval, query, maxdepth, checked ) maxdepth = maxdepth or 10 if not checked then checked = {} end if maxdepth < 0 then return false end local acceptedvals = p.transitiveVals( sourceval, query, 0) -- width first if not acceptedvals then return false end if alreadyHere(acceptedvals, searchedval) then return true end for i, j in pairs(acceptedvals) do local success if not alreadyHere(checked, j) then table.insert(checked, j) success = p.inTransitiveVals(searchedval, j, query, maxdepth -1, checked) end if success then return true end end return false end -- returns true if an item is a superclass of another, based on P279 function p.isSubclass(class, item, maxdepth) query = {property = 'P279'} if class == item then -- item is a subclass of itself iff it is a class if getids(item, query) then return true end return false end return p.inTransitiveVals(class, item, query, maxdepth ) end -- returns true if one of the best ranked P31 values of an item is the target or a subclass of the target -- rank = 'valid' would seem to make sense, but it would need to check for date qualifiers as some P31 values have begin or end date function p.isInstance(targetclass, item, maxdepth) maxdepth = maxdepth or 10 local directclasses = p.transitiveVals(item, {property = 'P31'}, 1) if not directclasses then return false end for i, class in pairs(directclasses) do if p.isSubclass(targetclass, class, maxdepth - 1) then return true end end return false end return p