Module:Wikidata/Analyse transitive

De Lagny-sur-Marne Wiki
Révision datée du 21 août 2015 à 22:13 par Zolo (discussion) (Nouvelle page : -- Helpers for queries using transitive properties local p = {} local wd = require "Module:Wikidata" local function getids(item, query) query.excludespecial = true query.displ...)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à : navigation, rechercher

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.inTrasitiveVals(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.inTrasitiveVals(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.inTrasitiveVals(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