diff --git a/solution.pl b/solution.pl index d8ef515..14223f9 100644 --- a/solution.pl +++ b/solution.pl @@ -151,10 +151,27 @@ prompt, but which may include selectors. Selectors are terms of the form (See tests.pl for some concrete usage examples.) */ delete(Table, Conds) :- - (tabl(Table, _) -> - (rows(tables, Row), \+ (member(Cond, Conds), \+ Cond) -> retract(Row); true); - throw("Table doesn't exist") - ). + (tabl(Table, _) -> + row(Table, Row), + does_match(Conds, Table, Row) + ; + throw("Table doesn't exist") + ). + + +does_match([], _, Row) :- !. + +does_match([Cond|Rest], Table, Row) :- + % Extract the operator, field and value from the condition + Cond =.. [Operator | T], + [+F, S] = T, + + tabl(Table, Cols), + member(F, Cols), + nth0(Index, Cols, F), + nth0(Index, Row, Value), + apply(Operator, [Value, S]), + does_match(Rest, Table, Row). :- dynamic selec/4. /* @@ -186,86 +203,36 @@ For example: findall(Values, selec(persons,[+id,+first],[],Values), Projections) returns: Projections = [[0, "Jeffrey"], [1, "Lorena"], [2, "Joseph"], ... */ -selec(Table, Selectors, Conds, Projection) :- - selec_help(Table, Selectors,[], [], ColumnNames, ColumnValue), - %remove combinations that don't exist - row(Table, Row), - has_value(ColumnValue, Row), - Projection = ColumnNames/ColumnValue. +selec(Table, Selector, Cond, Projection) :- + tabl(Table, Cols), + row(Table, R), + does_match(Cond, Table, R), + selector(R,Cols, Selector, [],[],ColumnNames,ColumnValue), + Projection = ColumnNames/ColumnValue. %base case -selec_help(_, [], ColumnNames, ColumnValue, ColumnNames, ColumnValue). +selector(_,_,[],ColumnNames, ColumnValue, ColumnNames, ColumnValue):-!. /** - * Table: name of the table the selection is done one + * Row: A row from the table + * Cols: name of the column of the table * [Selector|Selectors] name(s) of the column(s) for selection * AccCols: acumulator list for the column(s) name(s) * AccVals: acumulator list for the row(s) values * ColumnNames: List returning the column(s) name(s) * ColumnValue: List returning the row values for each column */ -selec_help(Table, [Selector|Selectors], AccCols, AccVals, ColumnNames, ColumnValue) :- - %check if table exist - (tabl(Table, Cols) -> - %check if column exist - member(Selector, Cols) -> - %find the value corresponding to the column in the row - nth0(Index, Cols, Selector), - row(Table, Row), - nth0(Index, Row, Value), - %go to next column tho evaluate - selec_help(Table, Selectors, [Selector|AccCols], [Value|AccVals], ColumnNames, ColumnValue) - ; - string_concat(Selector, " isn't a column of table ", X), - string_concat(X, Table, Error), - throw(Error) - ; - string_concat(Table, " doesn't exist.", Error), throw(Error) +selector(Row, Cols, [+Selector|Selectors], AccCols, AccVals, ColumnNames, ColumnValue):- + (member(Selector, Cols) -> + %find the value corresponding to the column in the row + nth0(Index, Cols, Selector), + nth0(Index, Row, Value), + %go to next column tho evaluate + selector(Row, Cols, Selectors, [Selector|AccCols], [Value|AccVals], ColumnNames, ColumnValue) + ; + string_concat(Selector, " isn't a column of table ", X), + string_concat(X, Table, Error), + throw(Error) ). -/* -Check if a list has all the values in [Value|Rest] -*/ -has_value([], _) :- !. -has_value([Value|Rest], List) :- - memberchk(Value, List), - has_value(Rest, List). - -evaluate_condition_string(ConditionString) :- - atom_codes(AtomCondition, ConditionString), % Convert string to atom - read_term_from_codes(AtomCondition, Term, []), % Parse the term - call(Term). % Evaluate the parsed term - -selec_column(Table, Column, Proj) :- - tabl(Table, Cols), - row(Table, Row), - nth0(I, Cols, Column), - nth0(I, Row, Value), - Proj = Value. - -apply_cond(Table, Cond, Proj) :- - tabl(Table, Cols), - row(Table, Row), - nth0(I, Cols, Column), - nth0(I, Row, Value), - split_string(Cond, " ", "", SubStrings), - Decomp = SubStrings, - Decomp = [Column, Op, Value], - check_condition(Column, Op, Value), - Proj = Row. - -check_condition(Left, =, Right) :- - Left =:= Right. -check_condition(Left, <, Right) :- - Left < Right. -check_condition(Left, >, Right) :- - Left > Right. -check_condition(Left, <=, Right) :- - Left =< Right. -check_condition(Left, >=, Right) :- - Left >= Right. -check_condition(Left, \=, Right) :- - Left =\= Right. - - :- dynamic selec/3. /*