Mercurial > hg > dml-open-cliopatria
view cpack/dml/lib/humdrum_p2r.pl @ 0:718306e29690 tip
commiting public release
author | Daniel Wolff |
---|---|
date | Tue, 09 Feb 2016 21:05:06 +0100 |
parents | |
children |
line wrap: on
line source
/* Part of DML (Digital Music Laboratory) Copyright 2014-2015 Samer Abdallah, University of London This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ :- module(humdrum_p2r, [ humdrum_import/1, hum_uri_path/2 ]). /** <module> Manages a database of Humdrum files and mappings to RDF. */ :- use_module(library(memo)). :- use_module(library(humdrum)). :- use_module(library(humdrum/humdrum_world), [with_kern_module/4]). :- use_module(library(fileutils)). :- use_module(library(termutils)). :- use_module(library(typedef)). :- use_module(library(dcg_core)). :- use_module(library(musiclab)). :- use_module(library(settings)). :- use_module(entailment(p2r)). :- set_prolog_flag(double_quotes,string). :- rdf_register_prefix(humdb,'http://dml.org/humdrum/data/'). :- rdf_register_prefix(hum,'http://dml.org/humdrum/schema/'). :- rdf_register_prefix(kern,'kern:'). :- setting(kern_root,string,"~/lib/kern","Root of kern lib tree"). :- setting(kern_subdirs,list(atom),[classical,lorraine,jrp,ragtime,ireland,pentatonic,idyom],"Kern library directories to import"). uripattern:def( work(Opus), humdb:work/enc(Opus)). uripattern:def( trefcode(C), hum:refcode/trans/enc(C)). uripattern:def( refcode(C), hum:refcode/enc(C)). uripattern:def( kernfile(F), kern:tail(F)). % Humdrum schema rdf(hum:refcode('OTL'), rdfs:subPropertyOf, dc:title), rdf(hum:composer, rdfs:subPropertyOf, foaf:maker), rdf(hum:opus, rdfs:subPropertyOf, mo:opus), rdf(hum:'Work', rdfs:subClassOf, mo:'MusicalWork'), rdf(hum:'File', rdfs:subClassOf, mo:'Score'), rdf(hum:encodedBy, rdfs:type, rdf:'ObjectProperty'), % rdf(hum:encodedBy, owl:inverseOf, hum:encodes) <== true. rdf(\refcode(C), rdfs:subPropertyOf, \trefcode(C)) <== setof(C, translated_refcode(C), Codes), member(C, Codes). rdf(\trefcode(C), rdf:comment, Desc1) <== setof(C, translated_refcode(C), Codes), member(C, Codes), hum_prop_desc(C,Desc), atom_concat(Desc,' (translated)',Desc1). translated_refcode(Code) :- browse(file_props(_,Props)), member(Code-((sec-_)-_),Props). hum_prop_desc(C,_) ==> rdf(\refcode(C), rdf:type, rdf:'ObjectProperty'), rdf(\refcode(C), rdf:domain, hum:'File'). hum_prop_desc(C,Desc) ==> rdf(\refcode(C), rdf:comment, literal(Desc)). % -- mappings that use file_opus/2 --------------- %% file(-File) is nondet. % True when File is a Humdrum file that has been imported into % the current database. :- dynamic file/1. %% file_opus(-File,-Opus) is nondet. % True when Humdrum file File contains an SCT refcode % (scholarly catalog number) Opus. file_opus(F,O) :- file(F), file_prop(F,'SCT',_,O). rdf(\kernfile(F), \trefcode(C), literal(Value)) <== call_with_mode(browse,file_prop(F,C,sec,Value)). rdf(\kernfile(F), \refcode(C), literal(Value)) <== call_with_mode(browse,file_prop(F,C,pri,Value)). rdf(\kernfile(F), hum:directory, literal(Dir1)) <== file(F), file_directory_name(F,Dir), atom_concat('/',Dir1,Dir). file(F) ==> % rdf(\kernfile(F), hum:language, hum:language/humdrum), rdf(\kernfile(F), rdf:type, hum:'File'). file_opus(_,O) ==> rdf(\work(O), rdf:type, hum:'Work'), rdf(\work(O), hum:opus, literal(O)). % file_opus(F,O) ==> % rdf(\kernfile(F), hum:encodes, \work(O)). % rdf(\work(O), dc:title, literal(Title)) <== % file_opus(F,O), % (file_has(F,'OTL',Title); file_has(F,'OTP',Title)). % rdf(\work(O), dc:title, literal(lang(Lang,Title))) <== % file_opus(F,O), % file_has(F,'OTL',Title), % file_has(F,'TXO',Lang). % rdf(\work(O), hum:partOf, humdb:parent_work/enc(P)) <== % file_opus(F,O), % (file_has(F,'OPT',P); file_has(F,'OPR',P)). % rdf(\work(O), hum:composer, humdb:agent/enc(C)) <== % file_opus(F,O), file_has(F,'COM',C). % rdf(\work(O), hum:number, literal(Num)) <== % file_opus(F,O), file_has(F,'ONM',Num). % ----- mappings using composers/1 -------- % rdf(humdb:agent/enc(C), foaf:name, literal(C)), % rdf(humdb:agent/enc(C), rdf:type, mo:'MusicArtist') <== % composers(Composers), % member(C,Composers). % ----- mappings using parent_works/1 -------- % rdf(humdb:parent_work/enc(P), rdf:type, hum:'Work'), % rdf(humdb:parent_work/enc(P), dc:title, literal(P)) <== % parent_works(Works), % member(P,Works). has_stripped(Recs,Prop,Status,Literal) :- member(ref(Prop,Lang,RawValue),Recs), split_string(RawValue,""," ",[String]), String\="", atom_string(Value,String), refcode_literal(Lang,Value,Status,Literal). refcode_literal(def, Val, pri, Val). refcode_literal(P-Lang, Val, P, lang(L,Val)) :- lang(Lang,L). :- type prop ---> prop(atom,atom,ground). :- volatile_memo file_props(+file:atomic,-props:list(prop)). file_props(File,Props) :- setting(kern_root,Root0), expand_file_name(Root0,[Root]), string_concat(Root,File,Abs), % !!! FIXME: will barf if Root contains funny characters format(string(Cmd),"grep '^!!!' \"~w\"",[Abs]), hum_read(pipe(Cmd),utf8,Recs), setof(prop(Prop,Status,Lit),has_stripped(Recs,Prop,Status,Lit),Props). :- volatile_memo parent_works(-works:list(ground)). parent_works(Works) :- writeln('% Compiling list of parent works...'), setof(P, F^O^(file_opus(F,O),file_prop(F,'OPR',_,P)), Works). :- volatile_memo composers(-composers:list(atom)). %% composers(-Composers:list(atom)) is det. % Compiles a list of composer names referenced in the current % Humdrum file property database file_props/2. composers(Composers) :- writeln('% Compiling list of composers...'), findall(C, call_with_mode(browse,file_prop(_,'COM',_,C)), CList), sort(CList,Composers). % rdf(URI,rdf:type,mo:'MusicArtist') <== % composers(Comps), % member(C,Comps), % agent_uri(composer,C,URI). % rdf(URI,hum:name,literal(Name)) <== % agent_uri(composer,Name,URI). % rdf(\kernfile(F), hum:composer, literal(Name)) <== % call_with_mode(browse,file_prop(F,'COM',pri,Name)), % agent_uri(composer,Name,URI). file_work_terms(File) --> if(file_prop(File,'OTL',_,Title), [Title]), if(file_prop(File,'OPR',_,Parent), [Parent]), if(file_prop(File,'OPN',_,Opus), [Opus]), if(file_prop(File,'SCT',_,Cat), [Cat]). file_prop(File,Prop,Status,Lit) :- file_props(File,Props), member(prop(Prop,Status,Lit),Props). hum_uri_path(URI,Path) :- atom_concat('kern:',Rel,URI), setting(kern_root,Root), expand_file_name(Root,[Root1]), string_concat(Root1,Rel,Path). %% humdrum_import(+Path:atom) is det. % % Searches for files in the directory tree beneath % =|<kern_root>/Path|=, where =|<kern_root"|= is the current % value of the setting =|humdrum_p2r:kern_root|=. Path can % be any relative path. Files are added to memoised property % database predicate file_props/2. humdrum_import(Path) :- setting(kern_root,Root0), expand_file_name(Root0,[Root]), with_status_line( forall( ( kern_file(under(Root/Path),File), atom_concat(Root,Rel,File), memo(file_props(Rel,_),_-ok)), ( status(" Imported ~s",[Rel]), id_assert(file(Rel))) )). :- volatile_memo scan_library_dir(+ground,-float). scan_library_dir(Dir,T):- humdrum_import(Dir), get_time(T). :- public import/0, import/1. import :- setting(kern_subdirs,Dirs), import(Dirs). import(Dirs) :- maplist(scan_library_dir,Dirs,_), assert_all(humdrum_p2r). :- volatile_memo humfile_status(+string,-ground). humfile_status(Path,Status) :- status(Path,[]), catch( ( with_kern_module(Path,utf8,_,true) -> Status=ok ; Status=fail), Ex, Status=ex(Ex)). humdrum_check :- with_status_line( forall( (rdf_db:rdf(X,rdf:type,hum:'File'), hum_uri_path(X,Path)), ( humfile_status(Path,Status), ( Status=ok -> true ; Status=fail -> format('\nFailed on: ~w\n',[Path]) ; Status=ex(Ex) -> format('\nException on: ~w\n',[Path]), print_message(error,Ex) ) ))). kern_file(Findspec,File) :- find_files(Findspec,File), extension_in(File,[krn,kern,'KRN','KERN']). id_assert(Fact) :- call(Fact) -> true; assert(Fact). lang('ENG',en). lang('EN',en). lang('FRA',fr). lang('FRE',fr). lang('FR',fr). lang('DE',de). lang('DEU',de). lang('GER',de). lang('ITA',it). lang('IT',it). lang('NO',no). lang('NOR',no). lang('LAT',la). lang('LA',la). lang('RU',ru). lang('RUS',ru).