-1

1) The class interfaces do not follow good object-oriented design
principles, which make them bug-prone and hard to extend/subclass properly.

Improve the object-oriented design of the classes.

2) The class interfaces are almost completely undocumented. Include proper
interface documentation in the .h-file.

3) There seems to be a bug somewhere, as the test program seems to end with
a SEGV. Find the bug, explain what is wrong, and make a working fix.

4) The class LogicalFunction only supports functions defined by a table.
For some logical functions, especially with many inputs, the truth tables
may be inconveniently large. As an example, a 10-input XOR would need 1024
rows, whereas you could implement it by a couple of lines of C++ code.

Make modifications that makes it possible for the calling program to define
the behavior of a LogicalFunction by providing C++ code.

5) Using your modified classes, define LogicalProcessors that are able to inspect an 8x8 monochrome pixel grid, represented by 64 inputs, and report whether this grid has horizontal, vertical or rotational symmetry. Verify LogicalProcessors by using the grids given in testcases.h as input

Attachments
/* Logical function */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "logicfunction.h"

class LogicFunctionList {
private:

	struct LogicFunctionElm {
		LogicFunction *m_function;
		struct LogicFunctionElm *m_next;
	};

	static struct LogicFunctionElm *head;

public:
	static void insert(LogicFunction *f);
	static void remove(LogicFunction *f);
	static LogicFunction *find(const char *name);
};

LogicFunctionList::LogicFunctionElm *LogicFunctionList::head;

void LogicFunctionList::insert(LogicFunction *f)
{
	struct LogicFunctionElm *oldhead=head;
	head = new struct LogicFunctionElm;
	head->m_function = f;
	head->m_next = oldhead;
}


void LogicFunctionList::remove(LogicFunction *f)
{
	for (LogicFunctionElm **elm=&head; *elm; elm=&((*elm)->m_next))
	{
		if ( (*elm)->m_function == f)
		{
			LogicFunctionElm *next = (*elm)->m_next;
			delete (*elm);
			(*elm) = next;
		}
	}
}

LogicFunction *LogicFunctionList::find(const char *name)
{
	for (LogicFunctionElm *elm=head; elm; elm=elm->m_next)
	{
		if (0 == strcmp(name, elm->m_function->m_name) )
		{
			return elm->m_function;
		}
	}
	return 0;
}


LogicFunction::LogicFunction(const char *name, int numinputs, const char **table) :
	m_numinputs(numinputs), m_table(table)
{
	if (LogicFunction *lf = LogicFunctionList::find(name))
	{
		fprintf(stderr, "Warning: Duplicate definition of LogicFunction \"%s\"\n", name);
		delete lf;
	}
	m_name = strdup(name);
	LogicFunctionList::insert(this);
}

LogicFunction::~LogicFunction()
{
	LogicFunctionList::remove(this);
	free(m_name);
}

LogicFunction *LogicFunction::findFunction(const char *name)
{
	return LogicFunctionList::find(name);
}

char LogicFunction::calculate(char *inputs)
{
	for (const char **t=m_table; *t ; t++)
	{
		int i;
		for (i=0; (*t)[i] == 'x' || inputs[i] == (*t)[i] ; )
		{
			if (++i == m_numinputs )
				return (*t)[i];
		}
	}
	return 'x';
}


LogicProcessor::LogicProcessor( LogicFunction *function )
	: m_logicfunction ( function )
{
	m_inputsources = new char * [ function->m_numinputs ];
	m_inputfunctions = new LogicProcessor * [ function->m_numinputs ];
	for (int i=0; i<function->m_numinputs; i++)
	{
		m_inputsources[i] = 0;
		m_inputfunctions[i] = 0;
	}
}


LogicProcessor::~LogicProcessor()
{
	delete [] m_inputsources;
	delete [] m_inputfunctions;
}

void LogicProcessor::setInput(int input, LogicProcessor *lf)
{
	m_inputfunctions[input] = lf;
}

void LogicProcessor::setInput(int input, char * source)
{
	m_inputsources[input] = source;
}

char LogicProcessor::process()
{
	char *inputs = new char [ m_logicfunction->m_numinputs ];

	for (int i=0;i<m_logicfunction->m_numinputs;i++)
	{
		inputs[i] =  m_inputsources[i] ? *m_inputsources[i] :
			m_inputfunctions[i] ? m_inputfunctions[i]->process() : 'x';
	}
	char output=m_logicfunction->calculate(inputs);
	delete [] inputs;
	return output;
}
/* Logical function */
#ifndef LOGICFUNCTION_H
#define LOGICFUNCTION_H


class LogicFunction {
public:

	// inputs/output are char: 't','f','x'
	// table entries are strings of numinputs inputs + resulting output
	LogicFunction(const char *name, int numinputs, const char **table);
	~LogicFunction();

