PageRenderTime 46ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/GO/Handlers/prolog.pm

https://github.com/gitpan/go-perl
Perl | 666 lines | 579 code | 38 blank | 49 comment | 86 complexity | 1b8688bce52c381d009d6db2a27159ba MD5 | raw file
  1. # stag-handle.pl -p GO::Parsers::GoOntParser -m <THIS> function/function.ontology
  2. package GO::Handlers::prolog;
  3. use base qw(GO::Handlers::abstract_prolog_writer
  4. Data::Stag::Writer);
  5. use strict;
  6. sub s_obo {
  7. my $self = shift;
  8. $self->cmt("-- ********************************************************* --\n");
  9. $self->cmt("-- Autogenerated Prolog factfiles \n");
  10. $self->cmt("-- see http://www.blipkit.org for details \n");
  11. $self->cmt("-- ********************************************************* --\n");
  12. $self->nl;
  13. }
  14. sub e_header {
  15. my ($self, $hdr) = @_;
  16. my $idspace = $hdr->sget_idspace;
  17. if ($idspace && $idspace =~ /(\S+)\s+(\S+)/) {
  18. $self->factq('metadata_db:idspace'=>[$1]);
  19. $self->factq('metadata_db:idspace_uri'=>[$1,$2]);
  20. }
  21. if ($hdr->get_ontology) {
  22. $self->factq('ontology'=>[$hdr->sget_ontology]);
  23. }
  24. foreach ($hdr->get_subsetdef) {
  25. my $id = $_->sget_id;
  26. my $name = $_->sget_name;
  27. $self->factq('metadata_db:partition'=>[$id]);
  28. $self->factq('metadata_db:entity_label', [$id, $name]) if $name;
  29. }
  30. foreach ($hdr->get_synonymtypedef) {
  31. my $id = $_->sget_id;
  32. my $name = $_->sget_name;
  33. my $scope = $_->sget_scope || '';
  34. $self->factq('metadata_db:synonym_type_desc'=>[$id,$scope,$name]);
  35. }
  36. foreach ($hdr->get_import) {
  37. $self->factq('ontol_db:import_directive'=>[$_]);
  38. }
  39. foreach ($hdr->subnodes) {
  40. my $n = $_->name;
  41. if ($n =~ /^treat/) {
  42. $n =~ s/\-/_/g;
  43. my @vals = split(' ',$_->data);
  44. $self->factq("ontol_db:$n"=>[@vals]);
  45. }
  46. }
  47. $self->nl;
  48. return;
  49. }
  50. sub e_typedef {
  51. my ($self, $typedef) = @_;
  52. $self->cmt("-- Property/Slot --\n");
  53. my $ont = $typedef->get_namespace;
  54. my $id = $typedef->get_id || $self->throw($typedef->sxpr);
  55. my $proptype = 'property';
  56. my $domain = $typedef->get_domain;
  57. my $range = $typedef->get_range;
  58. if ($range && $range =~ /^xsd:/) {
  59. $proptype = 'slot';
  60. }
  61. #$self->fact($proptype, [$id, $typedef->sget_name]);
  62. $self->factq($proptype, [$id]);
  63. my $name = $typedef->sget_name;
  64. $self->factq('metadata_db:entity_label', [$id, $name]) if $name;
  65. my @is_as = $typedef->get_is_a;
  66. foreach my $is_a (@is_as) {
  67. if (ref($is_a)) {
  68. my $gci_rel = $is_a->sget('@/gci_relation');
  69. if ($gci_rel) {
  70. $self->rfactq($_,
  71. 'gci_subclass',
  72. [$id,$is_a->data, $gci_rel, $is_a->sget('@/gci_filler')]);
  73. }
  74. else {
  75. $self->rfactq($_, 'subclass', [$id, $is_a->data]);
  76. }
  77. }
  78. else {
  79. $self->rfactq($_, 'subclass', [$id, $is_a]);
  80. }
  81. }
  82. if ($ont) {
  83. $self->factq('metadata_db:entity_resource', [$id, $ont]);
  84. }
  85. if ($typedef->get_is_obsolete) {
  86. $self->factq( 'metadata_db:entity_obsolete', [$id, 'property']);
  87. }
  88. foreach (qw(is_reflexive
  89. is_anti_symmetric
  90. is_symmetric
  91. is_transitive
  92. is_functional
  93. is_inverse_functional
  94. is_proper
  95. is_cyclic
  96. is_metadata_tag
  97. is_class_level
  98. holds_for_all_times
  99. is_symmetric_on_instance_level
  100. is_transitive_on_instance_level)) {
  101. if ($typedef->sget($_)) {
  102. $self->rfactq($typedef->sget($_), $_,[$id]);
  103. }
  104. }
  105. foreach (qw(all_some
  106. all_only
  107. all_some_all_times)) {
  108. my $val = $typedef->sget($_);
  109. if ($val) {
  110. $self->fact('property_relationship',[$id,$_,$val]);
  111. }
  112. }
  113. # if (!$typedef->sget_is_metadata_tag) {
  114. # $self->factq( 'all_some',[$id]);
  115. # }
  116. $self->export_tags($typedef);
  117. foreach (qw(domain range)) {
  118. my $val = $typedef->sget($_);
  119. if ($val) {
  120. $self->fact("property_$_",[$id,convert_to_ref($val)]);
  121. }
  122. }
  123. foreach (qw(transitive_over inverse_of class_level_inverse_of inverse_of_on_instance_level transitive_form_of cyclic_form_of cyclic_over
  124. complement_of directed_simple_path_over directed_path_over reflexive_over expand_expression_to expand_assertion_to)) {
  125. my $val = $typedef->sget($_);
  126. if ($val) {
  127. $self->factq( $_,[$id,$val]);
  128. }
  129. }
  130. my @relchains = $typedef->get_holds_over_chain;
  131. foreach my $relchain (@relchains) {
  132. my @rels = $relchain->get_relation;
  133. if (@rels) {
  134. $self->factq( holds_over_chain=>[$id,\@rels]);
  135. }
  136. }
  137. my @equivchains = $typedef->get_equivalent_to_chain;
  138. foreach my $equivchain (@equivchains) {
  139. my @rels = $equivchain->get_relation;
  140. if (@rels) {
  141. $self->factq( equivalent_to_chain=>[$id,\@rels]);
  142. }
  143. }
  144. $self->factq('disjoint_from', [$id, $_]) foreach $typedef->get_disjoint_from;
  145. $self->factq('disjoint_over', [$id, $_]) foreach $typedef->get_disjoint_over;
  146. my @xpelts = $typedef->get_intersection_of;
  147. foreach (@xpelts) {
  148. $self->factq( 'property_intersection_element',[$id,$_->get_to]);
  149. }
  150. @xpelts = $typedef->get_union_of;
  151. foreach (@xpelts) {
  152. $self->factq( 'property_union_element',[$id,$_->get_to]);
  153. }
  154. foreach (qw(holds_temporally_between holds_atemporally_between)) {
  155. my $holds = $typedef->sget($_);
  156. if ($holds) {
  157. $self->factq( $_,[$id,$holds->get_subject,$holds->get_object]);
  158. }
  159. }
  160. $self->nl;
  161. return;
  162. }
  163. sub e_term {
  164. my ($self, $term) = @_;
  165. my $id = $term->get_id || $self->throw($term->sxpr);
  166. my $name_h = $self->{name_h};
  167. my $name = $term->get_name;
  168. #$name =~ s/_/ /g; # ontologies lack consistency; force use of spc
  169. my $ont = $term->get_namespace;
  170. if ($name) {
  171. # cache the name; useful for use in comment fields later
  172. if (!$name_h) {
  173. $name_h = {};
  174. $self->{name_h} = $name_h;
  175. }
  176. $name_h->{$id} = $name;
  177. #$self->cmt("-- $name --\n");
  178. $self->factq('metadata_db:entity_label', [$id, $name]) if $name;
  179. }
  180. if ($ont) {
  181. $self->factq('metadata_db:entity_resource', [$id, $ont]);
  182. }
  183. if ($term->get_is_obsolete) {
  184. $self->factq('metadata_db:entity_obsolete', [$id, 'class']);
  185. }
  186. else {
  187. # only declare this to be a class if not obsolete
  188. $self->factq('class', [$id]);
  189. }
  190. #my @is_as = $term->findval_is_a;
  191. my @is_as = $term->get_is_a;
  192. foreach my $is_a (@is_as) {
  193. if (ref($is_a)) {
  194. my $gci_rel = $is_a->sget('@/gci_relation');
  195. if ($gci_rel) {
  196. $self->rfactq($_,
  197. 'gci_subclass',
  198. [$id,$is_a->get('.'), $gci_rel, $is_a->sget('@/gci_filler')]);
  199. }
  200. else {
  201. #$self->rfactq($_,'subclass', [$id, ref($is_a) ? $_->get('.') : $_], $name_h->{$_});
  202. $self->rfactq($_, 'subclass', [$id, $is_a->get('.')], $name_h->{$_});
  203. }
  204. }
  205. else {
  206. $self->rfactq($_,'subclass', [$id, $is_a], $name_h->{$is_a});
  207. }
  208. }
  209. my @equivs = $term->get_equivalent_to;
  210. $self->rfactq($_, 'equivalent_class', [$id, ref($_) ? $_->get('.') : $_]) foreach @equivs;
  211. my @xp = $term->get_intersection_of;
  212. if (scalar(@xp) == 1) {
  213. $self->warn("IGNORING single intersection_of tag for $id/$name");
  214. @xp=();
  215. }
  216. if (@xp) {
  217. my @genus_l = ();
  218. @xp = grep {
  219. # new style genus-differentia:
  220. # we say intersection_of: ID rather than
  221. # intersection_of: relation ID
  222. if (!$_->get_type || $_->get_type eq 'is_a') {
  223. if (@genus_l) {
  224. $self->warn(">1 genus for $id/$name");
  225. }
  226. push(@genus_l, $_->get_to);
  227. 0;
  228. }
  229. else {
  230. 1;
  231. }
  232. } @xp;
  233. $self->factq('genus',[$id, $_])
  234. foreach @genus_l;
  235. foreach my $diff (@xp) {
  236. my $rel = $diff->get_type;
  237. my $min_card = $diff->sget('@/minCardinality');
  238. my $max_card = $diff->sget('@/maxCardinality');
  239. my $card = $diff->sget('@/cardinality');
  240. if ($card) {
  241. $min_card = $card;
  242. $max_card = $card;
  243. }
  244. if (defined $min_card &&
  245. !defined $max_card) {
  246. $rel = {card=>[$rel,$min_card || 0]};
  247. }
  248. elsif (defined $max_card) {
  249. $rel = {card=>[$rel,$min_card || 0,$max_card]};
  250. }
  251. else {
  252. }
  253. $self->factq('differentium', [$id, $rel, $diff->sget_to])
  254. }
  255. }
  256. # TODO - unify handling of cardinality
  257. my @rels = $term->get_relationship;
  258. foreach (@rels) {
  259. my @args =
  260. ($id, $_->get_type, convert_to_ref($_->get_to), map { convert_to_ref($_) } $_->get_additional_argument);
  261. my $gci_rel = $_->sget('@/gci_relation');
  262. if ($gci_rel) {
  263. $self->rfactq($_,
  264. 'gci_restriction',
  265. [@args, $gci_rel, $_->sget('@/gci_filler')],
  266. $name_h->{$_->get_to});
  267. }
  268. else {
  269. $self->rfactq($_,
  270. 'restriction',
  271. [@args],
  272. $name_h->{$_->get_to});
  273. }
  274. foreach my $cardp (qw(cardinality minCardinality maxCardinality)) {
  275. my $card = $_->sget('@/'.$cardp);
  276. if ($card) {
  277. my @cargs = @args;
  278. splice(@cargs,2,0,'');
  279. $cargs[2] = $card;
  280. my $pred = $cardp;
  281. if ($cardp =~ /min/) {
  282. $pred = 'min_cardinality';
  283. }
  284. elsif ($cardp =~ /max/) {
  285. $pred = 'max_cardinality';
  286. }
  287. $self->rfact($_,
  288. $pred.'_restriction',
  289. [@cargs],
  290. $name_h->{$_->get_to});
  291. }
  292. }
  293. }
  294. # subject to change:
  295. if ($term->get_all_direct_subclasses_disjoint) {
  296. $self->factq('all_direct_subclasses_disjoint', [$id]);
  297. }
  298. $self->factq('disjoint_from', [$id, $_]) foreach $term->get_disjoint_from;
  299. $self->factq('class_union_element', [$id, $_->sget_to]) foreach $term->get_union_of;
  300. foreach (qw(is_anonymous)) {
  301. if ($term->sget($_)) {
  302. $self->factq($_,[$id]);
  303. }
  304. }
  305. $self->export_tags($term);
  306. $self->nl;
  307. # metadata
  308. return;
  309. }
  310. sub _flatten_dbxref {
  311. my $x = shift;
  312. my $db = $x->sget_dbname;
  313. my $acc = $x->sget_acc;
  314. if ($db eq "URL" && $acc =~ /http/) { # TODO - check for all URI forms (LSID,...)
  315. return $acc;
  316. }
  317. elsif ($acc eq 'NULL') {
  318. return $db;
  319. }
  320. else {
  321. return "$db:$acc";
  322. }
  323. }
  324. # stuff common to terms and typedefs and insts
  325. sub export_tags {
  326. my ($self, $entity) = @_;
  327. my $def = $entity->get_def;
  328. my $id = $entity->sget_id;
  329. if ($def) {
  330. $self->factq('def',[$id, $def->sget_defstr]);
  331. foreach ($def->get_dbxref) {
  332. $self->factq('def_xref',[$id, _flatten_dbxref($_)]);
  333. }
  334. }
  335. foreach ($entity->get_alt_id) {
  336. $self->factq('metadata_db:entity_alternate_identifier',[$id, $_]);
  337. }
  338. foreach ($entity->get_consider) {
  339. $self->factq('metadata_db:entity_consider',[$id, $_]);
  340. }
  341. foreach ($entity->get_replaced_by) {
  342. $self->factq('metadata_db:entity_replaced_by',[$id, $_]);
  343. }
  344. foreach ($entity->get_comment) {
  345. $self->factq('metadata_db:entity_comment',[$id, $_]);
  346. }
  347. foreach ($entity->get_example) {
  348. $self->factq('metadata_db:entity_example',[$id, $_]);
  349. }
  350. foreach ($entity->get_subset) {
  351. $self->factq('metadata_db:entity_partition',[$id, $_]);
  352. }
  353. foreach ($entity->get_synonym) {
  354. my $syn = $_->sget_synonym_text;
  355. my $scope = $_->sget('@/scope');
  356. my $type = $_->sget('@/synonym_type');
  357. $self->factq('metadata_db:entity_synonym',[$id,$syn]);
  358. $self->factq('metadata_db:entity_synonym_scope',[$id,$syn,$scope]) if $scope;
  359. $self->factq('metadata_db:entity_synonym_type',[$id,$syn,$type]) if $type;
  360. $self->factq('metadata_db:entity_synonym_xref',[$id,$syn,_flatten_dbxref($_)]) foreach $_->get_dbxref;
  361. }
  362. foreach ($entity->get_xref_analog) {
  363. my $xref = _flatten_dbxref($_);
  364. #$self->factq('class_xref',[$id, sprintf("%s:%s",$_->sget_dbname,$_->sget_acc)]);
  365. $self->factq('metadata_db:entity_xref',[$id, $xref]);
  366. my $n = $_->sget('name');
  367. if ($n && !$self->{_written_name_for}->{$xref}) {
  368. $self->factq('metadata_db:entity_label',[$xref, $n]);
  369. $self->{_written_name_for}->{$id} = 1;
  370. }
  371. }
  372. foreach ($entity->get_formula) {
  373. $self->factq('logicalformula',[$id,$_->sget_formula_text,$_->sget('@/format')]);
  374. }
  375. #foreach ($entity->get_subset) {
  376. # $self->fact('belongs_subset',$_->findval_scope || '',$_->sget_synonym_text);
  377. #}
  378. foreach (qw(lexical_category)) {
  379. my $val = $entity->sget($_);
  380. if ($val) {
  381. $self->factq($_,[$id,$val]);
  382. }
  383. }
  384. # property tag-val pairs
  385. foreach my $pv ($entity->get_property_value) {
  386. my $dt = $pv->sget_datatype;
  387. my @args = ($id,$pv->sget_type);
  388. my $link_id = $pv->get('@/id');
  389. if ($dt) {
  390. $self->factq('inst_sv',[@args,$pv->sget_value,$dt]);
  391. }
  392. else {
  393. $self->factq('inst_rel',[@args,$pv->sget_to]);
  394. if ($link_id) {
  395. $self->factq('reification',
  396. [$link_id,{inst_rel=>[@args,$pv->sget_to]}]);
  397. }
  398. }
  399. }
  400. return;
  401. }
  402. sub nextid_by_prod {
  403. my $self = shift;
  404. $self->{_nextid_by_prod} = shift if @_;
  405. $self->{_nextid_by_prod} = {}
  406. unless $self->{_nextid_by_prod};
  407. return $self->{_nextid_by_prod};
  408. }
  409. sub e_prod {
  410. my ($self, $gp) = @_;
  411. my $proddb = $self->up(-1)->sget_proddb;
  412. my $prodacc = $gp->sget_prodacc;
  413. # all gene products go in seqfeature_db module
  414. my $id = "$proddb:$prodacc";
  415. $self->factq('seqfeature_db:feature',[$id]);
  416. $self->factq('seqfeature_db:feature_type',
  417. [$id,$gp->sget_prodtype]);
  418. $self->factq('metadata_db:entity_label',
  419. [$id,$gp->sget_prodsymbol]);
  420. $self->factq('metadata_db:entity_source',
  421. [$id,$gp->sget_proddb]);
  422. # duplicate?
  423. $self->factq('seqfeature_db:feature_organism',
  424. [$id,'NCBITaxon:'.$gp->sget("prodtaxa")]);
  425. #$self->factq('taxon_db:entity_taxon',
  426. # [$id,'NCBITaxon:'.$gp->sget("prodtaxa")]);
  427. $self->factq('seqfeature_db:featureprop',
  428. [$id,'description',$gp->sget_prodname]);
  429. $self->factq('metadata_db:entity_synonym',
  430. [$id,$_])
  431. foreach $gp->get_prodsyn;
  432. # associations between gp and term'
  433. my @assocs = $gp->get_assoc;
  434. my $idh = $self->nextid_by_prod;
  435. foreach my $assoc (@assocs) {
  436. my $n = $idh->{$id}++;
  437. my $term_acc = $assoc->sget_termacc;
  438. my $is_not = $assoc->sget_is_not ? 1 : 0;
  439. my $aid = "$proddb:association-$id-$term_acc-$is_not";
  440. $self->fact('curation',[$aid]);
  441. my $pred = 'curation_statement';
  442. if ($is_not) {
  443. $pred = 'negative_'.$pred;
  444. }
  445. $self->fact($pred,
  446. [$aid,$id,'has_role',$term_acc]);
  447. my $aspect = $assoc->sget_aspect;
  448. if ($aspect) {
  449. if (!$self->{_written_aspect}) {
  450. $self->{_written_aspect} = {};
  451. }
  452. if (!$self->{_written_aspect}->{$term_acc}) {
  453. $self->{_written_aspect}->{$term_acc} = 1;
  454. my $ont = '';
  455. if ($aspect eq 'F') {
  456. $ont = 'molecular_function';
  457. }
  458. elsif ($aspect eq 'P') {
  459. $ont = 'biological_process';
  460. }
  461. elsif ($aspect eq 'C') {
  462. $ont = 'cellular_component';
  463. }
  464. if ($ont) {
  465. $self->fact('metadata_db:entity_resource',[$term_acc,$ont]);
  466. }
  467. }
  468. }
  469. my @evs = $assoc->get_evidence;
  470. my $ne=0;
  471. foreach my $ev (@evs) {
  472. my $eid = "$aid-$ne";
  473. $ne++;
  474. # eg PMID
  475. $self->factq('metadata_db:entity_source',
  476. [$aid,$ev->sget_ref]);
  477. $self->factq('evidence',[$eid]);
  478. $self->factq('curation_evidence',
  479. [$aid,$eid]);
  480. $self->factq('evidence_type',
  481. [$eid,$ev->sget_evcode]);
  482. $self->factq('evidence_with',
  483. [$eid,$_])
  484. foreach $ev->get_with;
  485. }
  486. # note: we treat the source DB as the publisher (the source is the provenance)
  487. $self->factq('metadata_db:entity_publisher',
  488. [$aid,$_])
  489. foreach $assoc->get_source_db;
  490. foreach ($assoc->get('properties/link')) {
  491. $self->factq('curation_subject_property_value',
  492. [$aid,$term_acc,$_->get_type,$_->get_to])
  493. }
  494. foreach ($assoc->get_assocdate) {
  495. if (length($_) eq 8) {
  496. $_ = sprintf("%s-%s-%s",
  497. substr($_,0,4),
  498. substr($_,4,2),
  499. substr($_,6,2));
  500. }
  501. $self->factq('metadata_db:entity_created',
  502. [$aid,$_])
  503. }
  504. my @pvs = $assoc->get_property_value;
  505. foreach my $pv (@pvs) {
  506. $self->factq('curation_qualifier',
  507. [$aid,$pv->sget_type,$pv->sget_to]);
  508. }
  509. my @quals = $assoc->get_qualifier;
  510. foreach my $q (@quals) {
  511. next if $q eq 'not';
  512. $self->factq('curation_qualifier',
  513. [$aid,$q,"true"]);
  514. }
  515. }
  516. }
  517. sub e_annotation {
  518. my ($self, $annotation) = @_;
  519. my $idh = $self->nextid_by_prod;
  520. my $proddb = $annotation->sget_namespace || '_';
  521. my $subj = $annotation->sget_subject;
  522. my $rel = $annotation->sget_relation;
  523. my $obj = $annotation->sget_object;
  524. my $is_not = $annotation->sget_is_not ? 1 : 0;
  525. my $aid = "$proddb:$subj-$obj-$is_not";
  526. $self->fact('curation',[$aid]);
  527. my $pred = 'curation_statement';
  528. if ($is_not) {
  529. $pred = 'negative_'.$pred;
  530. }
  531. $self->fact($pred,
  532. [$aid,$subj,$rel,$obj]);
  533. # my @evs = $assoc->get_evidence;
  534. # my $ne=0;
  535. # foreach my $ev (@evs) {
  536. # my $eid = "$aid-$ne";
  537. # $ne++;
  538. # # eg PMID
  539. # $self->factq('metadata_db:entity_source',
  540. # [$aid,$ev->sget_ref]);
  541. # $self->factq('evidence',[$eid]);
  542. # $self->factq('curation_evidence',
  543. # [$aid,$eid]);
  544. # $self->factq('evidence_type',
  545. # [$eid,$ev->sget_evcode]);
  546. # $self->factq('evidence_with',
  547. # [$eid,$_])
  548. # foreach $ev->get_with;
  549. # }
  550. # note: we treat the source DB as the publisher (the source is the provenance)
  551. $self->factq('metadata_db:entity_publisher',
  552. [$aid,$_])
  553. foreach $annotation->get_provenance;
  554. $self->factq('metadata_db:entity_creator',
  555. [$aid,$_])
  556. foreach $annotation->get_creator;
  557. $self->factq('metadata_db:entity_resource',
  558. [$aid,$_])
  559. foreach $annotation->get_namespace;
  560. my @pvs = $annotation->get_property_value;
  561. foreach my $pv (@pvs) {
  562. $self->factq('curation_qualifier',
  563. [$aid,$pv->sget_type,$pv->sget_to]);
  564. }
  565. }
  566. sub e_instance {
  567. my ($self, $inst) = @_;
  568. my $id = $inst->get_id;
  569. $self->factq('inst', [$id]);
  570. $self->factq('inst_of',[$id,$_])
  571. foreach $inst->get_instance_of;
  572. my $name = $inst->sget_name;
  573. $self->factq('metadata_db:entity_label', [$id, $name]) if $name;
  574. $self->export_tags($inst);
  575. foreach my $pv ($inst->get_relationship) {
  576. my @args = ($id,$pv->sget_type);
  577. my $link_id = $pv->get('@/id');
  578. $self->factq('inst_rel',[@args,$pv->sget_to]);
  579. if ($link_id) {
  580. $self->factq('reification',
  581. [$link_id,{inst_rel=>[@args,$pv->sget_to]}]);
  582. }
  583. }
  584. return;
  585. }
  586. # todo
  587. sub convert_to_ref {
  588. my $to = shift;
  589. if (ref($to)) { # may be enum
  590. return '';
  591. }
  592. else {
  593. return $to;
  594. }
  595. }
  596. sub rfactq {
  597. my $self = shift;
  598. my $elt = shift;
  599. my $f = shift;
  600. my $args = shift;
  601. my $cmt = shift;
  602. $self->factq($f,$args,$cmt);
  603. if (ref($elt)) {
  604. my $reif_id = $elt->get('@/id');
  605. if ($reif_id) {
  606. $self->factq('reification',
  607. [$reif_id,{$f=>$args}]);
  608. }
  609. }
  610. return;
  611. }
  612. sub rfact {
  613. my $self = shift;
  614. my $elt = shift;
  615. my $f = shift;
  616. my $args = shift;
  617. my $cmt = shift;
  618. $self->fact($f,$args,$cmt);
  619. if (ref($elt)) {
  620. my $reif_id = $elt->get('@/id');
  621. if ($reif_id) {
  622. $self->fact('reification',
  623. [$reif_id,{$f=>$args}]);
  624. }
  625. }
  626. return;
  627. }
  628. 1;