/* File: sub_delete.c
** Author(s): Ernie Johnson
** Contact: xsb-contact@cs.sunysb.edu
**
** Copyright (C) The Research Foundation of SUNY, 1986, 1993-1998
**
** XSB is free software; you can redistribute it and/or modify it under the
** terms of the GNU Library General Public License as published by the Free
** Software Foundation; either version 2 of the License, or (at your option)
** any later version.
**
** XSB 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 Library General Public License for
** more details.
**
** You should have received a copy of the GNU Library General Public License
** along with XSB; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** $Id: sub_delete.c,v 1.6 2003/03/12 14:56:35 lfcastro Exp $
**
*/
#include "xsb_config.h"
#include "xsb_debug.h"
#include <stdio.h>
#include <stdlib.h>
#include "auxlry.h"
#include "cell_xsb.h"
#include "psc_xsb.h"
#include "trie_internals.h"
#include "macro_xsb.h"
#include "error_xsb.h"
/* Freeing Individual Structures
----------------------------- */
static void free_btn(BTNptr btn) {
SM_DeallocateStruct(smTableBTN,btn);
}
static void free_btht(BTHTptr btht) {
TrieHT_RemoveFromAllocList(smTableBTHT,btht);
SM_DeallocateStruct(smTableBTHT,btht);
}
static void free_tstn(TSTNptr tstn) {
SM_DeallocateStruct(smTSTN,tstn);
}
static void free_tstht(TSTHTptr tstht) {
TrieHT_RemoveFromAllocList(smTSTHT,tstht);
SM_DeallocateStruct(smTSTHT,tstht);
}
static void free_tsi(TSTHTptr tstht) {
if ( IsNonNULL(TSTHT_IndexHead(tstht)) )
SM_DeallocateStructList(smTSIN,TSTHT_IndexTail(tstht),
TSTHT_IndexHead(tstht));
}
static void free_producer_sf(VariantSF sf) {
FreeProducerSF(sf);
}
static void free_consumer_sf(VariantSF sf) {
SM_DeallocateStruct(smConsSF,sf);
}
/*
* Answer List of a Consumer may already be completely deallocated, even
* the dummy node.
*/
static void free_al(VariantSF sf) {
if ( IsNonNULL(subg_ans_list_ptr(sf)) )
free_answer_list(sf);
}
/* Deleting Structures with Substructures
-------------------------------------- */
static void delete_btht(BTHTptr btht) {
free(BTHT_BucketArray(btht));
free_btht(btht);
}
static void delete_tstht(TSTHTptr tstht) {
free(BTHT_BucketArray(tstht));
free_tsi(tstht);
free_tstht(tstht);
}
static void delete_sf(VariantSF sf) {
free_al(sf);
if ( IsProducingSubgoal(sf) )
free_producer_sf(sf);
else
free_consumer_sf(sf);
}
/*-----------------------------------------------------------------------*/
/*
* Delete the given TST Answer Set node and recursively all of
* its children.
*/
static void delete_tst_answer_set(TSTNptr root) {
TSTNptr current, sibling;
TSTHTptr hash_hdr;
unsigned int i;
if ( IsNULL(root) )
return;
/* I inserted the check for TSTN_Child(root) below to avoid
a segmentation fault. It seems to be working fine with it,
and there doesn't seem to be any memory leak (wrt abolishing
subsumptive tables), but as I don't know the code, I'd feel
better if somebody who did looked at it. -- lfcastro */
if ( TSTN_Child(root) && IsHashHeader(TSTN_Child(root)) ) {
hash_hdr = TSTN_GetHashHdr(root);
for ( i = 0; i < TSTHT_NumBuckets(hash_hdr); i++ )
for ( current = TSTHT_BucketArray(hash_hdr)[i];
IsNonNULL(current); current = sibling ) {
sibling = TSTN_Sibling(current);
delete_tst_answer_set(current);
}
delete_tstht(hash_hdr);
}
else if ( ! IsLeafNode(root) )
for ( current = TSTN_Child(root); IsNonNULL(current);
current = sibling ) {
sibling = TSTN_Sibling(current);
delete_tst_answer_set(current);
}
free_tstn(root);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Delete the given Call Table node and recursively all of its children.
*/
void delete_call_index(BTNptr root) {
BTNptr current, sibling;
BTHTptr hash_hdr;
unsigned int i;
if ( IsNULL(root) )
return;
if ( IsHashHeader(BTN_Child(root)) ) {
hash_hdr = BTN_GetHashHdr(root);
for ( i = 0; i < BTHT_NumBuckets(hash_hdr); i++ )
for ( current = BTHT_BucketArray(hash_hdr)[i];
IsNonNULL(current); current = sibling ) {
sibling = BTN_Sibling(current);
delete_call_index(current);
}
delete_btht(hash_hdr);
}
else if ( ! IsLeafNode(root) )
for ( current = BTN_Child(root); IsNonNULL(current);
current = sibling ) {
sibling = BTN_Sibling(current);
delete_call_index(current);
}
free_btn(root);
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void delete_subsumptive_table(TIFptr tif) {
SubProdSF cur_prod, next_prod;
SubConsSF cur_cons, next_cons;
for ( cur_prod = (SubProdSF)TIF_Subgoals(tif);
IsNonNULL(cur_prod); cur_prod = next_prod ) {
for ( cur_cons = subg_consumers(cur_prod);
IsNonNULL(cur_cons); cur_cons = next_cons ) {
next_cons = conssf_consumers(cur_cons);
delete_sf((VariantSF)cur_cons);
}
next_prod = (SubProdSF)subg_next_subgoal(cur_prod);
delete_tst_answer_set((TSTNptr)subg_ans_root_ptr(cur_prod));
delete_sf((VariantSF)cur_prod);
}
delete_call_index(TIF_CallTrie(tif));
}
syntax highlighted by Code2HTML, v. 0.9.1