	static LogicFunction *findFunction(const char *name);

	char calculate(char *inputs);

	int m_numinputs;
	char *m_name;
	const char **m_table;
};


class LogicProcessor {
public:
	LogicProcessor( LogicFunction *function );
	~LogicProcessor();

	void setInput(int input, LogicProcessor *lf);
	void setInput(int input, char * source);

	char process();

	char **m_inputsources;
	LogicProcessor **m_inputfunctions;
	LogicFunction *m_logicfunction;
};

#endif // LOGICFUNCTION_H
// Testcases for task 5
// Sample inputs that show different types of symmetry
// Supplied as an array in an includable file for simplicity

static const char * testcases[] = {
// All symmetries
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff" ,

"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt" ,

"tttttttt"
"ffffffff"
"tttttttt"
"ffffffff"
"ffffffff"
"tttttttt"
"ffffffff"
"tttttttt" ,

"tttttttt"
"tfffffft"
"tfffffft"
"tfffffft"
"tfffffft"
"tfffffft"
"tfffffft"
"tttttttt" ,

"tfffffft"
"ftfffftf"
"fftfftff"
"fffttfff"
"fffttfff"
"fftfftff"
"ftfffftf"
"tfffffft" ,

"fffttfff"
"fftfftff"
"ftfffftf"
"tfffffft"
"tfffffft"
"ftfffftf"
"fftfftff"
"fffttfff" ,

"fffttfff"
"fffttfff"
"fffttfff"
"tttttttt"
"tttttttt"
"fffttfff"
"fffttfff"
"fffttfff" ,

"ttfffftt"
"ttfffftt"
"ttfffftt"
"tttttttt"
"tttttttt"
"ttfffftt"
"ttfffftt"
"ttfffftt" ,

// Horizontal symmetry only
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"tttttttt"
"tttttttt"
"tttttttt"
"tttttttt" ,

"ttfffftt"
"ttfffftt"
"ffttttff"
"ffttttff"
"ttfffftt"
"ttfffftt"
"ffttttff"
"ffttttff" ,

"tttttttt"
"fttttttf"
"ffttttff"
"fffttfff"
"tfffffft"
"ttfffftt"
"tttffttt"
"tttttttt" ,

"tfffffft"
"ftfffftf"
"fftfftff"
"fffttfff"
"tfffffft"
"ftfffftf"
"fftfftff"
"fffttfff" ,

"ttfffftt"
"ttfffftt"
"fttffttf"
"fttffttf"
"ffttttff"
"ffttttff"
"fffttfff"
"fffttfff" ,

"tfffffft"
"ttfffftt"
"fttffttf"
"ffttttff"
"fffttfff"
"fffttfff"
"fffttfff"
"fffttfff" ,

"ffttttff"
"fttffttf"
"fttffttf"
"ffttttff"
"fttttttf"
"ttfffftt"
"ttfffftt"
"ffttttff" ,

"fffttfff"
"ffttttff"
"fttffttf"
"ttfffftt"
"tttttttt"
"tttttttt"
"ttfffftt"
"ttfffftt" ,

// Vertical symmetry only
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff" ,

"ttffttff"
"ttffttff"
"ffttfftt"
"ffttfftt"
"ffttfftt"
"ffttfftt"
"ttffttff"
"ttffttff" ,

"fffffftt"
"ffffttff"
"ffttffff"
"ttffffff"
"ttffffff"
"ffttffff"
"ffffttff"
"fffffftt" ,

"tttttttt"
"tttttttf"
"ttttttff"
"ffffffff"
"ffffffff"
"ttttttff"
"tttttttf"
"tttttttt" ,

"ffttttff"
"fttttttf"
"ttfffftt"
"ttffffff"
"ttffffff"
"ttfffftt"
"fttttttf"
"ffttttff" ,

"ttttffff"
"ttttttff"
"ttfffttf"
"ttfffftt"
"ttfffftt"
"ttfffttf"
"ttttttff"
"ttttffff" ,

"tttttttt"
"tttttttt"
"ttffffff"
"tttttttt"
"tttttttt"
"ttffffff"
"tttttttt"
"tttttttt" ,

"ttttttff"
"ttfffftt"
"ttfffftt"
"ttttttff"
"ttttttff"
"ttfffftt"
"ttfffftt"
"ttttttff" ,

// No symmetry
"ttttffff"
"ttttffff"
"ttttffff"
"ttttffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff" ,

"ftffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff"
"ffffffff" ,

"ftffffff"
"tffffttf"
"ftfffttf"
"tfffffff"
"ftttffff"
"fffttttf"
"fffffttf"
"tffftttf" ,

"ttfffttf"
"ffttffft"
"tfffttff"
"fttffftt"
"fffttfff"
"ttfffttf"
"ffttffft"
"tfffttff" ,

"tttttttt"
"tttttttt"
"fffffttf"
"ffffttff"
"fffttfff"
"ffttffff"
"fttfffff"
"ttffffff" ,

"tttttttt"
"tttttttt"
"ttffffff"
"tttttttt"
"tttttttt"
"ttffffff"
"ttffffff"
"ttffffff" ,

"ffttttff"
"fttttttf"
"ttfffftt"
"ttffffff"
"ttfftttt"
"ttffffft"
"tttttttf"
"ffttttff" ,

"fffffftt"
"fffffftt"
"fffffftt"
"fffffftt"
"fffffftt"
"ttfffftt"
"fttffttf"
"ffttttff" };
/*
 * Test software
 */

#include <stdio.h>

#include "logicfunction.h"

const char *or2_table [] =
{
"txt",
"xtt",
"fff",
0
};

const char *or3_table [] =
{
"txxt",
"xtxt",
"xxtt",
"ffff",
0
};

const char *and2_table [] =
{
"ttt",
"fxf",
"xff",
0
};

const char *and3_table [] =
{
"tttt",
"fxxf",
"xfxf",
"xxff",
0
};

const char *xor2_table  [] =
{
"tft",
"ftt",
"fff",
"ttf",
0
};

const char *xor3_table  [] =
{
"fftt",
"ftft",
"tfft",
"tttt",
"ffff",
"fttf",
"ttff",
"tftf",
0
};

const char *impl_table [] =
{
"xtt",
"fxt",
"tff",
0
};

const char *not_table [] =
{
"tf",
"ft",
0
};

const char *incl_table [] =
{
"txxt",
0
};

void processor_test(LogicProcessor *proc, int n, char *inp)
{
	int i;
	for (i=0;i<n;i++)
	{
		inp[i] = 'f';
	}

	bool done=false;
	do {
		for (i=0 ; i<n; i++)
			printf("%c ", inp[i]);
		printf(" -> %c\n", proc->process());

		for (i=0 ; i<n; i++)
		{
			if (inp[i] == 'f')
			{
				inp[i] = 't';
				break;
			}
			else
			{
				inp[i] = 'f';
			}
		}
		done = i==n;
	} while (!done);

}


void function_test ( LogicFunction *func )
{
	char *inp;
	char n=func->m_numinputs;
	LogicProcessor proc(func);

	printf("Testing function: %s\n", func->m_name);
	inp = new char [n];
	for (int i=0; i<n; i++)
	{
		proc.setInput(i, inp+i);
	}

	processor_test(&proc, n, inp);

	delete [] inp;
}



int main()
{
	LogicFunction
		f_not("not",1,not_table),
		f_and2("and2",2,and2_table),
		f_and3("and3",3,and3_table),
		f_or2("or2",2,or2_table),
		f_or3("or3",3,or3_table),
		f_xor2("xor2",2,xor2_table),
		f_xor3("xor3",3,xor3_table),
		f_implies("implies", 2, impl_table);

	LogicFunction
		f_incomplete("incomplete",3, incl_table);

// Basic table tests
	function_test(&f_not);
	function_test(&f_and2);
	function_test(&f_and3);
	function_test(&f_or2);
	function_test(&f_or3);
	function_test(&f_xor2);
	function_test(&f_xor3);
	function_test(&f_implies);

	function_test(&f_incomplete);


// Combinatorial tests

	{
		printf("Testing combinatorial not (P and Q)\n");
		char inputs[2];
		LogicProcessor p_not(&f_not),  p_and(&f_and2);
		p_and.setInput(0,inputs);
		p_and.setInput(1,inputs + 1);
		p_not.setInput(0,&p_and);

		processor_test(&p_not, 2, inputs);
	}

	{
		printf("Testing combinatorial P and not (Q or not R)\n");
		//  A && !(B || !C)
		char inputs[3];
		LogicProcessor p_not0(&f_not), p_not1(&f_not), p_or(&f_or2), p_and(&f_and2);
		p_not0.setInput(0,inputs+2);
		p_or.setInput(0,inputs+1);
		p_or.setInput(1,&p_not0);
		p_not1.setInput(0,&p_or);
		p_and.setInput(0,inputs);
		p_and.setInput(1, &p_not1);

		processor_test(&p_and, 3, inputs);
	}
}
2
Contributors
3
Replies
4
Views
7 Years
Discussion Span
Last Post by VilePlecenta
0

You shouldn't be dumping off your homework, people aren't to serve you...

Sorry .. but please just give me sum suggestion how to solve this.. some ideas...

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.